B4A Library [Class] - OpenGL ES - 2D Image library

Informatix

Expert
Licensed User
Longtime User

The GameView class does not really uses a "simple" canvas. In fact, it uses the hardware accelerated canvas available since Honeycomb. In the Android API, this canvas is a wrapper around OpenGL functions. I use the same canvas in my AcceleratedSurface lib (but I'm compatible with Gingerbread )
 

agraham

Expert
Licensed User
Longtime User
As long as your target is running API 11 (Honeycomb) or later you can enable hardware acceleration by a manifest entry.

Hardware Acceleration | Android Developers

You can check if a View is hardware accelerated by Reflection.
B4X:
Dim r As Reflector
Dim hw As Boolean
r.Target = myview
hw = r.RunMethod("isHardwareAccelerated")
Msgbox(hw, "HardwareAccelerated")
I got the reflection code above reporting hardware acceleration on my Xoom just by by putting
B4X:
SetApplicationAttribute(android:hardwareAccelerated, "true")
in the Manifest Editor. I was already compiling with "...\android-13\android.jar" in my android.jar path.

The minSdkVersion and targetSdkVersion don't seem to matter. I've set both to 4 and I still get hardware acceleration reported.
 

agraham

Expert
Licensed User
Longtime User
You probably know better than me as I tend to stay away from GUI stuff, but the documentation seems to imply that it affects all Views though not all operations on those Views. I'm probably misunderstanding it or there are further qualifications that I am not aware of.
The easiest way to enable hardware acceleration is to turn it on globally for your entire application. If your application uses only standard views and Drawables, turning it on globally should not cause any adverse drawing effects.

If a B4A Canvas cannot be hardware accelerated I would be interested if you know why as I can see only one Canvas class in Android and the B4A Canvas is an instance of it. The documentation seems to imply that Canvas automatically gets accelerated.
When hardware accelerated, the 2D rendering pipeline supports the most commonly used Canvas drawing operations as well as many less-used operation

The manifest entry certainly affects whether a glSurfaceView reports that it is being hardware accelerated or not but I'm getting out of my depth here
 

bloxa69

Active Member
Licensed User
Longtime User
As long as your target is running API 11 (Honeycomb) or later you can enable hardware acceleration by a manifest entry.

The problem is I must cover all SDKs starting with 7, as there is a lot of those devices still, so enabling hardware acceleration alone doesn't cut it, it has to be some kind of OpenGL canvas or surface. As I mentioned, I have to actually write 2 independent apps and wrap them in one .apk to cover both older and newer SDKs, as Erel's GameView is much smoother but it doesn't work properly below SDK 11.
 

Informatix

Expert
Licensed User
Longtime User

All functions and classes are not in the API. You won't find any mention in the documentation of the GLES20Canvas
 

agraham

Expert
Licensed User
Longtime User
Yes but the documentation explicitly says
When hardware accelerated, the 2D rendering pipeline supports the most commonly used Canvas drawing operations as well as many less-used operations
Where "Canvas" is a link to the android.graphics.Canvas documentation so implying that a normal canvas will be hardware accelerated

Also
Again mentioning Canvas.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Yes but the documentation explicitly says
Where "Canvas" is a link to the android.graphics.Canvas documentation so implying that a normal canvas will be hardware accelerated

Also
Again mentioning Canvas.

I read it, yes, but when I get the type of the B4A Canvas on my Nexus 7 with the hardware acceleration enabled, I get:
android.graphics.Canvas

B4X:
Dim r As Reflector
r.Target = C
r.Target = r.GetField("canvas")
Log(GetType(r.Target))

When I get the type of my accelerated Canvas, I get:
android.view.GLES20RecordingCanvas
It's a subclass of android.view.GLES20Canvas.

The canvas returned by a view in the onDraw event is obviously different from a canvas instance of the Canvas class.

EDIT: GameView uses the GLES20Canvas.

EDIT2: http://stackoverflow.com/questions/9588776/canvas-in-surfaceview-hardware-acceleration
 
Last edited:

agraham

Expert
Licensed User
Longtime User
That's interesting, though I'm not sure it's hard evidence that a normal Canvas isn't accelerated. The documentation I've read, and some posts by Romain Guy of the Android team, all seem to imply that a Canvas uses the OpenGL pipeline for 2D operations when acceleration is enabled and I wouldn't have thought the documentation would be that wrong.

Maybe the "hardware-accelerated renderer" can paint onto a normal Canvas. However I can't get excercised enough to start digging into the Android code base to find out, as like I said I normally avoid GUI stuff if I can.
 

Informatix

Expert
Licensed User
Longtime User

One thing is sure: the B4A CanvasWrapper class is not hardware accelerated. I can easily compare its performance with my AcceleratedSurface, and it's inferior.
 

Jim Brown

Active Member
Licensed User
Longtime User
I would say this is because of the software-driven canvas as discussed. For performance I took many steps to ensure things remain efficient. For example, using the same image so that OpenGL surface usage is a minimum, and culling the backface, which would never normally be seen. Although doing that stopped the Image flip from working. The actual OpenGL drawing operations are pretty minimal I believe.

You talked about a FPS timing issue in my smileys demo a few posts back but when I checked my drawing loop I am doing the same as you. That is, checking how much time has passed once the complete draw cycle is finished.
 

Informatix

Expert
Licensed User
Longtime User
I would say this is because of the software-driven canvas as discussed.

I don't see any Canvas in your code.

You talked about a FPS timing issue in my smileys demo a few posts back but when I checked my drawing loop I am doing the same as you. That is, checking how much time has passed once the complete draw cycle is finished.

In your Performance example, you count the number of times you enter into the Timer1_Tick sub. That could be fine if you entered the same number of times in the glsv_Draw sub, but it's not the case despite your RequestRender call, so your count is completely wrong. Move your code in the glsv_Draw sub and you'll see. I have not this problem in my AcceleratedSurface example.

Here's a log showing the problem (I traced the calls with 200 smileys):
TICK
TICK
DRAW
TICK
TICK
TICK
TICK
DRAW
TICK
TICK
TICK
TICK
TICK
TICK
TICK
TICK
TICK
TICK
DRAW
TICK
TICK
TICK
TICK
DRAW
TICK
TICK
TICK
TICK
TICK
TICK
DRAW
TICK
TICK
TICK
TICK
TICK
DRAW
TICK
DRAW
TICK
TICK
TICK
TICK
TICK
TICK
 

Jim Brown

Active Member
Licensed User
Longtime User
Regarding surfaces, I can only assume Andrew's GLSurfaceView is software at this time. Hence the slower performance
OpenGL - SurfaceView

That could be fine if you entered the same number of times in the glsv_Draw sub, but it's not the case despite your RequestRender call
That's interesting. I assumed the rendering happens every time glsv.RequestRender is called, since I initialize the GL surface view via RENDERMODE_WHEN_DIRTY. The document info says:
B4X:
RENDERMODE_WHEN_DIRTY As Int
The renderer only renders when the surface is created, or when requestRender() is called
 

agraham

Expert
Licensed User
Longtime User
I can only assume Andrew's GLSurfaceView is software at this time.
No, it's a VERY thin wrapper over the standard API and has no determination within it whether hardware acceleration is used or not. However Informatix knows far more about this than I do and is best placed to comment.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…