Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[android] hook into surface holder to cleanup renderer on the right thread before the surface is destroyed #13926

Merged
merged 1 commit into from
Feb 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ protected void onSurfaceChanged(@NonNull GL10 gl, int width, int height) {
nativeOnSurfaceChanged(width, height);
}

@CallSuper
protected void onSurfaceDestroyed() {
nativeOnSurfaceDestroyed();
}

@CallSuper
protected void onDrawFrame(GL10 gl) {
long startTime = System.nanoTime();
Expand Down Expand Up @@ -123,6 +128,8 @@ private native void nativeInitialize(MapRenderer self,

private native void nativeOnSurfaceChanged(int width, int height);

private native void nativeOnSurfaceDestroyed();

private native void nativeRender();

private long timeElapsed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import android.opengl.GLSurfaceView;

import android.support.annotation.NonNull;
import android.view.SurfaceHolder;

import com.mapbox.mapboxsdk.maps.renderer.MapRenderer;
import com.mapbox.mapboxsdk.maps.renderer.egl.EGLConfigChooser;

Expand Down Expand Up @@ -33,6 +35,15 @@ public GLSurfaceViewMapRenderer(Context context,
glSurfaceView.setRenderer(this);
glSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);
glSurfaceView.setPreserveEGLContextOnPause(true);

glSurfaceView.getHolder().addCallback(new SurfaceHolderCallbackAdapter() {

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
GLSurfaceViewMapRenderer.this.onSurfaceDestroyed();
}

});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.mapbox.mapboxsdk.maps.renderer.glsurfaceview;

import android.view.SurfaceHolder;

class SurfaceHolderCallbackAdapter implements SurfaceHolder.Callback {

@Override
public void surfaceCreated(SurfaceHolder holder) {

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ protected void onSurfaceChanged(GL10 gl, int width, int height) {
super.onSurfaceChanged(gl, width, height);
}

/**
* Overridden to provide package access
*/
@Override
protected void onSurfaceDestroyed() {
super.onSurfaceDestroyed();
}

/**
* Overridden to provide package access
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ public void run() {
if (destroySurface) {
eglHolder.destroySurface();
destroySurface = false;
mapRenderer.onSurfaceDestroyed();
break;
}

Expand Down
20 changes: 15 additions & 5 deletions platform/android/src/map_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ MapRenderer::~MapRenderer() = default;

void MapRenderer::reset() {
destroyed = true;
// Make sure to destroy the renderer on the GL Thread
auto self = ActorRef<MapRenderer>(*this, mailbox);
self.ask(&MapRenderer::resetRenderer).wait();

if (renderer) {
// Make sure to destroy the renderer on the GL Thread
auto self = ActorRef<MapRenderer>(*this, mailbox);
self.ask(&MapRenderer::resetRenderer).wait();
}

// Lock to make sure there is no concurrent initialisation on the gl thread
std::lock_guard<std::mutex> lock(initialisationMutex);
Expand Down Expand Up @@ -113,7 +116,6 @@ void MapRenderer::requestSnapshot(SnapshotCallback callback) {
// Called on OpenGL thread //

void MapRenderer::resetRenderer() {
assert (renderer);
renderer.reset();
}

Expand Down Expand Up @@ -188,6 +190,12 @@ void MapRenderer::onSurfaceChanged(JNIEnv&, jint width, jint height) {
requestRender();
}

void MapRenderer::onSurfaceDestroyed(JNIEnv&) {
// Make sure to destroy the renderer on the GL Thread
auto self = ActorRef<MapRenderer>(*this, mailbox);
self.ask(&MapRenderer::resetRenderer).wait();
}

// Static methods //

void MapRenderer::registerNative(jni::JNIEnv& env) {
Expand All @@ -204,7 +212,9 @@ void MapRenderer::registerNative(jni::JNIEnv& env) {
METHOD(&MapRenderer::onSurfaceCreated,
"nativeOnSurfaceCreated"),
METHOD(&MapRenderer::onSurfaceChanged,
"nativeOnSurfaceChanged"));
"nativeOnSurfaceChanged"),
METHOD(&MapRenderer::onSurfaceDestroyed,
"nativeOnSurfaceDestroyed"));
}

MapRenderer& MapRenderer::getNativePeer(JNIEnv& env, const jni::Object<MapRenderer>& jObject) {
Expand Down
3 changes: 3 additions & 0 deletions platform/android/src/map_renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class MapRenderer : public Scheduler {

void onSurfaceChanged(JNIEnv&, jint width, jint height);

// Called on Main thread
void onSurfaceDestroyed(JNIEnv&);

private:
jni::WeakReference<jni::Object<MapRenderer>, jni::EnvAttachingDeleter> javaPeer;

Expand Down