alpha blending

General FreeBASIC programming questions.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

dafhi wrote:Thanks for the compiler warnings list. They don't appear here, but I get 'suspicious pointer assignment' messages.
You're wellcome. Sure they will appear on your system when you compile with -w pedantic.
dafhi wrote:the cairo version runs slower.
I made the main loops stop after 100 executions and print out the execution time. On my system both versions are equal in speed (less than 2 % difference, cairo_test.bas was a bit faster in 2 of 3 tests).
dafhi wrote:I was wondering if you are familiar enough with Cairo to suggest speed improvements.
I wonder if you're able to evaluate this.

As expected you won't see any effect from hardware acceleration when you use cairo like fbgfx and set the color pixel by pixel. Improve your SUB Render. Have a look at cairo_mask and cairo_pattern functions.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Post by dafhi »

I made the main loops stop after 100 executions and print out the execution time. On my system both versions are equal in speed (less than 2 % difference, cairo_test.bas was a bit faster in 2 of 3 tests).
Interesting. On my machine it shows that Cairo is using around 34% of the cpu while the fbgfx is using 26%

One more question with regards to performance on your machine. Does the alpha in my Cairo version appear to be rendering correctly? Here, it appears super-saturated and clipped
As expected you won't see any effect from hardware acceleration when you use cairo like fbgfx and set the color pixel by pixel. Improve your SUB Render. Have a look at cairo_mask and cairo_pattern functions.
This demo I am only comparing the difference between Cairo and fbgfx alpha blend.
With the following code change, performance gain is minimal.

Code: Select all

	''Interpolated color based on 2 adjacent palette entries
	
	m_Sng = sngMap(x,y)
	Modulus(m_Sng,mPalUB_)
	*dest = mPalette(Int(m_Sng))
'	*dest = Int(m_Sng)
	
'	Alpha_ = 256 * (m_Sng - *dest)
'	Pixel_ = mPalette(*dest + 1)
'	MaskRB = (Pixel_ And &H00FF00FF) * Alpha_
'	MaskAG = ((Pixel_ And &HFF00FF00) Shr 8) * Alpha_
	
'	Alpha_ = 256 - Alpha_
'	Pixel_ = mPalette(*dest)
'	MaskRB += (Pixel_ And &H00FF00FF) * Alpha_
'	MaskAG += ((Pixel_ And &HFF00FF00) Shr 8) * Alpha_

'	MaskRB And= &HFF00FF00
'	MaskAG And= &HFF00FF00
	
'	*dest = (MaskRB Shr 8) Or MaskAG
	dest += 1
Next
I can understand how offloading all drawing functions to the card would improve the speed. Thanks again for your input and suggestions. I will certainly research these and learn more about Cairo.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Post by dafhi »

Just a little update for you guys. I discovered that the main culprit in the performance hit is this guy

Int(sng)

That said, I plan on diving into the realms of GL, Cairo and ASM.

Thanks for yall's input. (no I am not from the south)
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Post by TJF »

dafhi wrote:On my machine it shows that Cairo is using around 34% of the cpu while the fbgfx is using 26%
On my system both have the same CPU usage (approx 37 %).
dafhi wrote:One more question with regards to performance on your machine. Does the alpha in my Cairo version appear to be rendering correctly? Here, it appears super-saturated and clipped
That's hard to say. You'll need two similar (not changing) pictures side by side to evaluate this. But it should be no problem. You can fix it by finetuning the color parameters.
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Post by 1000101 »

TJF wrote:Cairo isn't a proprietary lib.
Not really the point. The point was that unless you are giving yourself a significant advantage by using [whatever] then you shouldn't.

"If you can only think of one reason for doing something, you don't have enough reasons." etc
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Post by dafhi »

I was able to improve the performance. Might take a breather before I begin researching the other stuff.

"put_test.bas"

Code: Select all

#Include "fbgfx.bi"

#If __FB_LANG__ = "fb"
Using fb
#EndIf

Dim e As EVENT

Dim Shared As Integer				SCR_W = 480
Dim Shared As Integer				SCR_H = 360

Dim Shared As Integer				WidM: WidM = SCR_W - 1
Dim Shared As integer				HgtM: HgtM = SCR_H - 1
Dim Shared As Single					sngMidx: sngMidx = WidM/2
Dim Shared As Single					sngMidy: sngMidy = HgtM/2

Type ImageInfo
	As Any ptr							img,pixels
	As Integer							pitch
	Declare Sub Create(pWid As UShort=SCR_W,pHgt As UShort=SCR_H,pRed As UByte=255,pGrn As UByte=255,pBlu As UByte=255,pAph As UByte=255)
	Declare Sub Destroy
End Type

#Include "palettizer.bi"

Dim Shared As Single					gradient_R()
Dim Shared As Single					gradient_G()
Dim Shared As Single					gradient_B()
Dim Shared As Single					gradient_A1()
Dim Shared As Single					gradient_A2()
Dim Shared As GradientRibbon		mGInfo
Dim Shared As ComponentAnimProps	PS_R,PS_G,PS_B,PS_A1,PS_A2

Dim Shared As Single					SuperSample = 2
Dim Shared As Integer				PaletteSize: PaletteSize = SuperSample*Sqr(sngMidx^2+sngMidy^2)
Dim Shared As UInteger				mPalette(PaletteSize)
Dim Shared As Integer 				X,Y
Dim Shared As Single					m_sng

