Skip to content

Commit

Permalink
Merge branch 'hardware_rendering_yet_another_time'
Browse files Browse the repository at this point in the history
  • Loading branch information
simonpoole committed Aug 17, 2024
2 parents 1657379 + 169cc79 commit 625a0ea
Show file tree
Hide file tree
Showing 19 changed files with 164 additions and 90 deletions.
2 changes: 1 addition & 1 deletion documentation/docs/help/en/Advanced preferences.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ Enable voice command support: Default: _off_.

### Enable hardware acceleration

Do not use, may cause hangs of the app and other problems.
Turn on use of hardware rendering on Android 10 and later. Default: _off_

### Enable split window property editor

Expand Down
2 changes: 1 addition & 1 deletion src/main/assets/help/en/Advanced preferences.html
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ <h3>Enable JS Console</h3>
<h3>Enable voice commands</h3>
<p>Enable voice command support: Default: <em>off</em>.</p>
<h3>Enable hardware acceleration</h3>
<p>Do not use, may cause hangs of the app and other problems.</p>
<p>Turn on use of hardware rendering on Android 10 and later. Default: <em>off</em></p>
<h3>Enable split window property editor</h3>
<p>Enable displaying the property editor in a separate window if available. Default: <em>off</em></p>
<h3>Use &quot;new task&quot; mode for property editor</h3>
Expand Down
2 changes: 1 addition & 1 deletion src/main/assets/styles/Color-round-no-mp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</dash>
</feature>
<!-- Validation -->
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="STROKE" cap="ROUND" join="MITER" />
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="FILL" cap="ROUND" join="MITER" />
<feature type="problem_node_tagged" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="FILL" cap="BUTT" join="MITER" />
<feature type="problem_node_thin" updateWidth="false" widthFactor="1.0" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" strokeWidth="1.0" typefacestyle="0" textsize="12.0" />
<feature type="problem_way" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" labelKey="name" />
Expand Down
2 changes: 1 addition & 1 deletion src/main/assets/styles/Color-round.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</dash>
</feature>
<!-- Validation -->
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="STROKE" cap="ROUND" join="MITER" />
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="FILL" cap="ROUND" join="MITER" />
<feature type="problem_node_tagged" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="FILL" cap="BUTT" join="MITER" />
<feature type="problem_node_thin" updateWidth="false" widthFactor="1.0" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" strokeWidth="1.0" typefacestyle="0" textsize="12.0" />
<feature type="problem_way" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" labelKey="name" />
Expand Down
2 changes: 1 addition & 1 deletion src/main/assets/styles/No-path-patterns.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</dash>
</feature>
<!-- Validation -->
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="STROKE" cap="ROUND" join="MITER" />
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="FILL" cap="ROUND" join="MITER" />
<feature type="problem_node_tagged" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="FILL" cap="BUTT" join="MITER" />
<feature type="problem_node_thin" updateWidth="false" widthFactor="1.0" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" strokeWidth="1.0" typefacestyle="0" textsize="12.0" />
<feature type="problem_way" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" labelKey="name" />
Expand Down
2 changes: 1 addition & 1 deletion src/main/assets/styles/Pen-round.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</dash>
</feature>
<!-- Validation -->
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="STROKE" cap="ROUND" join="MITER" />
<feature type="problem_node" updateWidth="true" widthFactor="2.0" color="ffff00ff" style="FILL" cap="ROUND" join="MITER" />
<feature type="problem_node_tagged" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="FILL" cap="BUTT" join="MITER" />
<feature type="problem_node_thin" updateWidth="false" widthFactor="1.0" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" strokeWidth="1.0" typefacestyle="0" textsize="12.0" />
<feature type="problem_way" updateWidth="true" widthFactor="1.5" color="ffff00ff" style="STROKE" cap="BUTT" join="MITER" labelKey="name" />
Expand Down
20 changes: 17 additions & 3 deletions src/main/java/de/blau/android/Map.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ public class Map extends View implements IMapView {

private TrackerService tracker = null;

private final boolean hardwareLayerType;

/**
* Construct a new Map object that orchestrates the layer drawing and related rendering
*
Expand All @@ -192,7 +194,8 @@ public Map(@NonNull final Context context) {

iconRadius = Density.dpToPx(context, ICON_SIZE_DP / 2);

setLayerType(View.LAYER_TYPE_SOFTWARE, null);
hardwareLayerType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && App.getPreferences(context).hwAccelerationEnabled();
setLayerType(hardwareLayerType ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_SOFTWARE, null);
}

/**
Expand Down Expand Up @@ -225,7 +228,7 @@ public void setUpLayers(@NonNull Context ctx) {
layer = new de.blau.android.layer.mvt.MapOverlay(this, new VectorTileRenderer(), false);
((MapTilesOverlayLayer<?>) layer).setRendererInfo(backgroundSource);
} else {
layer = new MapTilesLayer<Bitmap>(this, backgroundSource, null, new MapTilesLayer.BitmapTileRenderer());
layer = new MapTilesLayer<Bitmap>(this, backgroundSource, null, new MapTilesLayer.BitmapTileRenderer(hardwareLayerType));
}
}
break;
Expand All @@ -235,7 +238,7 @@ public void setUpLayers(@NonNull Context ctx) {
if (overlaySource.getTileType() == TileType.MVT) {
layer = new de.blau.android.layer.mvt.MapOverlay(this, new VectorTileRenderer(), true);
} else {
layer = new MapTilesOverlayLayer<Bitmap>(this, new MapTilesLayer.BitmapTileRenderer());
layer = new MapTilesOverlayLayer<Bitmap>(this, new MapTilesLayer.BitmapTileRenderer(hardwareLayerType));
}
((MapTilesOverlayLayer<?>) layer).setRendererInfo(overlaySource);
}
Expand Down Expand Up @@ -1302,4 +1305,15 @@ public TrackerService getTracker() {
public boolean rtlLayout() {
return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}

/**
* Check if we configured hardware acceleration
*
* The value returned from isHardwareAccelerated seems to not necessarily be consistent with what we set
*
* @return true if we enabled hardware acceleration
*/
public boolean isHardwareLayerType() {
return hardwareLayerType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ protected Void doInBackground(Void param) {
text.setText(tester.getOutput());
byte[] image = tester.getTile();
if (result && tester.getTileType() == TileType.BITMAP && image != null && image.length > 0) {
BitmapDecoder decoder = new BitmapDecoder();
BitmapDecoder decoder = new BitmapDecoder(false);
Bitmap bitmap = decoder.decode(image, false);
if (bitmap != null) {
tileView.setVisibility(View.VISIBLE);
Expand Down
95 changes: 50 additions & 45 deletions src/main/java/de/blau/android/layer/data/MapOverlay.java
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ protected void onDraw(Canvas canvas, IMapView osmv) {
@SuppressWarnings("unchecked")
private void paintOsmData(@NonNull final Canvas canvas) {

boolean hwAccelarationWorkaround = canvas.isHardwareAccelerated();
boolean hwAccelerated = canvas.isHardwareAccelerated();

int screenWidth = map.getWidth();
int screenHeight = map.getHeight();
Expand Down Expand Up @@ -607,8 +607,7 @@ private void paintOsmData(@NonNull final Canvas canvas) {
coordSize++;
}
}
paintNode(canvas, n, x, y, hwAccelarationWorkaround,
drawTolerance && !noTolerance && (n.getState() != OsmElement.STATE_UNCHANGED || isInDownload(lon, lat)));
paintNode(canvas, n, x, y, hwAccelerated, drawTolerance && !noTolerance && (n.getState() != OsmElement.STATE_UNCHANGED || isInDownload(lon, lat)));
}
// turn restrictions
if (inNodeIconZoomRange && showIcons) {
Expand Down Expand Up @@ -977,10 +976,10 @@ private void paintRestriction(@NonNull final Canvas canvas, int screenWidth, int
* @param node Node to be painted.
* @param x screen x coordinate
* @param y screen y coordinate
* @param hwAccelarationWorkaround use a workaround for unsupported operations when HW acceleration is used
* @param hwAccelerated use a workaround for unsupported operations when HW acceleration is used
* @param drawTolerance draw the touch halo
*/
private void paintNode(@NonNull final Canvas canvas, @NonNull final Node node, final float x, final float y, final boolean hwAccelarationWorkaround,
private void paintNode(@NonNull final Canvas canvas, @NonNull final Node node, final float x, final float y, final boolean hwAccelerated,
final boolean drawTolerance) {

boolean isSelected = tmpDrawingSelectedNodes != null && tmpDrawingSelectedNodes.contains(node);
Expand Down Expand Up @@ -1068,57 +1067,58 @@ private void paintNode(@NonNull final Canvas canvas, @NonNull final Node node, f
isTagged = false;
}

if (isTagged) {
boolean noIcon = true;
if (inNodeIconZoomRange && showIcons) {
Float direction = getDirection(node);
if (direction != null && !direction.equals(Float.NaN)) {
canvas.save();
canvas.rotate(direction + 90, x, y);
canvas.translate(x - iconRadius, y);
canvas.drawPath(currentStyle.getDirectionArrowPath(), nodeFeatureStyle.getPaint());
canvas.restore();
}
if (!isTagged) {
// this bit of code duplication makes sense
if (zoomLevel < featureStyle.getMinVisibleZoom()) {
return;
}
Paint paint = featureStyle.getPaint();
if (hwAccelerated) { // we don't actually know if this is slower than drawPoint
canvas.drawCircle(x, y, paint.getStrokeWidth() / 2, paint);
} else {
canvas.drawPoint(x, y, paint);
}
return;
}

noIcon = tmpPresets == null || !paintNodeIcon(node, canvas, x, y, isSelected || hasProblem ? featureStyleTagged : null);
if (noIcon) {
String houseNumber = node.getTagWithKey(Tags.KEY_ADDR_HOUSENUMBER);
if (houseNumber != null && !"".equals(houseNumber)) { // draw house-numbers
paintHouseNumber(x, y, canvas, featureStyleThin, featureStyleFontSmall, houseNumber);
return;
}
} else if (zoomLevel > showIconLabelZoomLimit) {
paintLabel(x, y, canvas, featureStyleFont, node, nodeFeatureStyleTagged.getPaint().getStrokeWidth(), true);
}
boolean noIcon = true;
if (inNodeIconZoomRange && showIcons) {
Float direction = getDirection(node);
if (direction != null && !direction.equals(Float.NaN)) {
canvas.save();
canvas.rotate(direction + 90, x, y);
canvas.translate(x - iconRadius, y);
canvas.drawPath(currentStyle.getDirectionArrowPath(), nodeFeatureStyle.getPaint());
canvas.restore();
}

noIcon = tmpPresets == null || !paintNodeIcon(node, canvas, x, y, isSelected || hasProblem ? featureStyleTagged : null);
if (noIcon) {
// draw regular nodes or without icons
if (zoomLevel < featureStyleTagged.getMinVisibleZoom()) {
String houseNumber = node.getTagWithKey(Tags.KEY_ADDR_HOUSENUMBER);
if (houseNumber != null && !"".equals(houseNumber)) { // draw house-numbers
paintHouseNumber(x, y, canvas, featureStyleThin, featureStyleFontSmall, houseNumber);
return;
}
Paint paint = featureStyleTagged.getPaint();
float strokeWidth = paint.getStrokeWidth();
if (hwAccelarationWorkaround) {
canvas.drawCircle(x, y, strokeWidth / 2, paint);
} else {
canvas.drawPoint(x, y, paint);
}
if (inNodeIconZoomRange) {
paintLabel(x, y, canvas, featureStyleFont, node, strokeWidth, false);
}
} else if (zoomLevel > showIconLabelZoomLimit) {
paintLabel(x, y, canvas, featureStyleFont, node, nodeFeatureStyleTagged.getPaint().getStrokeWidth(), true);
}
} else {
// this bit of code duplication makes sense
if (zoomLevel < featureStyle.getMinVisibleZoom()) {
}

if (noIcon) {
// draw regular nodes or without icons
if (zoomLevel < featureStyleTagged.getMinVisibleZoom()) {
return;
}
Paint paint = featureStyle.getPaint();
if (hwAccelarationWorkaround) { // FIXME we don't actually know if this is slower than drawPoint
canvas.drawCircle(x, y, paint.getStrokeWidth() / 2, paint);
Paint paint = featureStyleTagged.getPaint();
float strokeWidth = paint.getStrokeWidth();
if (hwAccelerated) {
canvas.drawCircle(x, y, strokeWidth / 2, paint);
} else {
canvas.drawPoint(x, y, paint);
}
if (inNodeIconZoomRange) {
paintLabel(x, y, canvas, featureStyleFont, node, strokeWidth, false);
}
}
}

Expand Down Expand Up @@ -1271,8 +1271,13 @@ private void retrieveIcon(@NonNull OsmElement element, boolean isWay, @NonNull W
}
Bitmap icon;
if (iconDrawable != null) {
icon = Bitmap.createBitmap(iconRadius * 2, iconRadius * 2, Config.ARGB_8888);
icon = Bitmap.createBitmap(iconRadius * 2, iconRadius * 2, Bitmap.Config.ARGB_8888);
iconDrawable.draw(new Canvas(icon));
if (map.isHardwareLayerType()) {
Bitmap temp = icon;
icon = temp.copy(Bitmap.Config.HARDWARE, false);
temp.recycle();
}
} else {
icon = NOICON;
}
Expand Down
14 changes: 9 additions & 5 deletions src/main/java/de/blau/android/layer/tasks/MapOverlay.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.blau.android.layer.tasks;

import static de.blau.android.contract.Constants.LOG_TAG_LEN;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
Expand Down Expand Up @@ -59,7 +61,8 @@
public class MapOverlay extends MapViewLayer
implements ExtentInterface, DiscardInterface, ClickableInterface<Task>, LayerInfoInterface, ConfigureInterface, PruneableInterface {

private static final String DEBUG_TAG = MapOverlay.class.getSimpleName().substring(0, Math.min(23, MapOverlay.class.getSimpleName().length()));
private static final int TAG_LEN = Math.min(LOG_TAG_LEN, MapOverlay.class.getSimpleName().length());
private static final String DEBUG_TAG = MapOverlay.class.getSimpleName().substring(0, TAG_LEN);

public static final String FILENAME = "selectedtask" + "." + FileExtensions.RES;

Expand Down Expand Up @@ -120,10 +123,11 @@ public MapOverlay(@NonNull final Map map) {
setPrefs(prefs);
download = new TaskDownloader(prefs.getServer());
// the following sets up the static icon caches
Note.setupIconCache(context);
OsmoseBug.setupIconCache(context);
MapRouletteTask.setupIconCache(context);
Todo.setupIconCache(context);
boolean hwAccelerated = map.isHardwareLayerType();
Note.setupIconCache(context, hwAccelerated);
OsmoseBug.setupIconCache(context, hwAccelerated);
MapRouletteTask.setupIconCache(context, hwAccelerated);
Todo.setupIconCache(context, hwAccelerated);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.blau.android.prefs;

import static de.blau.android.contract.Constants.LOG_TAG_LEN;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand All @@ -21,7 +23,8 @@

public class AdvancedPrefEditorFragment extends ExtendedPreferenceFragment {

private static final String DEBUG_TAG = AdvancedPrefEditorFragment.class.getSimpleName().substring(0, Math.min(23, AdvancedPrefEditorFragment.class.getSimpleName().length()));
private static final int TAG_LEN = Math.min(LOG_TAG_LEN, AdvancedPrefEditorFragment.class.getSimpleName().length());
private static final String DEBUG_TAG = AdvancedPrefEditorFragment.class.getSimpleName().substring(0, TAG_LEN);

private Resources r;
AdvancedPrefDatabase db;
Expand Down Expand Up @@ -87,6 +90,7 @@ public void onResume() {
setRestartRequiredMessage(R.string.config_autosaveMaxFiles_key);
setRestartRequiredMessage(R.string.config_indexMediaStore_key);
setRestartRequiredMessage(R.string.config_supportPresetLabels_key);
setRestartRequiredMessage(R.string.config_enableHwAcceleration_key);
setTitle();
}

Expand Down
13 changes: 8 additions & 5 deletions src/main/java/de/blau/android/tasks/MapRouletteTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,15 @@ public class MapRouletteTask extends LongIdTask {

/**
* Setup the icon caches
*
* @param context android Context
* @param hwAccelerated true if the Canvas is hw accelerated
*/
public static void setupIconCache(Context context) {
cachedIconRouletteOpen = getIcon(context, R.drawable.roulette_open);
cachedIconRouletteChanged = getIcon(context, R.drawable.roulette_changed);
cachedIconChangedRouletteClosed = getIcon(context, R.drawable.roulette_closed_changed);
cachedIconRouletteClosed = getIcon(context, R.drawable.roulette_closed);
public static void setupIconCache(@NonNull Context context, boolean hwAccelerated) {
cachedIconRouletteOpen = getIcon(context, R.drawable.roulette_open, hwAccelerated);
cachedIconRouletteChanged = getIcon(context, R.drawable.roulette_changed, hwAccelerated);
cachedIconChangedRouletteClosed = getIcon(context, R.drawable.roulette_closed_changed, hwAccelerated);
cachedIconRouletteClosed = getIcon(context, R.drawable.roulette_closed, hwAccelerated);
}

@Override
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/de/blau/android/tasks/Note.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,15 @@ public Note(XmlPullParser parser) throws XmlPullParserException, IOException, Nu

/**
* Setup the icon caches
*
* @param context android Context
* @param hwAccelerated true if the Canvas is hw accelerated
*/
public static void setupIconCache(Context context) {
cachedIconNoteOpen = getIcon(context, R.drawable.note_open);
cachedIconNoteChanged = getIcon(context, R.drawable.note_changed);
cachedIconNoteChangedClosed = getIcon(context, R.drawable.note_changed_closed);
cachedIconNoteClosed = getIcon(context, R.drawable.note_closed);
public static void setupIconCache(@NonNull Context context, boolean hwAccelerated) {
cachedIconNoteOpen = getIcon(context, R.drawable.note_open, hwAccelerated);
cachedIconNoteChanged = getIcon(context, R.drawable.note_changed, hwAccelerated);
cachedIconNoteChangedClosed = getIcon(context, R.drawable.note_changed_closed, hwAccelerated);
cachedIconNoteClosed = getIcon(context, R.drawable.note_closed, hwAccelerated);
}

/**
Expand Down
Loading

0 comments on commit 625a0ea

Please sign in to comment.