Scaling with hardware acceleration but without blending

This forum is for general developer support questions.
softwarefailure
Posts: 112
Joined: Fri Feb 14, 2014 10:29 pm

Scaling with hardware acceleration but without blending

Post by softwarefailure »

Is there any way to scale a 32-bit ARGB bitmap to another 32-bit ARGB bitmap but *without* any blending? AFAICS CompositeTags() will always blend the pixels onto the destination bitmap but I don't want that. Instead, pixels should just be scaled and vanilla copied without any blending, i.e. when scaling a 320x240 bitmap full of $80FFFFFF pixels to a 640x480 destination bitmap, all pixels in the destination bitmap should be set to $80FFFFFF as well (instead of blended values).

Is this possible somehow?
User avatar
gazelle
Posts: 102
Joined: Sun Mar 04, 2012 12:49 pm
Location: Frohnleiten, Austria

Re: Scaling with hardware acceleration but without blending

Post by gazelle »

Maybe using COMPOSITE_Src as operator instead of COMPOSITE_Src_Over_Dest? You would have to try it out.
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 600
Joined: Sat Jun 18, 2011 2:40 am
Location: Portsmouth, UK
Contact:

Re: Scaling with hardware acceleration but without blending

Post by broadblues »

Is this possible somehow?
Yes.

use COMPFLAG_SrcAlphaOveride and set the COMPTAG_SrcAlpha to 1.0 (which is the default so unless you have variable alpha overall alpha you can leave it out).

so you need thses tags but the firts is optional due to being the default.

COMPTAG_SrcAlpha,0x00010000,
COMPTAG_Flags, COMPFFLAG_IgnoreDestAlpha | COMPFLAG_SrcAlphaOverRide,

ie
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 600
Joined: Sat Jun 18, 2011 2:40 am
Location: Portsmouth, UK
Contact:

Re: Scaling with hardware acceleration but without blending

Post by broadblues »

gazelle wrote:Maybe using COMPOSITE_Src as operator instead of COMPOSITE_Src_Over_Dest? You would have to try it out.
No , here is an excellent discussion of compositing http://ssp.impulsetrain.com/porterduff.html the image halsway down shows how COMPOSITE_src with an alpha channel results in a result with an alpha channel. (the same as a src).

I'm not sure if the result is blended with or replaces the detination bitmap, either way it's not what software failure wants.
User avatar
gazelle
Posts: 102
Joined: Sun Mar 04, 2012 12:49 pm
Location: Frohnleiten, Austria

Re: Scaling with hardware acceleration but without blending

Post by gazelle »

broadblues wrote:
gazelle wrote:Maybe using COMPOSITE_Src as operator instead of COMPOSITE_Src_Over_Dest? You would have to try it out.
No , here is an excellent discussion of compositing http://ssp.impulsetrain.com/porterduff.html the image halway down shows how COMPOSITE_src with an alpha channel results in a result with an alpha channel. (the same as a src).
But my understanding of the question is: He doesn't want any changes of the source, just the size, so each alpha value of the source should be preserved, which COMPOSITE_Src will achieve, or not?
softwarefailure
Posts: 112
Joined: Fri Feb 14, 2014 10:29 pm

Re: Scaling with hardware acceleration but without blending

Post by softwarefailure »

Unfortunately, unless I'm doing something wrong neither of your suggestions achieves the desired effect. Here's some example code that shows that using COMPFLAG_SrcAlphaOverride will lead to a constant alpha value of 0xff in the destination bitmap instead of the alpha value from the source bitmap (0x80).

Code: Select all

#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <cybergraphx/cybergraphics.h>
#include <exec/exec.h>
#include <graphics/composite.h>
#include <graphics/gfx.h>
#include <graphics/rpattr.h>
#include <intuition/intuition.h>
#include <intuition/IntuitionBase.h>
#include <intuition/screens.h>

#include <proto/cybergraphics.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/picasso96api.h>

struct Library *IntuitionBase = NULL;
struct IntuitionIFace *IIntuition = NULL;

struct Library *GfxBase = NULL;
struct GraphicsIFace *IGraphics = NULL;

struct Library *P96Base = NULL;
struct P96IFace *IP96 = NULL;

struct Library *CyberGfxBase = NULL;
struct CyberGfxIFace *ICyberGfx = NULL;