Dim Shared As ImageInfo				img_B,img_F,img_Wnd

Type RenderMap
	As UShort							Alpha,PalEntry
End Type

Dim Shared As RenderMap				RenderMap(WidM,HgtM)
Dim Shared As RenderMap Ptr		A_,B_

Sub ImageInfo.Create(pWid As UShort,pHgt As UShort,pRed As UByte,pGrn As UByte,pBlu As UByte,pAph As UByte)
	img = ImageCreate( pWid, pHgt, RGB(pRed,pGrn,pBlu))
	ImageInfo img, ,,, pitch, pixels
End Sub
Sub ImageInfo.Destroy()
	ImageDestroy img
End Sub

Sub Checkerboard(pInfo As ImageInfo,CheckerSize As UInteger = 16,pCheckGray As Byte = 64,pWidM As Integer=WidM,pHgtM As Integer=HgtM)
	Dim As UInteger SizeDouble=CheckerSize*2,SizeM=CheckerSize-1
	For Y = 0 To pHgtM Step CheckerSize
		For X = -CheckerSize * ((Y/SizeDouble)=Int(Y/SizeDouble)) To pWidM Step SizeDouble
			Line pInfo.img,(X,Y)-(X+SizeM,Y+SizeM),RGB(pCheckGray,pCheckGray,pCheckGray),BF
		Next
	Next
End Sub

Private Sub NewGradients(yBase As Integer=0,yHeight As Integer=19,pSpeed As Single=0.8)
	Gradient mGInfo,2,50,25+Rnd*25,0
	DefComponent PS_R,mGInfo,gradient_R(),305,-50,0.003*pSpeed,0.0041*pSpeed,,,255

	Gradient mGInfo,2,50,25+Rnd*25,0
	DefComponent PS_G,mGInfo,gradient_G(),305,-50,0.004*pSpeed,0.0051*pSpeed,,,255

	Gradient mGInfo,2,50,25+Rnd*25,0
	DefComponent PS_B,mGInfo,gradient_B(),305,-50,0.005*pSpeed,0.0061*pSpeed,,,255

	Gradient mGInfo,3,30,25+Rnd*55,31
	DefComponent PS_A1,mGInfo,gradient_A1(),415,-300,0.0071*pSpeed,0.0079*pSpeed,,,127

	Gradient mGInfo,3,30,25+Rnd*55,31
	DefComponent PS_A2,mGInfo,gradient_A2(),415,-300,0.0057*pSpeed,0.0053*pSpeed,,,128
End Sub

Sub Render()
Dim As UInteger      MaskRB,MaskAG,Pixel_,Alpha_

	ScreenLock
	Put (0,0),img_B.img,PSET

	For y_ as Integer = 0 To HgtM
		Dim As UInteger Ptr	dest = img_F.pixels + img_F.pitch * y_
		For x_ As RenderMap Ptr = @RenderMap(0,y_) To @RenderMap(WidM,y_) Step SCR_H
 
	''Interpolated color 2 adjacent palette entries

	*dest = mPalette(x_->PalEntry)
'	*dest = x_->PalEntry
	
'	Pixel_ = mPalette(*dest + 1)
'	MaskRB = (Pixel_ And &H00FF00FF) * x_->Alpha
'	MaskAG = ((Pixel_ And &HFF00FF00) Shr 8) * x_->Alpha
	
'	Alpha_ = 256 - x_->Alpha
'	Pixel_ = mPalette(*dest)
'	MaskRB += (Pixel_ And &H00FF00FF) * Alpha_
'	MaskAG += ((Pixel_ And &HFF00FF00) Shr 8) * Alpha_

'	MaskRB And= &HFF00FF00
'	MaskAG And= &HFF00FF00
	
'	*dest = (MaskRB Shr 8) Or MaskAG
	dest += 1

			Next
		Next

	Put (0,0),img_F.img,Alpha
	ScreenUnLock
End Sub

Sub MakeMap
	Dim As Integer	Temp_
	Dim As Single							xDelt,yDsq,xyDist
	mPalUB_ = UBound(mPalette)
	For Y = 0 To HgtM
		yDsq = (y-sngMidy)^2
		For x = 0 To WidM
			xDelt = x - sngMidx
			m_sng = SuperSample*Sqr(yDsq + xDelt * xDelt)
			Modulus(m_sng,mPalUB_)
			Temp_ = Int(m_sng)
			m_sng -= Temp_
			RenderMap(x,y).PalEntry = Temp_
			RenderMap(x,y).Alpha = Int(256 * m_sng + 0.5)
		Next	
	Next
End Sub

MakeMap

ScreenRes SCR_W,SCR_H,32

img_F.Create
img_B.Create
Checkerboard img_B,,0

Randomize

NewGradients

Do

	PalStream_RGBAA mPalette(),PS_R,PS_G,PS_B,PS_A1,PS_A2, _
		gradient_R(),gradient_G(),gradient_B(),gradient_A1(),gradient_A2()

	Render

	If (ScreenEvent(@e)) Then
		if e.type = EVENT_KEY_PRESS Then
			Select Case e.scancode
				Case SC_ESCAPE
			Exit Do
				Case Else
			NewGradients
			End Select
		End If
	End If

	Sleep 20,1
	
Loop

img_B.Destroy
img_F.Destroy
Post Reply