private void OnMainImageBoundsChanged(Rect bounds) { //Console.WriteLine("mainImagePanel bounds -> {0}", bounds); if (bounds.IsEmpty) { return; } //Debug.WriteLine("OnMainImageBoundsChanged begin"); // Update drawer & invalidate _viewport.SetImageSize((float)bounds.Width, (float)bounds.Height); UpdateDrawerBounds(); InvalidateView(false); // We have invalidated our image // but we should resize avalonia bitmap (for image control) immediately // because avalonia may redraw scene at any time var pixelSize = new PixelSize((int)bounds.Width, (int)bounds.Height); BitmapAdapter.EnsureBitmapSize(ref _mainBitmap.AvaloniaBitmap, pixelSize); _mainImageControl.Source = _mainBitmap.AvaloniaBitmap; // set new bitmap to image control // We also fill new bitmap from last rendered bitmap to avoid "white resize" UpdateMainBitmap(); //Debug.WriteLine("OnMainImageBoundsChanged end"); }
private void RenderThread() { while (true) { _eventRenderDoWork.WaitOne(); //Debug.WriteLine("Render DoWork got"); // get image and bitmap to render TD.Image image; // source vector image int bitmapIndex = -1; // destination raster bitmap index lock (_renderLock) { if (_closingWindow) { return; } image = _mainImage; // choose system bitmap to render for (int i = 0; i < 3; ++i) { if (i != _copyingBitmap && i != _lastRenderedBitmap) { bitmapIndex = i; break; } } } //Debug.WriteLine("Rendering to {0} begin", bitmapIndex); // prepare valid size bitmap TD.Point imageSize = image.GetSize(); SD.Size bitmapSize = new SD.Size((int)imageSize.X, (int)imageSize.Y); BitmapAdapter.EnsureBitmapSize( ref _mainBitmap.SystemBitmaps[bitmapIndex], bitmapSize ); // render image to bitmap /* !!! slow stuff * * Render raster image : 9071899 ticks / count 29 = 312824 // smooth * Render raster image : 12153400 ticks / count 44 = 276213 // TextRenderingHint.SingleBitPerPixel * Render raster image : 6779342 ticks / count 35 = 193695 // no text * Render raster image : 8301237 ticks / count 42 = 197648 // no smooth * Render raster image : 8025534 ticks / count 48 = 167198 // TextRenderingHint.SingleBitPerPixel * Render raster image : 7030453 ticks / count 38 = 185011 // raster font MS serif * Render raster image : 5674569 ticks / count 71 = 79923 // no text * Render raster image : 10144730 ticks / count 30 = 338157 // always Arial 30 * Render raster image : 12752666 ticks / count 39 = 326991 // always Arial 30 - created once * * // read this: https://stackoverflow.com/questions/71374/fastest-api-for-rendering-text-in-windows-forms * // GDI vs. GDI+ Text Rendering Performance https://techcommunity.microsoft.com/t5/windows-blog-archive/gdi-vs-gdi-text-rendering-performance/ba-p/228431 * */ #if USE_PERF _perfRenderImage.Start(); #endif using (var graphics = SD.Graphics.FromImage( _mainBitmap.SystemBitmaps[bitmapIndex] )) { if (_systemSettings.drawerDisableAntialiasing) { graphics.SmoothingMode = SD.Drawing2D.SmoothingMode.None; graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel; } else { graphics.SmoothingMode = SD.Drawing2D.SmoothingMode.AntiAlias; // rendering time *= 1.5 } graphics.Clear(SD.Color.White); // smooting makes ugly edges is no background filled image.Draw(graphics); } #if USE_PERF _perfRenderImage.Stop(); #endif //Debug.WriteLine("Rendering to {0} end", bitmapIndex); // Let UI thread to continue lock (_renderLock) { _lastRenderedBitmap = bitmapIndex; } Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(UpdateMainBitmap); } }