static struct Screen *myscr;

static struct BitMap *allocvbmap(int width, int height)
{
	return AllocBitMap(width, height, GetBitMapAttr(myscr->RastPort.BitMap, BMA_DEPTH), BMF_MINPLANES|BMF_DISPLAYABLE, myscr->RastPort.BitMap);
}

int main(int argc, char *argv[])
{
	struct Window *win;
	struct BitMap *bmap, *bmap2, *bmap3;
 	ULONG ilock;
	struct RastPort tmprp;
	int borderleft, bordertop;
	struct IntuiMessage *msg;
	int width = 320, height = 240, k;
	float sx = 2, sy = 2;

	IntuitionBase = OpenLibrary("intuition.library", 53);
	IIntuition = (struct IntuitionIFace *) GetInterface(IntuitionBase, "main", 1, NULL);

	GfxBase = (struct Library *) OpenLibrary("graphics.library", 0);
	IGraphics = (struct GraphicsIFace *) GetInterface(GfxBase, "main", 1, NULL);

	CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
	ICyberGfx = (struct CyberGfxIFace *) GetInterface(CyberGfxBase, "main", 1, NULL);

	P96Base = OpenLibrary("Picasso96API.library", 0);
	IP96 = (struct P96IFace *) GetInterface(P96Base, "main", 1, NULL);

	ilock = LockIBase(0);
	myscr = ((struct IntuitionBase *) IntuitionBase)->ActiveScreen;
	UnlockIBase(ilock);

	borderleft = myscr->WBorLeft;
	bordertop = myscr->WBorTop + myscr->Font->ta_YSize + 1;

	bmap = allocvbmap(640, 480);
	bmap2 = allocvbmap(width, height);
	bmap3 = allocvbmap(640, 480);

	InitRastPort(&tmprp);
	tmprp.BitMap = bmap;
	FillPixelArray(&tmprp, 0, 0, 640, 480, 0);

	tmprp.BitMap = bmap2;
	FillPixelArray(&tmprp, 0, 0, width, height, 0x80FF0000);

	tmprp.BitMap = bmap3;
	FillPixelArray(&tmprp, 0, 0, 640, 480, 0xFFFFFFFF);

	win = OpenWindowTags(NULL,
		WA_Left, 100,
		WA_Top, 100,
		WA_InnerWidth, 640,
		WA_InnerHeight, 480,
		WA_SizeGadget, FALSE,
		WA_DragBar, TRUE,
		WA_DepthGadget, TRUE,
		WA_CloseGadget, TRUE,
		WA_Borderless, FALSE,
		WA_SimpleRefresh, TRUE,
		WA_IDCMP, IDCMP_CLOSEWINDOW,
		WA_Activate, TRUE,
		WA_Title, "Test",
		TAG_DONE);

	CompositeTags(COMPOSITE_Src_Over_Dest, bmap2, bmap,
		COMPTAG_ScaleX, COMP_FLOAT_TO_FIX(sx),
		COMPTAG_ScaleY, COMP_FLOAT_TO_FIX(sy),
		COMPTAG_Flags, COMPFLAG_SrcAlphaOverride,
		TAG_DONE);

	tmprp.BitMap = bmap;
	printf("CHECK SCALE RESULT: %lx\n", ReadRGBPixel(&tmprp, 0, 0));

	CompositeTags(COMPOSITE_Src_Over_Dest, bmap, bmap3,
		COMPTAG_Flags, COMPFLAG_IgnoreDestAlpha,
		TAG_DONE);

	BltBitMapRastPort(bmap3, 0, 0, win->RPort, borderleft, bordertop, 640, 480, 0xc0);

	for(k = 0; k < 200; k++) WaitTOF();

	FreeBitMap(bmap);
	FreeBitMap(bmap2);
	FreeBitMap(bmap3);

	CloseWindow(win);

	DropInterface((struct Interface *) IIntuition);
	CloseLibrary(IntuitionBase);

	DropInterface((struct Interface *) IGraphics);
	CloseLibrary(GfxBase);

	DropInterface((struct Interface *) ICyberGfx);
	CloseLibrary(CyberGfxBase);

	DropInterface((struct Interface *) IP96);
	CloseLibrary(P96Base);

	return 0;
}
Note that using COMPFLAG_IgnoreDestAlpha as suggested by broadblues will lead to the alpha byte being zero in the destination bitmap so I left it out. gazelle's suggestion yields the same, wrong result.
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 600
Joined: Sat Jun 18, 2011 2:40 am
Location: Portsmouth, UK
Contact:

