ThinkGeo.com    |     Documentation    |     Premium Support

Icons rendered on GPU are smaller than on CPU

Image markers appear smaller through GPU geometry than through a classic overlay. Both use the same PointStyle with ImageScale = 1.25. Our GPU path rasterizes that style with DrawSample, then displays the sprite through TrackPoint.

The comparison below places CPU left and GPU right.

  using ThinkGeo.Core;
  using ThinkGeo.Gpu;
  using ThinkGeo.UI.Wpf;

  // Run once after map is loaded. Use a small icon, e.g. 32×32.
  var icon = new GeoImage(@"C:\Temp\marker.png");
  var pointStyle = new PointStyle(icon) { ImageScale = 1.25 };

  // CPU: draw the original style.
  var layer = new InMemoryFeatureLayer();
  layer.InternalFeatures.Add(new Feature(-40, 0));
  layer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(pointStyle);
  layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel =
      ApplyUntilZoomLevel.Level20;

  var overlay = new LayerOverlay();
  overlay.Layers.Add(layer);
  map.Overlays.Add(overlay);

  // GPU: rasterize the same style, preserving its pixel dimensions.
  const int spriteSize = 128;
  var sprite = new GeoImage(spriteSize, spriteSize);
  var canvas = GeoCanvas.CreateDefaultGeoCanvas();
  canvas.BeginDrawing(sprite,
      new RectangleShape(-1, 1, 1, -1), GeographyUnit.Meter);
  try { pointStyle.DrawSample(canvas); }
  finally { canvas.EndDrawing(); }

  var geometry = new InMemoryGeometrySource();
  geometry.UpdatePoints(new[]
  {
      new TrackPoint(40, 0, 0, GeoColors.White, spriteSize, "marker")
  });

  var style = new MapStyle();
  style.SetBackground(GeoColors.White);
  style.Images.Add("marker", sprite, pixelRatio: 1);
  style.AddGeometry(geometry);

  map.MapUnit = GeographyUnit.Meter;
  map.Basemap = new GpuBasemap(style);
  map.CurrentExtent = new RectangleShape(-100, 60, 100, -60);
  await map.RefreshAsync();

CPU Render size:

image

GPU Render size:

image

Additionally, sometimes the GPU rendered icons disappear and become artifacts? Checking if we can create a reproducable sample

Hi Julian,

  1. The size difference is a bug, fixed in 15.0.0-beta158. Marker quads are sized in device pixels, and the ratio the geometry channel multiplied by had not been established yet when the marker batch was built — it got 1, and nothing rebuilt the batch afterwards. So the markers stayed in CSS pixels while everything around them drew in device pixels. At 100% the two are the same number; at 150% a marker is 1/1.5 of the classic one. Your screenshots measure 35 against 53 — 0.66, where a 150% display predicts 0.667.

  2. The second is not a bug: a TrackPoint’s size is the whole sprite, not the icon in it. DrawSample draws the style at its own size and centers it, so your 128 px sprite holds a 40 px icon and 88 px of space, and asking for 128 draws all of it. This overload measures the style and gives you a tight sprite, so the size you ask for is the icon’s size:

style.Images.Add("marker", pointStyle);   // no hand-rolled canvas
geometry.UpdatePoints(new[] { new TrackPoint(40, 0, 0, GeoColors.White, 40, "marker") });

Check out bad performance GPU render / lag for the icons-disappear issue.

Thanks,
Ben

1 Like