GL Surface and Visibility: Gone - android

So I have a GLSurfaceView in my app being rendered by a GLSurfaceView.Renderer and using JPCt as library.
The surface is in an invisible RelativeLayout (visibility: gone). When I change the visibility to "visible" then back to "gone", the layout shows and hides as expected, but the GLSurfaceView don't, it just shows and won't hide, even though I can click on items that are now "behind" it.
It seems like some graphical buffer issue, but I didn't find a way to get this to work... any ideas?
Thanks!

SurfaceView (and GLSurfaceView by extension) are interesting beasts in Android. Citation from Android javadoc:
The surface is Z ordered so that it is behind the window holding its
SurfaceView; the SurfaceView punches a hole in its window to allow its
surface to be displayed. The view hierarchy will take care of
correctly compositing with the Surface any siblings of the SurfaceView
that would normally appear on top of it
Android has a built-in window compositor (window has a bit different meaning here). Your status bar is a window, your activity has one window. But if your activity contains a surface view, another window is created, just to hold the surface, and android compositor draws the window with your views over the surface window. So the SurfaceView is really only a transparent area. When you hid it, the area is not drawn, does not react to touches, but the surface window is still present, android is not clever enough to hide the window.
I would recommend two solutions
Make your surface translucent. You can then render empty surface when you need to hide the view( Android, Transparent sub-GLSurfaceView in layout? )
Remove the view from view hierarchy altogether
Another a bit hacky way is to subclass GLSurfaceView and call onDetachedFromWindow() when visibility changes to GONE. I have not tested this and it might not work.

Related

using Alert Dialog like a toast, and without interrupting other activities for the user

I am new to android development. and I use in my application (alert dialog) in a builder to send notification massage to the user, just like the toast, but its clickable and can control the time of its appearance.
Now, my problem is that whenever the alert dialog is called, all video playback is paused and if the user is typing, the keyboard disappear, camera also suspended.
what I want is to call the alert dialog without interrupting the user UI or video playback and without acquiring the focus from other running applications.
Can someone help?
you can use surface view to get rid of your issues.
You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen
The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.
The transparent region that makes the surface visible is based on the layout positions in the view hierarchy. If the post-layout transform properties are used to draw a sibling view on top of the SurfaceView, the view may not be properly composited with the surface.
for detail
The easiest way would be to use Fragments. Create a fragment each time you need a dialog like that, you can control lifetime, appearance, interactivity etc.

How to set Fragment on top of GLSurfaceView that has setZOrderOnTop set to true

I have a GLSurfaceView that has the setZOrderOnTop set to true (otherwise the GLSurfaceView does not display the content correctly). I need to display a Fragment on top of this view but it seems an impossible task. I've tried everything present on the internet and nothing works.. Thanks in advance!
The SurfaceView's surface is on a separate layer from all of the View UI. By default, it's below the View layer, but if you use setZOrderOnTop() then it appears on top of everything.
You didn't say what sort of layout you're trying to get, but it's likely that a TextureView will work better, as those are rendered on the View layer.
You can use GLES to render to a TextureView, but you won't have the EGL setup or thread handling that GLSurfaceView provides. See Grafika for examples (e.g. "Simple GL in TextureView").

SurfaceView hides other components on screen

