public void AttachToContainer(CanvasControl result, Panel container, CachedTile tile) { _container = container; if (result != null) { _ctrl = result; } _container?.Dispatcher?.RunAsync(CoreDispatcherPriority.Normal, () => { if (_ctrl == null) { return; } if (_ctrl.Tag is TagContainer tag) { tag.IsAttached = true; tag.Tile = tile; } else { _ctrl.Tag = new TagContainer { IsAttached = true, Tile = tile } }; if (_container?.Children?.Contains(_ctrl) == true) { return; } _container?.Children?.Add(_ctrl); RunWaitingCommands(); }); }
/// <summary> /// Load a tile from the store, and add it to the display container and dictionary /// If no tile is available in the store at this position, we put an empty proxy in place. /// </summary> private void AddToCache(PositionKey key) { if (key == null) { return; } var pos = VisualRectangleNative(key); var tile = new CachedTile(_displayContainer, key, pos.X, pos.Y); // calls down to "Win2dCanvasManager.Employ" tile.SetState(TileState.Locked); lock (_reflowLock) { _tileCache.Add(key, tile); _loadQueue.Enqueue(tile); } }
private bool PrepareTileForDraw([NotNull] PositionKey key, out CachedTile tile) { lock (_reflowLock) { if (!_tileCache.ContainsKey(key)) { var pos = VisualRectangleNative(key); var newTile = new CachedTile(_displayContainer, key, pos.X, pos.Y); // calls down to "Win2dCanvasManager.Employ" newTile.AllocateEmptyImage(); _tileCache.Add(key, newTile); } tile = _tileCache[key]; } if (tile == null) { Logging.WriteLogMessage("Tile cache returned null after being populated!"); return(false); // should never happen } if (tile.State == TileState.Locked) { Logging.WriteLogMessage("Tried to write to a locked tile"); return(false); } var dst = tile.GetTileData(); if (dst == null) { tile.AllocateEmptyImage(); dst = tile.GetTileData(); } if (dst == null) { throw new Exception("Tile data is missing, even after allocation"); } return(true); }
public static CanvasControlAsyncProxy Employ([NotNull] Panel container, [NotNull] CachedTile cachedTile, double x, double y) { // Need a new canvas var proxy = new CanvasControlAsyncProxy(container); var targetTile = cachedTile; container.Dispatcher?.RunAsync(CoreDispatcherPriority.High, () => { var ctrl = new CanvasControl { Margin = new Thickness(0.0), Height = 256, Width = 256, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, UseLayoutRounding = false, RenderTransform = new TranslateTransform { X = x, Y = y } }; proxy.QueueAction(canv => { // We have a single common 'Draw' event hook and use context data to pump in image & state if (canv == null) { return; } canv.Draw += _drawHub.Draw; }); proxy.AttachToContainer(ctrl, container, targetTile); }); return(proxy); }
private void WriteTileToBackingStoreSync(PositionKey key, CachedTile tile) { if (key == null) { return; } if (tile == null) { return; } if (tile.State == TileState.Locked) { return; } var red = RawDataPool.Capture(); var green = RawDataPool.Capture(); var blue = RawDataPool.Capture(); try { var name = key.ToString(); if (tile.ImageIsBlank()) { _tileStore.Delete(name, "img"); tile.SetState(TileState.Empty); } else { var packed = tile.GetTileData(); if (packed == null) { return; } var end = TileImageSize * TileImageSize; for (int i = 0; i < end; i++) { blue[i] = packed[4 * i + 0]; green[i] = packed[4 * i + 1]; red[i] = packed[4 * i + 2]; } using (var ms = new MemoryStream()) { WaveletCompress.Compress(red, green, blue, tile.Width, tile.Height).WriteToStream(ms); ms.Seek(0, SeekOrigin.Begin); var ok = _tileStore.Store(name, "img", ms); if (ok.IsFailure) { throw new Exception("Storage error: DB might be corrupt.", ok.FailureCause); } } } } finally { RawDataPool.Release(red); RawDataPool.Release(green); RawDataPool.Release(blue); } }