Class GLSurfaceView
- java.lang.Object
-
- SurfaceView
-
- com.kakao.vectormap.graphics.gl.GLSurfaceView
-
- Direct Known Subclasses:
KGLSurfaceView
public abstract class GLSurfaceView extends SurfaceView
An implementation of SurfaceView that uses the dedicated surface for displaying OpenGL rendering.A GLSurfaceView provides the following features:
- Manages a surface, which is a special piece of memory that can be composited into the Android view system.
- Manages an EGL display, which enables OpenGL to render into a surface.
- Accepts a user-provided Renderer object that does the actual rendering.
- Renders on a dedicated thread to decouple rendering performance from the UI thread.
- Supports both on-demand and continuous rendering.
- Optionally wraps, traces, and/or error-checks the renderer's OpenGL calls.
Developer Guides
For more information about how to use OpenGL, read the OpenGL developer guide.
Using GLSurfaceView
Typically you use GLSurfaceView by subclassing it and overriding one or more of the View system input event methods. If your application does not need to override event methods then GLSurfaceView can be used as-is. For the most part GLSurfaceView behavior is customized by calling "set" methods rather than by subclassing. For example, unlike a regular View, drawing is delegated to a separate Renderer object which is registered with the GLSurfaceView using the
#setRenderer(Renderer)
call.Initializing GLSurfaceView
All you have to do to initialize a GLSurfaceView is call#setRenderer(Renderer)
. However, if desired, you can modify the default behavior of GLSurfaceView by calling one or more of these methods before calling setRenderer:setDebugFlags(int)
setEGLConfigChooser(boolean)
setEGLConfigChooser(EGLConfigChooser)
setEGLConfigChooser(int, int, int, int, int, int)
setGLWrapper(GLWrapper)
Specifying the android.view.Surface
By default GLSurfaceView will create a PixelFormat.RGB_888 format surface. If a translucent surface is required, call getHolder().setFormat(PixelFormat.TRANSLUCENT). The exact format of a TRANSLUCENT surface is device dependent, but it will be a 32-bit-per-pixel surface with 8 bits per component.Choosing an EGL Configuration
A given Android device may support multiple EGLConfig rendering configurations. The available configurations may differ in how many channels of data are present, as well as how many bits are allocated to each channel. Therefore, the first thing GLSurfaceView has to do when starting to render is choose what EGLConfig to use.By default GLSurfaceView chooses a EGLConfig that has an RGB_888 pixel format, with at least a 16-bit depth buffer and no stencil.
If you would prefer a different EGLConfig you can override the default behavior by calling one of the setEGLConfigChooser methods.
Debug Behavior
You can optionally modify the behavior of GLSurfaceView by calling one or more of the debugging methodssetDebugFlags(int)
, andsetGLWrapper(com.kakao.vectormap.graphics.gl.GLSurfaceView.GLWrapper)
. These methods may be called before and/or after setRenderer, but typically they are called before setRenderer so that they take effect immediately.Setting a Renderer
Finally, you must callsetRenderer(com.kakao.vectormap.graphics.gl.GLSurfaceView.Renderer, java.lang.Thread.UncaughtExceptionHandler)
to register aGLSurfaceView.Renderer
. The renderer is responsible for doing the actual OpenGL rendering.Rendering Mode
Once the renderer is set, you can control whether the renderer draws continuously or on-demand by callingsetRenderMode(int)
. The default is continuous rendering.Activity Life-cycle
A GLSurfaceView must be notified when to pause and resume rendering. GLSurfaceView clients are required to callonPause()
when the activity stops andonResume()
when the activity starts. These calls allow GLSurfaceView to pause and resume the rendering thread, and also allow GLSurfaceView to release and recreate the OpenGL display.Handling events
To handle an event you will typically subclass GLSurfaceView and override the appropriate method, just as you would with any other View. However, when handling the event, you may need to communicate with the Renderer object that's running in the rendering thread. You can do this using any standard Java cross-thread communication mechanism. In addition, one relatively easy way to communicate with your renderer is to call
queueEvent(Runnable)
. For example:class MyGLSurfaceView extends GLSurfaceView { private MyRenderer mMyRenderer; public void start() { mMyRenderer = ...; setRenderer(mMyRenderer); } public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { queueEvent(new Runnable() { // This method will be called on the rendering // thread: public void run() { mMyRenderer.handleDpadCenter(); }}); return true; } return super.onKeyDown(keyCode, event); } }
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
GLSurfaceView.BaseConfigChooser
static interface
GLSurfaceView.EGLConfigChooser
An interface for choosing an EGLConfig configuration from a list of potential configurations.static interface
GLSurfaceView.EGLContextFactory
An interface for customizing the eglCreateContext and eglDestroyContext calls.static interface
GLSurfaceView.EGLWindowSurfaceFactory
An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls.static interface
GLSurfaceView.GLWrapper
An interface used to wrap a GL interface.static interface
GLSurfaceView.Renderer
A generic renderer interface.
-
Field Summary
Fields Modifier and Type Field Description static int
DEBUG_CHECK_GL_ERROR
Check glError() after every GL call and throw an exception if glError indicates that an error has occurred.static int
DEBUG_LOG_GL_CALLS
Log GL calls to the system log at "verbose" level with tag "GLSurfaceView".static int
EXIT_TIMEOUT
가끔 지도 종료시 오래 걸리는 현상 때문에 ANR 이슈가 있음.static int
RENDERMODE_CONTINUOUSLY
The renderer is called continuously to re-render the scene.static int
RENDERMODE_WHEN_DIRTY
The renderer only renders when the surface is created, or whenrequestRender()
is called.
-
Constructor Summary
Constructors Constructor Description GLSurfaceView(Context context)
Standard View constructor.GLSurfaceView(Context context, AttributeSet attrs)
Standard View constructor.
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description void
doStop()
int
getDebugFlags()
Get the current value of the debug flags.boolean
getPreserveEGLContextOnPause()
int
getRenderMode()
Get the current rendering mode.abstract void
initEngine(boolean glThreadNull)
static boolean
isExitTimeout(long startTime)
abstract boolean
isFinishManually()
void
onPause()
Pause the rendering thread, optionally tearing down the EGL context depending upon the value ofsetPreserveEGLContextOnPause(boolean)
.void
onResume()
Resumes the rendering thread, re-creating the OpenGL context if necessary.void
queueEvent(java.lang.Runnable r)
Queue a runnable to be run on the GL rendering thread.void
requestRender()
Request that the renderer render a frame.void
setDebugFlags(int debugFlags)
Set the debug flags to a new value.void
setEGLConfigChooser(boolean needDepth)
Install a config chooser which will choose a config as close to 16-bit RGB as possible, with or without an optional depth buffer as close to 16-bits as possible.void
setEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize)
Install a config chooser which will choose a config with at least the specified depthSize and stencilSize, and exactly the specified redSize, greenSize, blueSize and alphaSize.void
setEGLConfigChooser(GLSurfaceView.EGLConfigChooser configChooser)
Install a custom EGLConfigChooser.void
setEGLContextClientVersion(int version)
Inform the default EGLContextFactory and default EGLConfigChooser which EGLContext client version to pick.void
setEGLContextFactory(GLSurfaceView.EGLContextFactory factory)
Install a custom EGLContextFactory.void
setEGLWindowSurfaceFactory(GLSurfaceView.EGLWindowSurfaceFactory factory)
Install a custom EGLWindowSurfaceFactory.void
setGLWrapper(GLSurfaceView.GLWrapper glWrapper)
Set the glWrapper.void
setPreserveEGLContextOnPause(boolean preserveOnPause)
Control whether the EGL context is preserved when the GLSurfaceView is paused and resumed.void
setRenderer(GLSurfaceView.Renderer renderer, java.lang.Thread.UncaughtExceptionHandler exceptionHandler)
Set the renderer associated with this view.void
setRenderMode(int renderMode)
Set the rendering mode.void
surfaceChanged(SurfaceHolder holder, int format, int w, int h)
This method is part of the SurfaceHolder.Callback interface, and is not normally called or subclassed by clients of GLSurfaceView.void
surfaceCreated(SurfaceHolder holder)
This method is part of the SurfaceHolder.Callback interface, and is not normally called or subclassed by clients of GLSurfaceView.void
surfaceDestroyed(SurfaceHolder holder)
This method is part of the SurfaceHolder.Callback interface, and is not normally called or subclassed by clients of GLSurfaceView.void
surfaceRedrawNeeded(SurfaceHolder holder)
Deprecated.void
surfaceRedrawNeededAsync(SurfaceHolder holder, java.lang.Runnable finishDrawing)
This method is part of the SurfaceHolder.Callback2 interface, and is not normally called or subclassed by clients of GLSurfaceView.
-
-
-
Field Detail
-
EXIT_TIMEOUT
public static final int EXIT_TIMEOUT
가끔 지도 종료시 오래 걸리는 현상 때문에 ANR 이슈가 있음. sGLThreadManager.wait() 시에 타임아웃으로 ANR 우회하도록.- See Also:
- Constant Field Values
-
RENDERMODE_WHEN_DIRTY
public static final int RENDERMODE_WHEN_DIRTY
The renderer only renders when the surface is created, or whenrequestRender()
is called.
-
RENDERMODE_CONTINUOUSLY
public static final int RENDERMODE_CONTINUOUSLY
The renderer is called continuously to re-render the scene.- See Also:
getRenderMode()
,setRenderMode(int)
, Constant Field Values
-
DEBUG_CHECK_GL_ERROR
public static final int DEBUG_CHECK_GL_ERROR
Check glError() after every GL call and throw an exception if glError indicates that an error has occurred. This can be used to help track down which OpenGL ES call is causing an error.- See Also:
getDebugFlags()
,setDebugFlags(int)
, Constant Field Values
-
DEBUG_LOG_GL_CALLS
public static final int DEBUG_LOG_GL_CALLS
Log GL calls to the system log at "verbose" level with tag "GLSurfaceView".- See Also:
getDebugFlags()
,setDebugFlags(int)
, Constant Field Values
-
-
Constructor Detail
-
GLSurfaceView
public GLSurfaceView(Context context)
Standard View constructor. In order to render something, you must callsetRenderer(com.kakao.vectormap.graphics.gl.GLSurfaceView.Renderer, java.lang.Thread.UncaughtExceptionHandler)
to register a renderer.
-
GLSurfaceView
public GLSurfaceView(Context context, AttributeSet attrs)
Standard View constructor. In order to render something, you must callsetRenderer(com.kakao.vectormap.graphics.gl.GLSurfaceView.Renderer, java.lang.Thread.UncaughtExceptionHandler)
to register a renderer.
-
-
Method Detail
-
isExitTimeout
public static boolean isExitTimeout(long startTime)
-
doStop
public void doStop() throws java.lang.Throwable
- Throws:
java.lang.Throwable
-
setGLWrapper
public void setGLWrapper(GLSurfaceView.GLWrapper glWrapper)
Set the glWrapper. If the glWrapper is not null, itsGLWrapper#wrap(GL)
method is called whenever a surface is created. A GLWrapper can be used to wrap the GL object that's passed to the renderer. Wrapping a GL object enables examining and modifying the behavior of the GL calls made by the renderer.Wrapping is typically used for debugging purposes.
The default value is null.
- Parameters:
glWrapper
- the new GLWrapper
-
setDebugFlags
public void setDebugFlags(int debugFlags)
Set the debug flags to a new value. The value is constructed by OR-together zero or more of the DEBUG_CHECK_* constants. The debug flags take effect whenever a surface is created. The default value is zero.- Parameters:
debugFlags
- the new debug flags- See Also:
DEBUG_CHECK_GL_ERROR
,DEBUG_LOG_GL_CALLS
-
getDebugFlags
public int getDebugFlags()
Get the current value of the debug flags.- Returns:
- the current value of the debug flags.
-
setPreserveEGLContextOnPause
public void setPreserveEGLContextOnPause(boolean preserveOnPause)
Control whether the EGL context is preserved when the GLSurfaceView is paused and resumed.If set to true, then the EGL context may be preserved when the GLSurfaceView is paused.
Prior to API level 11, whether the EGL context is actually preserved or not depends upon whether the Android device can support an arbitrary number of EGL contexts or not. Devices that can only support a limited number of EGL contexts must release the EGL context in order to allow multiple applications to share the GPU.
If set to false, the EGL context will be released when the GLSurfaceView is paused, and recreated when the GLSurfaceView is resumed.
The default is false.
- Parameters:
preserveOnPause
- preserve the EGL context when paused
-
getPreserveEGLContextOnPause
public boolean getPreserveEGLContextOnPause()
- Returns:
- true if the EGL context will be preserved when paused
-
setRenderer
public void setRenderer(GLSurfaceView.Renderer renderer, java.lang.Thread.UncaughtExceptionHandler exceptionHandler)
Set the renderer associated with this view. Also starts the thread that will call the renderer, which in turn causes the rendering to start.This method should be called once and only once in the life-cycle of a GLSurfaceView.
The following GLSurfaceView methods can only be called before setRenderer is called:
setEGLConfigChooser(boolean)
setEGLConfigChooser(EGLConfigChooser)
setEGLConfigChooser(int, int, int, int, int, int)
The following GLSurfaceView methods can only be called after setRenderer is called:
- Parameters:
renderer
- the renderer to use to perform OpenGL drawing.
-
setEGLContextFactory
public void setEGLContextFactory(GLSurfaceView.EGLContextFactory factory)
Install a custom EGLContextFactory.If this method is called, it must be called before
#setRenderer(Renderer)
is called.If this method is not called, then by default a context will be created with no shared context and with a null attribute list.
-
setEGLWindowSurfaceFactory
public void setEGLWindowSurfaceFactory(GLSurfaceView.EGLWindowSurfaceFactory factory)
Install a custom EGLWindowSurfaceFactory.If this method is called, it must be called before
#setRenderer(Renderer)
is called.If this method is not called, then by default a window surface will be created with a null attribute list.
-
setEGLConfigChooser
public void setEGLConfigChooser(GLSurfaceView.EGLConfigChooser configChooser)
Install a custom EGLConfigChooser.If this method is called, it must be called before
#setRenderer(Renderer)
is called.If no setEGLConfigChooser method is called, then by default the view will choose an EGLConfig that is compatible with the current android.view.Surface, with a depth buffer depth of at least 16 bits.
- Parameters:
configChooser
-
-
setEGLConfigChooser
public void setEGLConfigChooser(boolean needDepth)
Install a config chooser which will choose a config as close to 16-bit RGB as possible, with or without an optional depth buffer as close to 16-bits as possible.If this method is called, it must be called before
#setRenderer(Renderer)
is called.If no setEGLConfigChooser method is called, then by default the view will choose an RGB_888 surface with a depth buffer depth of at least 16 bits.
- Parameters:
needDepth
-
-
setEGLConfigChooser
public void setEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize)
Install a config chooser which will choose a config with at least the specified depthSize and stencilSize, and exactly the specified redSize, greenSize, blueSize and alphaSize.If this method is called, it must be called before
#setRenderer(Renderer)
is called.If no setEGLConfigChooser method is called, then by default the view will choose an RGB_888 surface with a depth buffer depth of at least 16 bits.
-
setEGLContextClientVersion
public void setEGLContextClientVersion(int version)
Inform the default EGLContextFactory and default EGLConfigChooser which EGLContext client version to pick.Use this method to create an OpenGL ES 2.0-compatible context. Example:
public MyView(Context context) { super(context); setEGLContextClientVersion(2); // Pick an OpenGL ES 2.0 context. setRenderer(new MyRenderer()); }
Note: Activities which require OpenGL ES 2.0 should indicate this by setting @lt;uses-feature android:glEsVersion="0x00020000" /> in the activity's AndroidManifest.xml file.
If this method is called, it must be called before
#setRenderer(Renderer)
is called.This method only affects the behavior of the default EGLContexFactory and the default EGLConfigChooser. If
setEGLContextFactory(EGLContextFactory)
has been called, then the supplied EGLContextFactory is responsible for creating an OpenGL ES 2.0-compatible context. IfsetEGLConfigChooser(EGLConfigChooser)
has been called, then the supplied EGLConfigChooser is responsible for choosing an OpenGL ES 2.0-compatible config.- Parameters:
version
- The EGLContext client version to choose. Use 2 for OpenGL ES 2.0
-
setRenderMode
public void setRenderMode(int renderMode)
Set the rendering mode. When renderMode is RENDERMODE_CONTINUOUSLY, the renderer is called repeatedly to re-render the scene. When renderMode is RENDERMODE_WHEN_DIRTY, the renderer only rendered when the surface is created, or whenrequestRender()
is called. Defaults to RENDERMODE_CONTINUOUSLY.Using RENDERMODE_WHEN_DIRTY can improve battery life and overall system performance by allowing the GPU and CPU to idle when the view does not need to be updated.
This method can only be called after
#setRenderer(Renderer)
- Parameters:
renderMode
- one of the RENDERMODE_X constants- See Also:
RENDERMODE_CONTINUOUSLY
,RENDERMODE_WHEN_DIRTY
-
getRenderMode
public int getRenderMode()
Get the current rendering mode. May be called from any thread. Must not be called before a renderer has been set.- Returns:
- the current rendering mode.
- See Also:
RENDERMODE_CONTINUOUSLY
,RENDERMODE_WHEN_DIRTY
-
requestRender
public void requestRender()
Request that the renderer render a frame. This method is typically used when the render mode has been set toRENDERMODE_WHEN_DIRTY
, so that frames are only rendered on demand. May be called from any thread. Must not be called before a renderer has been set.
-
surfaceCreated
public void surfaceCreated(SurfaceHolder holder)
This method is part of the SurfaceHolder.Callback interface, and is not normally called or subclassed by clients of GLSurfaceView.
-
surfaceDestroyed
public void surfaceDestroyed(SurfaceHolder holder)
This method is part of the SurfaceHolder.Callback interface, and is not normally called or subclassed by clients of GLSurfaceView.
-
surfaceChanged
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
This method is part of the SurfaceHolder.Callback interface, and is not normally called or subclassed by clients of GLSurfaceView.
-
surfaceRedrawNeededAsync
public void surfaceRedrawNeededAsync(SurfaceHolder holder, java.lang.Runnable finishDrawing)
This method is part of the SurfaceHolder.Callback2 interface, and is not normally called or subclassed by clients of GLSurfaceView.
-
surfaceRedrawNeeded
@Deprecated public void surfaceRedrawNeeded(SurfaceHolder holder)
Deprecated.This method is part of the SurfaceHolder.Callback2 interface, and is not normally called or subclassed by clients of GLSurfaceView.
-
onPause
public void onPause()
Pause the rendering thread, optionally tearing down the EGL context depending upon the value ofsetPreserveEGLContextOnPause(boolean)
. This method should be called when it is no longer desirable for the GLSurfaceView to continue rendering, such as in response toActivity.onStop
. Must not be called before a renderer has been set.
-
onResume
public void onResume()
Resumes the rendering thread, re-creating the OpenGL context if necessary. It is the counterpart toonPause()
. This method should typically be called inActivity.onStart
. Must not be called before a renderer has been set.
-
queueEvent
public void queueEvent(java.lang.Runnable r)
Queue a runnable to be run on the GL rendering thread. This can be used to communicate with the Renderer on the rendering thread. Must not be called before a renderer has been set.- Parameters:
r
- the runnable to be run on the GL rendering thread.
-
initEngine
public abstract void initEngine(boolean glThreadNull)
-
isFinishManually
public abstract boolean isFinishManually()
-
-