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); }
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); }
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; } }
/// <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); }
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); }
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); } } } }
public static void SetPlatformMemImpl(PlatformMemory p) { platformMem = p; }
public unsafe override void Apply(ColorBgra *dst, ColorBgra *src, int length) { PlatformMemory.Copy(dst, src, (ulong)length * (ulong)ColorBgra.SizeOf); }