Re: Scaling with hardware acceleration but without blending

Post by broadblues »

Sorry I misread / failed to read the part about preserving the alpha channel.

It's important to note this function does what is says it does, that is, it <b>Composites</b>. So the alpha channel is not used as an alpha channel but as a template for compositing operation. I don;t think (nor can I find by experimentation) there is a combination of operators and src dest values that will both preserve the alpha channel and the RGB data <b>at the same time</b> because the alpha channel operates on the rgb data.

For example Src_in_Dest Dest alpha ff

CHECK DEST: ff000000
CHECK SRC: ccff0000
CHECK SCALE RESULT: cccc0000

preserves the src alpha but multiplies the src colour by it's alpha value. Not what you want.

Src

CHECK DEST: ff000000
CHECK SRC: ccff0000
CHECK SCALE RESULT: cccc0000

CHECK DEST: 00000000
CHECK SRC: ccff0000
CHECK SCALE RESULT: cccc0000

Src_Over_Dest with SrcAlphaOveride preserves colour but not alpha (which is what I thought you wanted when I read the initial line about no blend)

CHECK DEST: 00000000
CHECK SRC: ccff0000
CHECK SCALE RESULT: ffff0000
softwarefailure
Posts: 112
Joined: Fri Feb 14, 2014 10:29 pm

Re: Scaling with hardware acceleration but without blending

Post by softwarefailure »

It's important to note this function does what is says it does, that is, it <b>Composites</b>
Yes, I know, that's why I was asking about alternatives. See my original post:
AFAICS CompositeTags() will always blend the pixels onto the destination bitmap but I don't want that.
So does OS4 offer any way of scaling a bitmap with hardware acceleration but without any blending? What about the old V36 BitMapScale() API? Will this use hardware acceleration on OS4? Or are there any other alternatives? If not, consider this post a feature request ;) I think we need hardware accelerated scaling support without blending as well.
User avatar
broadblues
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 600
Joined: Sat Jun 18, 2011 2:40 am
Location: Portsmouth, UK
Contact:

Re: Scaling with hardware acceleration but without blending

Post by broadblues »

softwarefailure wrote:
It's important to note this function does what is says it does, that is, it <b>Composites</b>
Yes, I know, that's why I was asking about alternatives. See my original post:
Yes, I thought you might realise this, but my post also addresses gazelles misunderstanding too.

So does OS4 offer any way of scaling a bitmap with hardware acceleration but without any blending? What about the old V36 BitMapScale() API? Will this use hardware acceleration on OS4? Or are there any other alternatives? If not, consider this post a feature request ;) I think we need hardware accelerated scaling support without blending as well.
Have you experimented with triangle mode in the CompositeTags function ? Not sure if that blends in the same way ot not ( it may do).

I'm not sure about the old ScaleBitmap API it certainly still works, but whether it's hardware accelerated I'm not sure. It might even depend on which hardware.

It does preserve the Alpha channel during scaling OS4 AWeb relies on this for it's png alpha support.

I would agree about the scaling with out blending requirement.
User avatar
mritter0
Posts: 214
Joined: Mon Aug 25, 2014 9:41 pm
Location: Bettendorf, IA, USA

Re: Scaling with hardware acceleration but without blending

Post by mritter0 »

I had a problem, too, with the alpha channel in my image preview code. After a lot of trial and error it was simply to not use any flags:

Code: Select all

	if (IGraphics->CompositeTags(
		COMPOSITE_Src,						PID->OrigBM, PID->PreviewBM,
		COMPTAG_ScaleX,						COMP_FLOAT_TO_FIX(ScaleFactorX),
		COMPTAG_ScaleY,						COMP_FLOAT_TO_FIX(ScaleFactorY),
	TAG_DONE) != COMPERR_Success )
	{
		if (PID->PreviewBM != NULL)
			IP96->p96FreeBitMap(PID->PreviewBM);
	}
This just scales the image and keeps all alpha channels in tact.
Workbench Explorer - A better way to browse drawers
Post Reply