I am creating a layout of type FrameLayout, in which I am adding two views. Two views are objects of GLSurfaceView and SurfaceView respectively. According to Android Developers Documentation regarding SurfaceView,
"The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed."
It works well for me and SurfaceView always stays behind my GLSurfaceView (used for opneGL drawings). But resuming after external event the behavior is odd for a following configuration,
Android Version: 4.3
Device Model Number : Nexus 7
Kernel Version 3.4.0.g1f57c39
Jun 13
Build Number: JWR66N
For this configuration, resuming after external event puts my GLSurfaceView behind SurfaceView. In other words, SurfaceView is placed at top in ZOrder and my OpenGL drawings are no more visible. On versions greater that Android 4.3, this behavior is not seen.
I can replicate this behavior on all versions by calling SurfaceView's following method with true as a parameter.
void setZOrderOnTop
Is this known issue. Anybody can help me on this?
Regards,
Sumedh
SurfaceViews have two parts, the Surface and the View. The Surface is a completely independent layer. The View is there so the UI layout code has something to work with. Generally the View is just transparent black, so you can see through to whatever is behind it.
GLSurfaceView is just SurfaceView with some code to manage EGL contexts and threading. Underneath it's just a SurfaceView. So if you have both a SurfaceView and a GLSurfaceView, and they have the same dimensions and Z-order, then one of them is going to "win" and the other is going to "lose" because they're trying to occupy the same space at the same time. There is no defined value for which one will "win", so inconsistent behavior is expected.
One way to avoid clashes is to leave one set to the default Z, and call setZOrderMediaOverlay() on the other. The "media overlay" is still behind the UI, but above the default Surface position. If you use setZOrderOnTop(), the Surface will be positioned above the UI as well.
The upper Surface will need to be rendered with transparent pixels if you want to see something behind it (the same way that the View needs to be transparent to see the Surface).
The most efficient way to avoid this issue is to not have this issue: use one SurfaceView for everything, rendering all of your non-UI-element content to it. This requires a bit more work (and probably a SurfaceTexture) if you're rendering video or showing a camera preview on one of the Surfaces.
You can find some examples in Grafika. The "multi-surface exerciser" demonstrates three overlapping SurfaceViews rendered in software, overlapping with UI elements. Other activities show ways to work with Surfaces, GLES, the camera, and video.
See also the Android System-Level Graphics Architecture doc, which explains all this in much greater detail.
Dont use "setZOrderOnTop" as true. That will get it over all the other layouts.
If you are using multiple surfaceviews. use this for each surfaceview
yourSurfaceView.setZOrderMediaOverlay(true);
then set this setZOrderOnTop as false for the surfaceview you initiated later and wanted it to get back to the other surfaceviews
secondSurfaceview.setZOrderOnTop(false);

what is SurfaceView SurfaceHolder Surface Camera API android [duplicate]

