Ejemplo n.º 1
0
        private unsafe void RenderTileWorkItem(PointInt32 tileOffset)
        {
            IBitmap <ColorPbgra32> bitmap;
            bool      isCancelled = false;
            bool      flag        = false;
            Exception error       = null;

            isCancelled |= this.IsTileRenderingCancelled(tileOffset);
            if (isCancelled)
            {
                bitmap = null;
            }
            else
            {
                RectInt32 tileSourceRect = this.tileMathHelper.GetTileSourceRect(tileOffset);
                SizeInt32 tileBufferSize = this.GetTileBufferSize(tileOffset);
                bitmap = RetryManager.Eval <IBitmap <ColorPbgra32> >(3, () => BitmapAllocator.Pbgra32.Allocate(tileBufferSize, AllocationOptions.Default), delegate(Exception _) {
                    CleanupManager.RequestCleanup();
                    Thread.Sleep(200);
                    CleanupManager.WaitForPendingCleanup();
                }, delegate(AggregateException ex) {
                    throw new AggregateException($"could not allocate a bitmap of size {tileBufferSize.Width} x {tileBufferSize.Height}", ex).Flatten();
                });
                if (this.source != null)
                {
                    try
                    {
                        isCancelled |= this.IsTileRenderingCancelled(tileOffset);
                        if (!isCancelled)
                        {
                            using (IBitmapLock <ColorPbgra32> @lock = bitmap.Lock <ColorPbgra32>(BitmapLockOptions.ReadWrite))
                            {
                                if (this.mipLevel == 0)
                                {
                                    this.source.CopyPixels(new RectInt32?(tileSourceRect), @lock);
                                    RenderingKernels.ConvertBgra32ToPbgra32((uint *)@lock.Scan0, tileBufferSize.Width, tileBufferSize.Height, @lock.Stride);
                                    flag = true;
                                }
                                else
                                {
                                    BitmapInterpolationMode linear;
                                    if (!this.isHighQuality)
                                    {
                                        linear = BitmapInterpolationMode.Linear;
                                    }
                                    else if (this.mipLevel == 1)
                                    {
                                        linear = BitmapInterpolationMode.Linear;
                                    }
                                    else
                                    {
                                        linear = BitmapInterpolationMode.Fant;
                                    }
                                    IImagingFactory    instance    = ImagingFactory.Instance;
                                    ICancellationToken cancelToken = CancellationTokenUtil.Create((Func <bool>)(() => (isCancelled | this.IsTileRenderingCancelled(tileOffset))));
                                    int copyHeightLog2             = Math.Max(3, 7 - this.mipLevel);
                                    using (ClippedBitmapSource <ColorBgra32> source2 = new ClippedBitmapSource <ColorBgra32>(this.source, tileSourceRect))
                                    {
                                        using (CancellableBitmapSource <ColorBgra32> source3 = new CancellableBitmapSource <ColorBgra32>(source2, r => this.tileMathHelper.EnumerateTilesClippedToSourceRect(r), null, cancelToken))
                                        {
                                            using (IBitmapSource <ColorPbgra32> source4 = CreateBufferedTileScaler(instance, source3, tileBufferSize.Width, tileBufferSize.Height, linear))
                                            {
                                                using (CancellableBitmapSource <ColorPbgra32> source5 = new CancellableBitmapSource <ColorPbgra32>(source4, r => TileRectSplitter(r, ((int)1) << copyHeightLog2), null, cancelToken))
                                                {
                                                    try
                                                    {
                                                        source5.CopyPixels <ColorPbgra32>(@lock);
                                                        flag = true;
                                                    }
                                                    catch (OperationCanceledException exception2)
                                                    {
                                                        error       = exception2;
                                                        isCancelled = true;
                                                    }
                                                    catch (Exception exception3)
                                                    {
                                                        error = exception3;
                                                        throw;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                isCancelled |= this.IsTileRenderingCancelled(tileOffset);
                                if (isCancelled)
                                {
                                    flag = false;
                                }
                            }
                            if (!flag)
                            {
                                DisposableUtil.Free <IBitmap <ColorPbgra32> >(ref bitmap);
                            }
                        }
                    }
                    catch (OperationCanceledException exception4)
                    {
                        error       = exception4;
                        isCancelled = true;
                    }
                    catch (Exception exception5)
                    {
                        error        = exception5;
                        isCancelled |= this.IsTileRenderingCancelled(tileOffset);
                        if (!isCancelled)
                        {
                            using (IDrawingContext context = DrawingContext.FromBitmap(bitmap, FactorySource.PerThread))
                            {
                                context.Clear(new ColorRgba128Float?((ColorRgba128Float)Colors.White));
                                string text = exception5.ToString();
                                using (ISystemFonts fonts = new SystemFonts(true))
                                {
                                    TextLayout textLayout = UIText.CreateLayout(context, text, fonts.Caption, null, HotkeyRenderMode.Ignore, (double)bitmap.Size.Width, 65535.0);
                                    textLayout.FontSize    *= 0.6;
                                    textLayout.WordWrapping = WordWrapping.Wrap;
                                    context.DrawTextLayout(PointDouble.Zero, textLayout, SolidColorBrushCache.Get((ColorRgba128Float)Colors.Black), DrawTextOptions.None);
                                }
                            }
                            flag = true;
                        }
                    }
                }
            }
            isCancelled |= this.IsTileRenderingCancelled(tileOffset);
            if (isCancelled)
            {
                DisposableUtil.Free <IBitmap <ColorPbgra32> >(ref bitmap);
            }
            RenderedTileInfo info = new RenderedTileInfo(bitmap, !isCancelled && (bitmap > null), error);

            if (!this.tilesRenderedQueue.TryEnqueue(tileOffset, info))
            {
                ExceptionUtil.ThrowInternalErrorException("Could not enqueue to this.tilesRenderedQueue");
            }
            if (Interlocked.Exchange(ref this.isProcessTileRenderedQueueQueued, 1) == 0)
            {
                this.syncContext.Post(this.processTileRenderedQueueCallback);
            }
        }
Ejemplo n.º 2
0
 public bool ProcessTileRenderedQueue()
 {
     base.VerifyAccess();
     using (this.processTileRenderedQueueRegion.UseEnterScope())
     {
         if (this.IsDisposed)
         {
             bool flag = false;
             do
             {
                 KeyValuePair <PointInt32, RenderedTileInfo> pair;
                 while (this.tilesRenderedQueue.TryDequeue(out pair))
                 {
                     DisposableUtil.Free <IBitmap <ColorPbgra32> >(ref pair.Value.Buffer);
                     flag = true;
                 }
             }while (Interlocked.Exchange(ref this.isProcessTileRenderedQueueQueued, 0) == 1);
             return(flag);
         }
         if (Interlocked.Exchange(ref this.isProcessTileRenderedQueueQueued, 0) == 0)
         {
             return(false);
         }
         List <PointInt32> collection           = new List <PointInt32>();
         List <PointInt32> cancelledTileOffsets = null;
         bool flag3 = false;
         int  count = this.tilesRenderedQueue.Count;
         for (int i = 0; i < count; i++)
         {
             KeyValuePair <PointInt32, RenderedTileInfo> pair2;
             if (this.tilesRenderedQueue.TryDequeue(out pair2))
             {
                 PointInt32             key    = pair2.Key;
                 RenderedTileInfo       info2  = pair2.Value;
                 IBitmap <ColorPbgra32> buffer = info2.Buffer;
                 if (this.tilesRenderingCancelledSet.Remove(key) || !info2.Completed)
                 {
                     DisposableUtil.Free <IBitmap <ColorPbgra32> >(ref buffer);
                     if (this.tilesRenderQueue.Contains(key))
                     {
                         flag3 = true;
                     }
                     else if (info2.Error is OperationCanceledException)
                     {
                         if (cancelledTileOffsets == null)
                         {
                             cancelledTileOffsets = new List <PointInt32>();
                         }
                         cancelledTileOffsets.Add(key);
                     }
                 }
                 else
                 {
                     if ((buffer.IsNullReference <IBitmap <ColorPbgra32> >() || buffer.IsDisposed) || !pair2.Value.Completed)
                     {
                         throw new PaintDotNet.InternalErrorException();
                     }
                     IBitmap <ColorPbgra32> disposeMe = this.tileBuffers[key.Y][key.X];
                     DisposableUtil.Free <IBitmap <ColorPbgra32> >(ref disposeMe);
                     this.tileBuffers[key.Y][key.X] = buffer;
                     this.tileIsValid[key.Y][key.X] = true;
                     collection.Add(key);
                 }
                 if (!this.tilesRenderingSet.Remove(key))
                 {
                     throw new PaintDotNet.InternalErrorException();
                 }
             }
         }
         if (collection.Any <PointInt32>())
         {
             this.owner.NotifyTileCacheFinishedRendering <List <PointInt32> >(this, collection);
         }
         if (flag3)
         {
             this.ProcessTileRenderQueue();
         }
         if (!this.tilesRenderingSet.Any <PointInt32>())
         {
             this.owner.NotifyTileCacheIsIdle(this);
         }
         if (cancelledTileOffsets != null)
         {
             this.syncContext.Post(delegate(object _) {
                 this.InvalidateCancelledTiles(cancelledTileOffsets);
             });
         }
         return(collection.Any <PointInt32>());
     }
 }