B4A Library [Lib] Accelerated surface

This library provides a dedicated drawing surface embedded inside a view, which benefits from the hardware acceleration. With it, you get the speed of OpenGL for 2D without the complexity.
It includes many Canvas methods (with anti-aliasing, matrix and camera) and a few useful methods for Bitmaps and Drawables (AlterColors, Crop, LoadNinePatch, ReduceColors, SetDensity, etc.). You can import the Matrix, Camera, Paint and Path objects from another library (if they are not wrapped).

surface.png

imageviews.jpg


You can use it to make games:

princess_tiles.png

space_enemies.png


It includes a tool (TextFactory) to do nice titles (that you can export to a bitmap):

textfactory.jpg


It supports Porter-Duff modes, color filters and texture blending (the processing time is very fast):

pdmodes.jpg


The archive includes four benchmarks:

Perf.png


Because of my lack of (free) time, don't expect answers from me about this library if you're not one of my donors.

Download the latest version (1.12)
To convert a project from v0.9x to v1.x, read this.

Hints & Tips

This library does not work with Android versions < 2 (Eclair and Froyo may exhibit performance problems, so I recommend only Gingerbread or a newer version for animations with a high FPS).
The hardware acceleration is not enabled with Android versions < 3.
 

Attachments

  • Java source - AcceleratedSurface.zip
    21.3 KB · Views: 653
Last edited:

sorex

Expert
Licensed User
Longtime User
indeed, now it works. altho I didn't touch the code at all, weird.

sometimes the app just starts with a black screen but the click events still trigger.
might be because of debugger mode that I was currently using.
 

sorex

Expert
Licensed User
Longtime User
loadbitmapsample on some OS versions doesn't scale to the given maxx & maxy.

not really a problem with .drawbitmap as you give the destination rectangle for the extra/correct downsizing.

but when you use .MatrixSetRotate or Rotate2 there's no .DrawBitmapWithMatrix that uses a destination rectangle.

Is there an easy way to do this or do I really need to load the bitmap, copy it via canvas to another one with the right size and use that for the rotated matrix draw ?

Edit: the above mentioned method currently works as workaround
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
loadbitmapsample on some OS versions doesn't scale to the given maxx & maxy.

not really a problem with .drawbitmap as you give the destination rectangle for the extra/correct downsizing.

but when you use .MatrixSetRotate or Rotate2 there's no .DrawBitmapWithMatrix that uses a destination rectangle.

Is there an easy way to do this or do I really need to load the bitmap, copy it via canvas to another one with the right size and use that for the rotated matrix draw ?

Edit: the above mentioned method currently works as workaround
Bitmaps should be loaded in AC with the AC function "LoadScaledBitmap".
 

sorex

Expert
Licensed User
Longtime User
I read in a post in this thread something about loadScaledBitmap but I can't find that function.

ac. intellisense doesn't bring up such method/function.

does that need an additional class file?
 

sorex

Expert
Licensed User
Longtime User
ok, found it. Didn't notice that imageUtil object before.

so it was

B4X:
bm.bitmap=asUI.LoadScaledBitmap(File.DirAssets,"bm.png",100,100,True)

which is a lot easier than that workaround.

Thanks!
 

sorex

Expert
Licensed User
Longtime User
@Informatix,

Is there a way to turn off smoothing/anti-aliasing during upscaling drawbitmap copying?

I was checking the behaviour on pixel gfx and the only thing that seems to work 99% right is a regular bitmap copy without Acc.S.

Below you see what happens to Bruce with different methods.

bruces.png
 

Informatix

Expert
Licensed User
Longtime User
@Informatix,

Is there a way to turn off smoothing/anti-aliasing during upscaling drawbitmap copying?

I was checking the behaviour on pixel gfx and the only thing that seems to work 99% right is a regular bitmap copy without Acc.S.

Below you see what happens to Bruce with different methods.

View attachment 54478
Could you post the code you used? I don't understand what means exactly "upscaling drawbitmap copying".
 
Last edited:

sorex

Expert
Licensed User
Longtime User
with upscaling I meant going from the initial 16x21px source to display it at x10 (160x210)