I'm struggling to understand the process of drawing to SurfaceView and therefore the whole Surface/Canvas/Bitmap system, which is used in Android.
I've read all articles and API documentation pages, which I was able to find on android-developers site, a few tutorials of android graphics, LunarLander source code and this question.
Please tell me, which of these statements are true, which are not, and why.
Canvas has its own Bitmap attached to it. Surface has its own Canvas attached to it.
All View's of window share the same Surface and thus share the same Canvas.
SurfaceView is subclass of View, which, unlike other View's subclasses and View itself, has its own Surface to draw in.
There is also one additional question:
Why is there a need for a Surface class, if there is already a Canvas for high-level operations with bitmap. Give an example of a situation where Canvas is non-suitable for doing work which Surface can do.
Here are some definitions:
A Surface is an object holding pixels that are being composited to the screen. Every window you see on the screen (a dialog, your full-screen activity, the status bar) has its own surface that it draws in to, and Surface Flinger renders these to the final display in their correct Z-order. A surface typically has more than one buffer (usually two) to do double-buffered rendering: the application can be drawing its next UI state while the surface flinger is compositing the screen using the last buffer, without needing to wait for the application to finish drawing.
A window is basically like you think of a window on the desktop. It has a single Surface in which the contents of the window is rendered. An application interacts with the Window Manager to create windows; the Window Manager creates a Surface for each window and gives it to the application for drawing. The application can draw whatever it wants in the Surface; to the Window Manager it is just an opaque rectangle.
A View is an interactive UI element inside of a window. A window has a single view hierarchy attached to it, which provides all of the behavior of the window. Whenever the window needs to be redrawn (such as because a view has invalidated itself), this is done into the window's Surface. The Surface is locked, which returns a Canvas that can be used to draw into it. A draw traversal is done down the hierarchy, handing the Canvas down for each view to draw its part of the UI. Once done, the Surface is unlocked and posted so that the just drawn buffer is swapped to the foreground to then be composited to the screen by Surface Flinger.
A SurfaceView is a special implementation of View that also creates its own dedicated Surface for the application to directly draw into (outside of the normal view hierarchy, which otherwise must share the single Surface for the window). The way this works is simpler than you may expect -- all SurfaceView does is ask the window manager to create a new window, telling it to Z-order that window either immediately behind or in front of the SurfaceView's window, and positioning it to match where the SurfaceView appears in the containing window. If the surface is being placed behind the main window (in Z order), SurfaceView also fills its part of the main window with transparency so that the surface can be seen.
A Bitmap is just an interface to some pixel data. The pixels may be allocated by Bitmap itself when you are directly creating one, or it may be pointing to pixels it doesn't own such as what internally happens to hook a Canvas up to a Surface for drawing. (A Bitmap is created and pointed to the current drawing buffer of the Surface.)
Also please keep in mind that, as this implies, a SurfaceView is a pretty heavy-weight object. If you have multiple SurfaceViews in a particular UI, stop and think about whether this is really needed. If you have more than two, you almost certainly have too many.
Here is a very basic and simple conceptual overview of how interaction happens among the Window, Surface, Canvas, and Bitmap.
Sometimes, a visual representation helps a lot in understanding twisted concepts.
I hope this graphic could help someone.
A Bitmap is simply a wrapper for a collection of pixels. Think of it as an array of pixels with some other convenient functions.
The Canvas is simply the class that contains all the drawing methods. It is similar to the Graphics class in AWT/Swing if you are familiar with that. All the logic on how to draw a circle, or a box, etc is contained inside Canvas. A canvas draws on a Bitmap or an open GL container but there is no reason why in the future it could be extended to draw onto other types of rasters.
SurfaceView is a View that contains a Surface. A surface is similar to a bitmap (it has a pixel store). I do not know how it is implemented but I'd imagine it is a some kind of Bitmap wrapper with extra methods for things that are directly related to screen displays (That is the reason for a surface, a Bitmap is too generic). You can get a Canvas from your Surface which is really getting the Canvas associated with the underlying Bitmap.
Your questions.
1.Canvas has its own Bitmap attached to it. Surface has its own Canvas attached to it.
Yes, a canvas operates on a Bitmap (or an open GL panel). Surface gives you a Canvas that is operating on whatever Surface is using for its Bitmap style pixel store.
2.All View's of window share the same Surface and thus share the same Canvas.
No. You could have as many surface views as you want.
3.SurfaceView is subclass of View, which, unlike other View's subclasses and View itself, has its own Surface to draw in.
Yes. Just like ListView is a subclass of View that has its own List data structure. Each subclass of View does something different.

How to add a text on the top of GLSurfaceview with transparent background in android?

Hi im having a parent viewgroup which has a background, contains a openglview as a part of that viewgroup.
What I want exactly is, i need a openglview with a transparent background and I want to able to see the parent background and I want to be able to write text on top of openglview, I dont want to use textures.
I tried this options,
Setting the openglview zorderontop as true. It makes my text to go behind the glview. If im not making zorderontop true, the background is black.
Setting the transluent theme to the activity which makes my glview and also the parent view group to become transparent.
I tried to inflate the layout contains the glview and use ContexThemeWrapper class to change the theme of the glview dynamically. But setTheme() not working at runtime. only applying theme in manifest file it works.
Applying the layout backgroud to transparent also didnt work, still black background.
The problem is that you're drawing to two separate surfaces: one surface created by ViewRoot, and one surface created for the GLSurfaceView. These surfaces are composited by SurfaceFlinger, one on top of the other. (By default the ViewRoot surface will be on top and the GLSurfaceView surface will be on bottom.)
Since all of your Views are drawn into the ViewRoot's surface, they must all be on top of the OpenGL surface or beneath the OpenGL surface.
If you don't want to use textures, period, your only choice is to create a third surface, this time with SurfaceView instead of GLSurfaceView, to draw your text above the GLSurfaceView.

Categories

Resources