Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        private void ReleaseBuffer(TextureCallbackInformation information)
        {
            AndroidFence fence = AndroidFence.NoFence;

            information.Layer.Consumer.ReleaseBuffer(information.Item, ref fence);
        }
Пример #4
0
 public abstract void CancelBuffer(int slot, ref AndroidFence fence);
Пример #5
0
 public abstract Status DetachNextBuffer(out AndroidStrongPointer <GraphicBuffer> graphicBuffer, out AndroidFence fence);
Пример #6
0
 public abstract Status DequeueBuffer(out int slot, out AndroidFence fence, bool async, uint width, uint height, PixelFormat format, uint usage);
Пример #7
0
        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);
        }