source: josm/trunk/test/functional/org/openstreetmap/josm/gui/mappaint/StyleCacheTest.java@ 14138

Last change on this file since 14138 was 14138, checked in by Don-vip, 6 years ago

see #15229 - deprecate Main.platform and related methods - new class PlatformManager

  • Property svn:eol-style set to native
File size: 6.5 KB
RevLine 
[9770]1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import static org.junit.Assert.assertEquals;
5
6import java.awt.Color;
7import java.awt.Graphics2D;
8import java.awt.image.BufferedImage;
9import java.io.File;
10import java.io.InputStream;
[11215]11import java.util.IdentityHashMap;
[9770]12
[11776]13import org.junit.AfterClass;
[11215]14import org.junit.Assert;
[11776]15import org.junit.Before;
[9770]16import org.junit.BeforeClass;
[11776]17import org.junit.Rule;
[9770]18import org.junit.Test;
19import org.openstreetmap.josm.data.Bounds;
20import org.openstreetmap.josm.data.osm.DataSet;
[11215]21import org.openstreetmap.josm.data.osm.OsmPrimitive;
[9770]22import org.openstreetmap.josm.data.osm.visitor.paint.Rendering;
23import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer;
[12636]24import org.openstreetmap.josm.gui.MainApplication;
[11776]25import org.openstreetmap.josm.gui.MapView;
[9770]26import org.openstreetmap.josm.gui.NavigatableComponent;
27import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
28import org.openstreetmap.josm.io.Compression;
29import org.openstreetmap.josm.io.OsmReader;
[11776]30import org.openstreetmap.josm.testutils.JOSMTestRules;
[11215]31import org.openstreetmap.josm.tools.Pair;
[9770]32
[11776]33import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
34
[9770]35/**
36 * Test {@link StyleCache}.
37 */
38public class StyleCacheTest {
39
40 private static final int IMG_WIDTH = 1400;
41 private static final int IMG_HEIGHT = 1050;
42
43 private static Graphics2D g;
44 private static BufferedImage img;
45 private static NavigatableComponent nc;
46 private static DataSet dsCity;
[11215]47 private static DataSet dsCity2;
[9770]48
[11776]49 /**
50 * The test rules used for this test.
51 */
52 @Rule
53 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
[14138]54 public JOSMTestRules test = new JOSMTestRules().preferences().projection().mapStyles().timeout(60000);
[11776]55
56 /**
57 * Load the test data that is required.
[11778]58 * @throws Exception If an error occurred during load.
[11776]59 */
[9770]60 @BeforeClass
61 public static void load() throws Exception {
62 img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_ARGB);
63
64 try (
65 InputStream fisC = Compression.getUncompressedFileInputStream(new File("data_nodist/neubrandenburg.osm.bz2"));
66 ) {
67 dsCity = OsmReader.parseDataSet(fisC, NullProgressMonitor.INSTANCE);
68 }
[11776]69 dsCity2 = new DataSet(dsCity);
[9770]70 }
71
[11215]72 /**
[11776]73 * Free the memory allocated for this test.
74 * <p>
75 * Since we are running junit in non-forked mode, we don't know when this test will not be referenced any more.
76 */
77 @AfterClass
78 public static void unload() {
79 g = null;
80 img = null;
81 nc = null;
82 dsCity = null;
83 dsCity2 = null;
84 }
85
86 /**
87 * Create the temporary graphics
88 */
89 @Before
90 public void loadGraphicComponents() {
91 g = (Graphics2D) img.getGraphics();
92 g.setClip(0, 0, IMG_WIDTH, IMG_WIDTH);
93 g.setColor(Color.BLACK);
94 g.fillRect(0, 0, IMG_WIDTH, IMG_WIDTH);
[12636]95 nc = new MapView(MainApplication.getLayerManager(), null);
[11776]96 nc.setBounds(0, 0, IMG_WIDTH, IMG_HEIGHT);
97 }
98
99 /**
[11215]100 * Verifies, that the intern pool is not growing when repeatedly rendering the
101 * same set of primitives (and clearing the calculated styles each time).
102 *
103 * If it grows, this is an indication that the {@code equals} and {@code hashCode}
104 * implementation is broken and two identical objects are not recognized as equal
105 * or produce different hash codes.
106 *
107 * The opposite problem (different objects are mistaken as equal) has more visible
108 * consequences for the user (wrong rendering on the map) and is not recognized by
109 * this test.
110 */
[9770]111 @Test
[11215]112 public void testStyleCacheInternPool() {
[11818]113 MapPaintStyles.getStyles().clearCached();
[11781]114 StyleCache.clearStyleCachePool();
[9770]115 Bounds bounds = new Bounds(53.56, 13.25, 53.57, 13.26);
116 Rendering visitor = new StyledMapRenderer(g, nc, false);
117 nc.zoomTo(bounds);
118 Integer internPoolSize = null;
119 for (int i = 0; i < 10; i++) {
120 visitor.render(dsCity, true, bounds);
121 MapPaintStyles.getStyles().clearCached();
122 int newInternPoolSize = StyleCache.getInternPoolSize();
123 if (internPoolSize == null) {
124 internPoolSize = newInternPoolSize;
125 } else {
[11805]126 if (internPoolSize != newInternPoolSize) {
127 System.err.println("style sources:");
128 for (StyleSource s : MapPaintStyles.getStyles().getStyleSources()) {
129 System.err.println(s.url + " active:" + s.active);
130 }
131 }
[9770]132 assertEquals("intern pool size", internPoolSize.intValue(), newInternPoolSize);
133 }
134 }
135 }
[11215]136
137 /**
138 * Verifies, that the number of {@code StyleElementList} instances stored
139 * for all the rendered primitives is actually low (as intended).
140 *
141 * Two primitives with the same style should share one {@code StyleElementList}
142 * instance for the cached style elements. This is verified by counting all
143 * the instances using {@code A == B} identity.
144 */
145 @Test
146 public void testStyleCacheInternPool2() {
[11781]147 StyleCache.clearStyleCachePool();
[11215]148 Bounds bounds = new Bounds(53.56, 13.25, 53.57, 13.26);
149 Rendering visitor = new StyledMapRenderer(g, nc, false);
150 nc.zoomTo(bounds);
151 visitor.render(dsCity2, true, bounds);
152
153 IdentityHashMap<StyleElementList, Integer> counter = new IdentityHashMap<>();
154 int noPrimitives = 0;
155 for (OsmPrimitive osm : dsCity2.allPrimitives()) {
156 // primitives, that have been rendered, should have the cache populated
[13636]157 if (osm.getCachedStyle() != null) {
[11215]158 noPrimitives++;
[13636]159 Pair<StyleElementList, Range> p = osm.getCachedStyle().getWithRange(nc.getDist100Pixel(), false);
[11215]160 StyleElementList sel = p.a;
161 Assert.assertNotNull(sel);
162 Integer k = counter.get(sel);
163 if (k == null) {
164 k = 0;
165 }
166 counter.put(sel, k + 1);
167 }
168 }
[11276]169 int EXPECTED_NO_PRIMITIVES = 4294; // needs to be updated if data file or bbox changes
[11215]170 Assert.assertEquals(
171 "The number of rendered primitives should be " + EXPECTED_NO_PRIMITIVES,
172 EXPECTED_NO_PRIMITIVES, noPrimitives);
173 Assert.assertTrue(
174 "Too many StyleElementList instances, they should be shared using the StyleCache",
175 counter.size() < 100);
176 }
[9770]177}
Note: See TracBrowser for help on using the repository browser.