summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2017-01-31 13:43:37 +0200
committerTobrun <tobrun.van.nuland@gmail.com>2017-02-10 16:37:53 +0100
commit35b810dd6ddfc5e6f1a635b2682b3add5ec5d5bb (patch)
tree12a453473e605f389a963cc4a752eb667ff28316 /platform/android/MapboxGLAndroidSDK
parent9b05af8f45f669dc1f79938a1112adac3db7ca00 (diff)
downloadqtlocation-mapboxgl-35b810dd6ddfc5e6f1a635b2682b3add5ec5d5bb.tar.gz
[android] render on gl thread
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java216
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java155
2 files changed, 193 insertions, 178 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index efc1001467..11928615d6 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -53,6 +53,8 @@ import java.util.List;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
+import timber.log.Timber;
+
import static android.opengl.GLSurfaceView.RENDERMODE_WHEN_DIRTY;
/**
@@ -69,15 +71,18 @@ import static android.opengl.GLSurfaceView.RENDERMODE_WHEN_DIRTY;
* <strong>Warning:</strong> Please note that you are responsible for getting permission to use the map data,
* and for ensuring your use adheres to the relevant terms of use.
*/
-public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
+public class MapView extends FrameLayout {
private NativeMapView nativeMapView;
private boolean destroyed;
- private boolean hasSurface = false;
private GLSurfaceView glSurfaceView;
+ private CompassView compassView;
+ private ImageView attrView;
+ private View logoView;
+ private MyLocationView myLocationView;
private MapboxMap mapboxMap;
- private MapCallback mapCallback;
+ private MapCallback mapCallback = new MapCallback();
private boolean onStartCalled;
private boolean onStopCalled;
@@ -87,6 +92,8 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
private ConnectivityReceiver connectivityReceiver;
+ private MapboxMapOptions mapboxMapOptions;
+
@UiThread
public MapView(@NonNull Context context) {
super(context);
@@ -112,21 +119,89 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
}
private void initialise(@NonNull final Context context, @NonNull final MapboxMapOptions options) {
+ Timber.i("Initialize");
+ this.mapboxMapOptions = options;
+
+ // in IDE, show preview map
if (isInEditMode()) {
- // in IDE, show preview map
LayoutInflater.from(context).inflate(R.layout.mapbox_mapview_preview, this);
return;
}
+ //Setup basic view properties
+ setupViewProperties();
+
// inflate view
View view = LayoutInflater.from(context).inflate(R.layout.mapbox_mapview_internal, this);
- CompassView compassView = (CompassView) view.findViewById(R.id.compassView);
- MyLocationView myLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
- ImageView attrView = (ImageView) view.findViewById(R.id.attributionView);
- initialiseDrawingSurface();
+ compassView = (CompassView) view.findViewById(R.id.compassView);
+ myLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
+ attrView = (ImageView) view.findViewById(R.id.attributionView);
+ logoView = view.findViewById(R.id.logoView);
+
+ glSurfaceView = (GLSurfaceView) findViewById(R.id.surfaceView);
+ glSurfaceView.setEGLConfigChooser(8, 8, 8, 0 /** TODO: What alpha value do we need here?? */, 16, 8);
+ glSurfaceView.setEGLContextClientVersion(2);
+ glSurfaceView.setRenderer(new GLSurfaceView.Renderer() {
+ @Override
+ public void onSurfaceCreated(final GL10 gl, EGLConfig eglConfig) {
+ Timber.i("[%s] onSurfaceCreated", Thread.currentThread().getName());
+ glSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);
+
+ // Create native Map object
+ nativeMapView = new NativeMapView(MapView.this);
+
+ //Continue configuring the map view on the main thread
+ MapView.this.post(new Runnable() {
+ @Override
+ public void run() {
+ onNativeMapViewReady();
+ }
+ });
+ }
+
+ @Override
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ Timber.i("[%s] onSurfaceChanged %sx%s", Thread.currentThread().getName(), width, height);
+ // Sets the current view port to the new size.
+ gl.glViewport(0, 0, width, height);
+ nativeMapView.onViewportChanged(width, height);
+ }
+
+ @Override
+ public void onDrawFrame(GL10 gl) {
+ Timber.i("[%s] onDrawFrame", Thread.currentThread().getName());
+ nativeMapView.render();
+ }
+ });
+
+ }
+
+ private void setupViewProperties() {
+ // allow onDraw invocation
+ setWillNotDraw(false);
+
+ // Ensure this view is interactable
+ setClickable(true);
+ setLongClickable(true);
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+ requestDisallowInterceptTouchEvent(true);
+ }
- // create native Map object
- nativeMapView = new NativeMapView(this);
+// private void loopRender() {
+// postDelayed(new Runnable() {
+// @Override
+// public void run() {
+// //glSurfaceView.queueEvent(renderRunnable);
+// onInvalidate();
+//// nativeMapView.update();
+// //onInvalidate();
+// loopRender();
+// }
+// }, 500);
+// }
+
+ protected void onNativeMapViewReady() {
// callback for focal point invalidation
FocalPointInvalidator focalPoint = new FocalPointInvalidator(compassView);
@@ -139,7 +214,7 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
// setup components for MapboxMap creation
Projection proj = new Projection(nativeMapView);
- UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, view.findViewById(R.id.logoView));
+ UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, logoView);
TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint, zoomInvalidator);
MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint);
MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer));
@@ -149,56 +224,23 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
registerTouchListener, annotations);
// user input
- mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings, trackingSettings, annotations);
+ mapGestureDetector = new MapGestureDetector(getContext(), transform, proj, uiSettings, trackingSettings, annotations);
mapKeyListener = new MapKeyListener(transform, trackingSettings, uiSettings);
mapZoomButtonController = new MapZoomButtonController(this, uiSettings, transform);
// inject widgets with MapboxMap
compassView.setMapboxMap(mapboxMap);
myLocationView.setMapboxMap(mapboxMap);
- attrView.setOnClickListener(new AttributionOnClickListener(context, transform));
-
- // Ensure this view is interactable
- setClickable(true);
- setLongClickable(true);
- setFocusable(true);
- setFocusableInTouchMode(true);
- requestDisallowInterceptTouchEvent(true);
-
- // allow onDraw invocation
- setWillNotDraw(false);
+ attrView.setOnClickListener(new AttributionOnClickListener(getContext(), transform));
// notify Map object about current connectivity state
nativeMapView.setReachability(isConnected());
// initialise MapboxMap
- mapboxMap.initialise(context, options);
- }
-
- private void initialiseDrawingSurface() {
- glSurfaceView = (GLSurfaceView) findViewById(R.id.surfaceView);
- glSurfaceView.setEGLContextClientVersion(2);
- glSurfaceView.setRenderer(this);
- glSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);
- }
-
- @Override
- public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
- nativeMapView.initializeDisplay();
- nativeMapView.initializeContext();
- nativeMapView.createSurface(glSurfaceView.getHolder().getSurface());
- hasSurface = true;
- }
-
- @Override
- public void onSurfaceChanged(GL10 gl10, int i, int i1) {
- nativeMapView.resizeView(i, i1);
- nativeMapView.resizeFramebuffer(i, i1);
- }
-
- @Override
- public void onDrawFrame(GL10 gl10) {
+ mapboxMap.initialise(getContext(), mapboxMapOptions);
+ addOnMapChangedListener(mapCallback);
+ mapboxMap.onStart();
}
//
@@ -218,7 +260,7 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
*/
@UiThread
public void onCreate(@Nullable Bundle savedInstanceState) {
- nativeMapView.setAccessToken(Mapbox.getAccessToken());
+ //nativeMapView.setAccessToken(Mapbox.getAccessToken());
if (savedInstanceState == null) {
MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapLoadEvent());
@@ -226,7 +268,6 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
mapboxMap.onRestoreInstanceState(savedInstanceState);
}
- addOnMapChangedListener(mapCallback = new MapCallback(mapboxMap));
}
/**
@@ -249,7 +290,6 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
public void onStart() {
onStartCalled = true;
registerConnectivityReceiver();
- mapboxMap.onStart();
glSurfaceView.onResume();
}
@@ -296,12 +336,17 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
}
destroyed = true;
- hasSurface = false;
- nativeMapView.terminateContext();
- nativeMapView.terminateDisplay();
- nativeMapView.destroySurface();
- nativeMapView.destroy();
- nativeMapView = null;
+ //nativeMapView.terminateContext();
+ //nativeMapView.terminateDisplay();
+ //nativeMapView.destroySurface();
+
+ glSurfaceView.queueEvent(new Runnable() {
+ @Override
+ public void run() {
+ nativeMapView.destroy();
+ nativeMapView = null;
+ }
+ });
}
private void registerConnectivityReceiver() {
@@ -435,28 +480,34 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
// Rendering
//
- // Called when the map needs to be rerendered
- // Called via JNI from NativeMapView
+ /**
+ * Called when the map needs to be re-rendered
+ * Called via JNI from NativeMapView
+ * <p>
+ * May be called from any thread
+ */
protected void onInvalidate() {
+ Timber.i("onInvalidate");
+ //glSurfaceView.onInvalidate();
+ //XXX Don't need this right? postInvalidate();
postInvalidate();
}
+ protected void requestRender() {
+ if (glSurfaceView != null) {
+ glSurfaceView.requestRender();
+ }
+ }
+
@Override
public void onDraw(Canvas canvas) {
+ Timber.i("onDraw");
super.onDraw(canvas);
if (isInEditMode()) {
return;
}
- if (destroyed) {
- return;
- }
-
- if (!hasSurface) {
- return;
- }
-
- nativeMapView.render();
+ //glSurfaceView.queueEvent(renderRunnable);
}
@Override
@@ -466,7 +517,9 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
}
if (!isInEditMode()) {
- nativeMapView.resizeView(width, height);
+ if (nativeMapView != null) {
+ //XXX This should happen through GLSurfaceView#Renderer callbacks nativeMapView.resizeView(width, height);
+ }
}
}
@@ -488,7 +541,9 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
if (isInEditMode()) {
return;
}
- mapZoomButtonController.setVisible(visibility == View.VISIBLE);
+ if (mapZoomButtonController != null) {
+ mapZoomButtonController.setVisible(visibility == View.VISIBLE);
+ }
}
//
@@ -501,7 +556,7 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
// Called when an action we are listening to in the manifest has been sent
@Override
public void onReceive(Context context, Intent intent) {
- if (!destroyed && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ if (nativeMapView != null && !destroyed && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
nativeMapView.setReachability(!intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false));
}
}
@@ -929,16 +984,11 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
}
}
- private static class MapCallback implements OnMapChangedListener {
+ private class MapCallback implements OnMapChangedListener {
- private final MapboxMap mapboxMap;
private final List<OnMapReadyCallback> onMapReadyCallbackList = new ArrayList<>();
private boolean initialLoad = true;
- MapCallback(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- }
-
@Override
public void onMapChanged(@MapChange int change) {
if (change == DID_FINISH_LOADING_STYLE && initialLoad) {
@@ -971,4 +1021,14 @@ public class MapView extends FrameLayout implements GLSurfaceView.Renderer {
onMapReadyCallbackList.add(callback);
}
}
+
+ private class RenderRunnable implements Runnable {
+ @Override
+ public void run() {
+ if (destroyed) {
+ return;
+ }
+ nativeMapView.render();
+ }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index 1d260cacf3..5069a25d69 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -68,6 +68,8 @@ final class NativeMapView {
//
public NativeMapView(MapView mapView) {
+ this.mapView = mapView;
+
Context context = mapView.getContext();
String dataPath = OfflineManager.getDatabasePath(context);
@@ -95,7 +97,10 @@ final class NativeMapView {
throw new IllegalArgumentException("totalMemory cannot be negative.");
}
onMapChangedListeners = new CopyOnWriteArrayList<>();
- this.mapView = mapView;
+
+// if (Looper.myLooper() == null) {
+// Looper.prepare();
+// }
nativeMapViewPtr = nativeCreate(cachePath, dataPath, apkPath, pixelRatio, availableProcessors, totalMemory);
}
@@ -103,84 +108,10 @@ final class NativeMapView {
// Methods
//
- private boolean isDestroyedOn(String callingMethod) {
- if (destroyed && !TextUtils.isEmpty(callingMethod)) {
- Timber.e(String.format(MapboxConstants.MAPBOX_LOCALE,
- "You're calling `%s` after the `MapView` was destroyed, were you invoking it after `onDestroy()`?",
- callingMethod));
- }
- return destroyed;
- }
-
- public void destroy() {
- nativeDestroy(nativeMapViewPtr);
- nativeMapViewPtr = 0;
- mapView = null;
- destroyed = true;
- }
-
- public void initializeDisplay() {
- if (isDestroyedOn("initializeDisplay")) {
- return;
- }
- nativeInitializeDisplay(nativeMapViewPtr);
- }
-
- public void terminateDisplay() {
- if (isDestroyedOn("terminateDisplay")) {
- return;
- }
- nativeTerminateDisplay(nativeMapViewPtr);
- }
-
- public void initializeContext() {
- if (isDestroyedOn("initializeContext")) {
- return;
- }
- nativeInitializeContext(nativeMapViewPtr);
- }
-
- public void terminateContext() {
- if (isDestroyedOn("terminateContext")) {
- return;
- }
- nativeTerminateContext(nativeMapViewPtr);
- }
-
- public void createSurface(Surface surface) {
- if (isDestroyedOn("createSurface")) {
+ public void onViewportChanged(int width, int height) {
+ if (isDestroyedOn("onViewportChanged")) {
return;
}
- nativeCreateSurface(nativeMapViewPtr, surface);
- }
-
- public void destroySurface() {
- if (isDestroyedOn("destroySurface")) {
- return;
- }
- nativeDestroySurface(nativeMapViewPtr);
- }
-
- public void update() {
- if (isDestroyedOn("update")) {
- return;
- }
- nativeUpdate(nativeMapViewPtr);
- }
-
- public void render() {
- if (isDestroyedOn("render")) {
- return;
- }
- nativeRender(nativeMapViewPtr);
- }
-
- public void resizeView(int width, int height) {
- if (isDestroyedOn("resizeView")) {
- return;
- }
- width = (int) (width / pixelRatio);
- height = (int) (height / pixelRatio);
if (width < 0) {
throw new IllegalArgumentException("width cannot be negative.");
@@ -203,31 +134,39 @@ final class NativeMapView {
+ "capping value at 65535 instead of " + height);
height = 65535;
}
- nativeViewResize(nativeMapViewPtr, width, height);
+
+ nativeOnViewportChanged(nativeMapViewPtr, width, height);
}
- public void resizeFramebuffer(int fbWidth, int fbHeight) {
- if (isDestroyedOn("resizeFramebuffer")) {
- return;
- }
- if (fbWidth < 0) {
- throw new IllegalArgumentException("fbWidth cannot be negative.");
+ private boolean isDestroyedOn(String callingMethod) {
+ if (destroyed && !TextUtils.isEmpty(callingMethod)) {
+ Timber.e(String.format(MapboxConstants.MAPBOX_LOCALE,
+ "You're calling `%s` after the `MapView` was destroyed, were you invoking it after `onDestroy()`?",
+ callingMethod));
}
+ return destroyed;
+ }
- if (fbHeight < 0) {
- throw new IllegalArgumentException("fbHeight cannot be negative.");
- }
+ public void destroy() {
+ nativeDestroy(nativeMapViewPtr);
+ nativeMapViewPtr = 0;
+ mapView = null;
+ destroyed = true;
+ }
- if (fbWidth > 65535) {
- throw new IllegalArgumentException(
- "fbWidth cannot be greater than 65535.");
+ public void update() {
+ if (isDestroyedOn("update")) {
+ return;
}
+ nativeUpdate(nativeMapViewPtr);
+ }
- if (fbHeight > 65535) {
- throw new IllegalArgumentException(
- "fbHeight cannot be greater than 65535.");
+ public void render() {
+ Timber.i("Render");
+ if (isDestroyedOn("render")) {
+ return;
}
- nativeFramebufferResize(nativeMapViewPtr, fbWidth, fbHeight);
+ nativeRender(nativeMapViewPtr);
}
public void addClass(String clazz) {
@@ -329,6 +268,7 @@ final class NativeMapView {
}
public void moveBy(double dx, double dy, long duration) {
+ Timber.i("Move by %sx%s - %s", dx, dy, duration);
if (isDestroyedOn("moveBy")) {
return;
}
@@ -343,6 +283,7 @@ final class NativeMapView {
}
public void setLatLng(LatLng latLng, long duration) {
+ Timber.i("setLatLng %sx%s - %s", latLng.getLatitude(), latLng.getLongitude(), duration);
if (isDestroyedOn("setLatLng")) {
return;
}
@@ -372,6 +313,7 @@ final class NativeMapView {
}
public void setPitch(double pitch, long duration) {
+ Timber.i("setLatLng %s - %s", pitch, duration);
if (isDestroyedOn("setPitch")) {
return;
}
@@ -926,14 +868,29 @@ final class NativeMapView {
// Callbacks
//
+ /**
+ * Called through JNI when the map needs to be re-rendered
+ */
protected void onInvalidate() {
+ Timber.i("onInvalidate");
mapView.onInvalidate();
}
- protected void onMapChanged(int rawChange) {
+ protected void wakeCallback() {
+ Timber.i("wake!");
+ mapView.requestRender();
+ }
+
+ protected void onMapChanged(final int rawChange) {
+ Timber.i("onMapChanged: %s", rawChange);
if (onMapChangedListeners != null) {
- for (MapView.OnMapChangedListener onMapChangedListener : onMapChangedListeners) {
- onMapChangedListener.onMapChanged(rawChange);
+ for (final MapView.OnMapChangedListener onMapChangedListener : onMapChangedListeners) {
+ mapView.post(new Runnable() {
+ @Override
+ public void run() {
+ onMapChangedListener.onMapChanged(rawChange);
+ }
+ });
}
}
}
@@ -974,9 +931,7 @@ final class NativeMapView {
private native void nativeRender(long nativeMapViewPtr);
- private native void nativeViewResize(long nativeMapViewPtr, int width, int height);
-
- private native void nativeFramebufferResize(long nativeMapViewPtr, int fbWidth, int fbHeight);
+ private native void nativeOnViewportChanged(long nativeMapViewPtr, int width, int height);
private native void nativeAddClass(long nativeMapViewPtr, String clazz);