예제 #1
0
        private static IntPtr Allocate(long bytes, bool allowRetry)
        {
            IntPtr block;

            try
            {
                if (bytes >= largeBlockThreshold)
                {
                    block = PlatformMemory.AllocateLarge((ulong)bytes);
                }
                else
                {
                    block = PlatformMemory.Allocate((ulong)bytes);
                }
            }

            catch (OutOfMemoryException)
            {
                if (allowRetry)
                {
                    PixelUtils.GCFullCollect();
                    return(Allocate(bytes, false));
                }
                else
                {
                    throw;
                }
            }

            return(block);
        }
예제 #2
0
        public byte[] ToByteArray(long startOffset, long lengthDesired)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("MemoryBlock");
            }

            if (startOffset < 0)
            {
                throw new ArgumentOutOfRangeException("startOffset", "must be greater than or equal to zero");
            }

            if (lengthDesired < 0)
            {
                throw new ArgumentOutOfRangeException("length", "must be greater than or equal to zero");
            }

            if (startOffset + lengthDesired > this.length)
            {
                throw new ArgumentOutOfRangeException("startOffset, length", "startOffset + length must be less than Length");
            }

            byte[] dstArray   = new byte[lengthDesired];
            byte * pbSrcArray = (byte *)this.VoidStar;

            fixed(byte *pbDstArray = dstArray)
            {
                PlatformMemory.Copy(pbDstArray, pbSrcArray + startOffset, (ulong)lengthDesired);
            }

            return(dstArray);
        }
예제 #3
0
        private void Dispose(bool disposing)
        {
            if (!disposed)
            {
                disposed = true;

                if (disposing)
                {
                }

                if (this.valid && parentBlock == null)
                {
                    if (this.bitmapHandle != IntPtr.Zero)
                    {
                        PlatformMemory.FreeBitmap(this.bitmapHandle, this.bitmapWidth, this.bitmapHeight);
                    }
                    else if (this.length >= largeBlockThreshold)
                    {
                        PlatformMemory.FreeLarge(new IntPtr(voidStar), (ulong)this.length);
                    }
                    else
                    {
                        PlatformMemory.Free(new IntPtr(voidStar));
                    }
                }

                parentBlock = null;
                voidStar    = null;
                this.valid  = false;
            }
        }
예제 #4
0
        /// <summary>
        /// Copies bytes from one area of memory to another. Since this function works
        /// with MemoryBlock instances, it does bounds checking.
        /// </summary>
        /// <param name="dst">The MemoryBlock to copy bytes to.</param>
        /// <param name="dstOffset">The offset within dst to copy bytes to.</param>
        /// <param name="src">The MemoryBlock to copy bytes from.</param>
        /// <param name="srcOffset">The offset within src to copy bytes from.</param>
        /// <param name="length">The number of bytes to copy.</param>
        public static void CopyBlock(MemoryBlock dst, long dstOffset, MemoryBlock src, long srcOffset, long length)
        {
            if ((dstOffset + length > dst.length) || (srcOffset + length > src.length))
            {
                throw new ArgumentOutOfRangeException("", "copy ranges were out of bounds");
            }

            if (dstOffset < 0)
            {
                throw new ArgumentOutOfRangeException("dstOffset", dstOffset, "must be >= 0");
            }

            if (srcOffset < 0)
            {
                throw new ArgumentOutOfRangeException("srcOffset", srcOffset, "must be >= 0");
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", length, "must be >= 0");
            }

            void *dstPtr = (void *)((byte *)dst.VoidStar + dstOffset);
            void *srcPtr = (void *)((byte *)src.VoidStar + srcOffset);

            PlatformMemory.Copy(dstPtr, srcPtr, (ulong)length);
        }
예제 #5
0
        private static IntPtr Allocate(int width, int height, out IntPtr handle, bool allowRetry)
        {
            IntPtr block;

            try
            {
                block = PlatformMemory.AllocateBitmap(width, height, out handle);
            }

            catch (OutOfMemoryException)
            {
                if (allowRetry)
                {
                    PixelUtils.GCFullCollect();
                    return(Allocate(width, height, out handle, false));
                }
                else
                {
                    throw;
                }
            }

            return(block);
        }
예제 #6
0
        private MemoryBlock(SerializationInfo info, StreamingContext context)
        {
            disposed = false;

            // Try to read a 64-bit value, and for backwards compatibility fall back on a 32-bit value.
            try
            {
                this.length = info.GetInt64("length64");
            }

            catch (SerializationException)
            {
                this.length = (long)info.GetInt32("length");
            }

            try
            {
                this.bitmapWidth  = (int)info.GetInt32("bitmapWidth");
                this.bitmapHeight = (int)info.GetInt32("bitmapHeight");

                if (this.bitmapWidth != 0 || this.bitmapHeight != 0)
                {
                    long bytes = (long)this.bitmapWidth * (long)this.bitmapHeight * (long)ColorBgra.SizeOf;

                    if (bytes != this.length)
                    {
                        throw new ApplicationException("Invalid file format: width * height * 4 != length");
                    }
                }
            }

            catch (SerializationException)
            {
                this.bitmapWidth  = 0;
                this.bitmapHeight = 0;
            }

            bool hasParent = info.GetBoolean("hasParent");

            if (hasParent)
            {
                this.parentBlock = (MemoryBlock)info.GetValue("parentBlock", typeof(MemoryBlock));

                // Try to read a 64-bit value, and for backwards compatibility fall back on a 32-bit value.
                long parentOffset;

                try
                {
                    parentOffset = info.GetInt64("parentOffset64");
                }

                catch (SerializationException)
                {
                    parentOffset = (long)info.GetInt32("parentOffset");
                }

                this.voidStar = (void *)((byte *)parentBlock.VoidStar + parentOffset);
                this.valid    = true;
            }
            else
            {
                DeferredFormatter deferredFormatter = context.Context as DeferredFormatter;
                bool deferred = false;

                // Was this stream serialized with deferment?
                foreach (SerializationEntry entry in info)
                {
                    if (entry.Name == "deferred")
                    {
                        deferred = (bool)entry.Value;
                        break;
                    }
                }

                if (deferred && deferredFormatter != null)
                {
                    // The newest PDN files use deferred deserialization. This lets us read straight from the stream,
                    // minimizing memory use and adding the potential for multithreading
                    // Deserialization will complete in IDeferredDeserializer.FinishDeserialization()
                    // deferredFormatter.AddDeferredObject(this, this.length);

                    throw new StillNotPortedException();
                }
                else if (deferred && deferredFormatter == null)
                {
                    throw new InvalidOperationException("stream has deferred serialization streams, but a DeferredFormatter was not provided");
                }
                else
                {
                    this.voidStar = Allocate(this.length).ToPointer();
                    this.valid    = true;

                    // Non-deferred format serializes one big byte[] chunk. This is also
                    // how PDN files were saved with v2.1 Beta 2 and before.
                    byte[] array = (byte[])info.GetValue("pointerData", typeof(byte[]));

                    fixed(byte *pbArray = array)
                    {
                        PlatformMemory.Copy(this.VoidStar, (void *)pbArray, (ulong)array.LongLength);
                    }
                }
            }
        }
예제 #7
0
 public static void SetPlatformMemImpl(PlatformMemory p)
 {
     platformMem = p;
 }
예제 #8
0
 public unsafe override void Apply(ColorBgra *dst, ColorBgra *src, int length)
 {
     PlatformMemory.Copy(dst, src, (ulong)length * (ulong)ColorBgra.SizeOf);
 }