Ejemplo n.º 1
0
        private void CreateOrUpdateBitmap(bool isPopup, IntPtr buffer, Rect dirtyRect, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
        {
            bool createNewBitmap = false;

            if (image.Dispatcher.HasShutdownStarted)
            {
                return;
            }

            lock (lockObject)
            {
                int pixels        = width * height;
                int numberOfBytes = pixels * BytesPerPixel;

                createNewBitmap = mappedFile == null || currentSize.Height != height || currentSize.Width != width;

                if (createNewBitmap)
                {
                    ReleaseMemoryMappedView(ref mappedFile, ref viewAccessor);

                    mappedFile = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);

                    viewAccessor = mappedFile.CreateViewAccessor();

                    currentSize.Height = height;
                    currentSize.Width  = width;
                }

                NativeMethodWrapper.CopyMemoryUsingHandle(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, numberOfBytes);
            }

            image.Dispatcher.BeginInvoke((Action)(() =>
            {
                lock (lockObject)
                {
                    if (createNewBitmap)
                    {
                        if (image.Source != null)
                        {
                            image.Source = null;
                            GC.Collect(1);
                        }

                        image.Source = new WriteableBitmap(width, height, DpiX, DpiY, PixelFormat, null);
                    }

                    var backBufferHandle = isPopup ? popupMemoryMappedFile.SafeMemoryMappedFileHandle : viewMemoryMappedFile.SafeMemoryMappedFileHandle;

                    var stride = width * BytesPerPixel;
                    var noOfBytes = stride * height;

                    // Update the dirty region
                    var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
                    var bitmap = (WriteableBitmap)image.Source;
                    bitmap.WritePixels(sourceRect, backBufferHandle.DangerousGetHandle(), noOfBytes, stride, dirtyRect.X, dirtyRect.Y);
                }
            }), DispatcherPriority.Render);
        }