B4X:
Sub Globals
Dim tileheight As Int
Dim tilewidth As Double
Dim asf As AcceleratedSurface
Dim b As Bitmap
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.Color=Colors.Blue
tilewidth=16*10
tileheight=21*10
b.InitializeMutable(16,21)
b=LoadBitmap(File.DirAssets,"bruce.png")
asf.Initialize("asf",True)
asf.StartRegularDraw(1000/1)
Activity.AddView(asf,0,0,100%x,100%y)
End Sub

Sub asf_Draw(AC As AS_Canvas)
  AC.DrawBitmapAt(b,0,0)
  Dim r As Rect
  r.Initialize(0,0,tilewidth,tileheight)
  AC.DrawBitmap(b,Null,r)
End Sub
 

Attachments

  • bruce.png
    bruce.png
    253 bytes · Views: 190
Last edited:

Informatix

Expert
Licensed User
Longtime User
with upscaling I meant going from the initial 16x21px source to display it at x10 (160x210)

B4X:
Sub Globals
Dim tileheight As Int
Dim tilewidth As Double
Dim asf As AcceleratedSurface
Dim b As Bitmap
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.Color=Colors.Blue
tilewidth=16*10
tileheight=21*10
b.InitializeMutable(16,21)
b=LoadBitmap(File.DirAssets,"bruce.png")
asf.Initialize("asf",True)
asf.StartRegularDraw(1000/1)
Activity.AddView(asf,0,0,100%x,100%y)
End Sub

Sub asf_Draw(AC As AS_Canvas)
  AC.DrawBitmapAt(b,0,0)
  Dim r As Rect
  r.Initialize(0,0,tilewidth,tileheight)
  AC.DrawBitmap(b,Null,r)
End Sub
You can deactivate the antialiasing filter but with such an upscaling factor, the result will be blurry anyway:
B4X:
AC.MatrixSetScale(10, 10)
AC.DrawBitmapWithMatrixAt(b, 130, 0, False)

How do you get your perfect result? Could you share the code?
 

sorex

Expert
Licensed User
Longtime User
It's just a canvas bound to an imageview of 160x210px then I used cvs.drawBitmap.

now this is interesting...

I'm now at home and in this virtual machine it works right.

this is a emulated Galaxy S2 with 4.1.1 and api 16

the one where the screenshots were taken was 4.4.4 api 19

Edit: I have it here on my home computer aswell. I'll try to find what's causing that blur.
 
Last edited:

sorex

Expert
Licensed User
Longtime User
it seems that api 19 makes that blur happen.

I added a new Nexus 4.4.4 Api 19 and the blur happens there too.

and yes, that's with the matrix copy with or without filter enabled.
 

sorex

Expert
Licensed User
Longtime User
I managed to get it working by using createScaledBitmap to pre-upscale the image

B4X:
  Dim dr As Rect
  Dim bmu As AS_ImageUtils
  Dim bs As Bitmap
  b=LoadBitmap(File.DirAssets,"bruce.png")
  bs=bmu.CreateScaledBitmap(b,tilewidth,tileheight,False)
  dr.Initialize(0,0,tilewidth,tileheight)
  AC.DrawBitmap(bs,Null,dr)

changing the False to True give the blur again. So it seems that on some api that filter is on by default and off on others?



can be reduced to

B4X:
Dim bmu As AS_ImageUtils
Dim bs As Bitmap
bs=bmu.LoadScaledBitmap(File.DirAssets,"bruce.png",tilewidth,tileheight,False)
AC.DrawBitmapat(bs,0,0)
 
Last edited:

sorex

Expert
Licensed User
Longtime User
Now I wonder how the image is stored. will it be stored as a 160x210px image or just as a 16x21 and tagged to not use that filter during operations?

Worst case it uses 10x the memory of the original but I guess it keeps the original size since it's smaller than what I define and that filter does the rest.
 

Informatix

Expert
Licensed User
Longtime User
Now I wonder how the image is stored. will it be stored as a 160x210px image or just as a 16x21 and tagged to not use that filter during operations?

Worst case it uses 10x the memory of the original but I guess it keeps the original size since it's smaller than what I define and that filter does the rest.
CreateScaledBitmap creates a 160x210 image. During the change of scale, it applies (or not) a filtering function. After that, the bitmap is displayed as is.
 

sorex

Expert
Licensed User
Longtime User
CreateScaledBitmap creates a 160x210 image.

does loadScaledBitmap create the 160x210 image aswell even when the dimensions are bigger than those from the image? I guess it does a createScaledBitmap first before it loads the image into it.
 
Top