public override Status DetachNextBuffer(out AndroidStrongPointer <GraphicBuffer> graphicBuffer, out AndroidFence fence) { lock (Core.Lock) { Core.WaitWhileAllocatingLocked(); if (Core.IsAbandoned) { graphicBuffer = default; fence = AndroidFence.NoFence; return(Status.NoInit); } int nextBufferSlot = BufferSlotArray.InvalidBufferSlot; for (int slot = 0; slot < Core.Slots.Length; slot++) { if (Core.Slots[slot].BufferState == BufferState.Free && !Core.Slots[slot].GraphicBuffer.IsNull) { if (nextBufferSlot == BufferSlotArray.InvalidBufferSlot || Core.Slots[slot].FrameNumber < Core.Slots[nextBufferSlot].FrameNumber) { nextBufferSlot = slot; } } } if (nextBufferSlot == BufferSlotArray.InvalidBufferSlot) { graphicBuffer = default; fence = AndroidFence.NoFence; return(Status.NoMemory); } graphicBuffer = Core.Slots[nextBufferSlot].GraphicBuffer; fence = Core.Slots[nextBufferSlot].Fence; Core.FreeBufferLocked(nextBufferSlot); return(Status.Success); } }
public override Status DequeueBuffer(out int slot, out AndroidFence fence, bool async, uint width, uint height, PixelFormat format, uint usage) { if ((width == 0 && height != 0) || (height == 0 && width != 0)) { slot = BufferSlotArray.InvalidBufferSlot; fence = AndroidFence.NoFence; return(Status.BadValue); } Status returnFlags = Status.Success; bool attachedByConsumer = false; lock (Core.Lock) { if (format == PixelFormat.Unknown) { format = Core.DefaultBufferFormat; } usage |= Core.ConsumerUsageBits; Status status = WaitForFreeSlotThenRelock(async, out slot, out returnFlags); if (status != Status.Success) { slot = BufferSlotArray.InvalidBufferSlot; fence = AndroidFence.NoFence; return(status); } if (slot == BufferSlotArray.InvalidBufferSlot) { fence = AndroidFence.NoFence; Logger.PrintError(LogClass.SurfaceFlinger, "No available buffer slots"); return(Status.Busy); } attachedByConsumer = Core.Slots[slot].AttachedByConsumer; if (width == 0 || height == 0) { width = (uint)Core.DefaultWidth; height = (uint)Core.DefaultHeight; } Core.Slots[slot].BufferState = BufferState.Dequeued; GraphicBuffer graphicBuffer = Core.Slots[slot].GraphicBuffer.Object; if (Core.Slots[slot].GraphicBuffer.IsNull || graphicBuffer.Width != width || graphicBuffer.Height != height || graphicBuffer.Format != format || (graphicBuffer.Usage & usage) != usage) { if (Core.Slots[slot].GraphicBuffer.IsNull) { slot = BufferSlotArray.InvalidBufferSlot; fence = AndroidFence.NoFence; return(Status.NoMemory); } else { string formattedError = $"Preallocated buffer mismatch - slot {slot}\n" + $"available: Width = {graphicBuffer.Width} Height = {graphicBuffer.Height} Format = {graphicBuffer.Format} Usage = {graphicBuffer.Usage:x} " + $"requested: Width = {width} Height = {height} Format = {format} Usage = {usage:x}"; Logger.PrintError(LogClass.SurfaceFlinger, formattedError); slot = BufferSlotArray.InvalidBufferSlot; fence = AndroidFence.NoFence; return(Status.NoInit); } } fence = Core.Slots[slot].Fence; Core.Slots[slot].Fence = AndroidFence.NoFence; Core.CheckSystemEventsLocked(Core.GetMaxBufferCountLocked(async)); } if (attachedByConsumer) { returnFlags |= Status.BufferNeedsReallocation; } return(returnFlags); }
private void ReleaseBuffer(TextureCallbackInformation information) { AndroidFence fence = AndroidFence.NoFence; information.Layer.Consumer.ReleaseBuffer(information.Item, ref fence); }
public abstract void CancelBuffer(int slot, ref AndroidFence fence);
public abstract Status DetachNextBuffer(out AndroidStrongPointer <GraphicBuffer> graphicBuffer, out AndroidFence fence);
public abstract Status DequeueBuffer(out int slot, out AndroidFence fence, bool async, uint width, uint height, PixelFormat format, uint usage);
protected virtual Status AddReleaseFenceLocked(int slot, ref AndroidStrongPointer <GraphicBuffer> graphicBuffer, ref AndroidFence fence) { if (!StillTracking(slot, ref graphicBuffer)) { return(Status.Success); } Slots[slot].Fence = fence; return(Status.Success); }