Beispiel #1
0
        public BufferQueueCore(Switch device, KProcess process)
        {
            Slots                    = new BufferSlotArray();
            IsAbandoned              = false;
            OverrideMaxBufferCount   = 0;
            DequeueEvent             = new AutoResetEvent(false);
            DequeueBufferCannotBlock = false;
            UseAsyncBuffer           = false;
            DefaultWidth             = 1;
            DefaultHeight            = 1;
            DefaultMaxBufferCount    = 2;
            MaxAcquiredBufferCount   = 1;
            FrameCounter             = 0;
            TransformHint            = 0;
            DefaultBufferFormat      = PixelFormat.Rgba8888;
            IsAllocating             = false;
            IsAllocatingEvent        = new AutoResetEvent(false);
            ProducerListener         = null;
            ConsumerListener         = null;
            ConsumerUsageBits        = 0;

            Queue = new List <BufferItem>();

            // TODO: CreateGraphicBufferAlloc?

            _waitBufferFreeEvent  = new KEvent(device.System);
            _frameAvailaibleEvent = new KEvent(device.System);

            Owner = process;
        }
Beispiel #2
0
        public BufferQueueCore(Switch device, KProcess process)
        {
            Slots                    = new BufferSlotArray();
            IsAbandoned              = false;
            OverrideMaxBufferCount   = 0;
            DequeueBufferCannotBlock = false;
            UseAsyncBuffer           = true;
            DefaultWidth             = 1;
            DefaultHeight            = 1;
            DefaultMaxBufferCount    = 2;
            MaxAcquiredBufferCount   = 1;
            FrameCounter             = 0;
            TransformHint            = 0;
            DefaultBufferFormat      = PixelFormat.Rgba8888;
            IsAllocating             = false;
            ProducerListener         = null;
            ConsumerListener         = null;
            ConsumerUsageBits        = 0;

            Queue = new List <BufferItem>();

            // TODO: CreateGraphicBufferAlloc?

            _waitBufferFreeEvent = new KEvent(device.System.KernelContext);
            _frameAvailableEvent = new KEvent(device.System.KernelContext);

            Owner = process;

            BufferHistory        = new BufferInfo[BufferHistoryArraySize];
            EnableExternalEvent  = true;
            MaxBufferCountCached = 0;
        }
Beispiel #3
0
        public BufferItemConsumer(Switch device,
                                  BufferQueueConsumer consumer,
                                  uint consumerUsage,
                                  int bufferCount,
                                  bool controlledByApp,
                                  IConsumerListener listener = null) : base(consumer, controlledByApp, listener)
        {
            _gpuContext = device.Gpu;

            Status status = Consumer.SetConsumerUsageBits(consumerUsage);

            if (status != Status.Success)
            {
                throw new InvalidOperationException();
            }

            if (bufferCount != -1)
            {
                status = Consumer.SetMaxAcquiredBufferCount(bufferCount);

                if (status != Status.Success)
                {
                    throw new InvalidOperationException();
                }
            }
        }
Beispiel #4
0
        public ConsumptionShapesClearedReason(IStateTransitioner controller,
                                              IConsumerListener consumed, FSMStateID goToState)
            : base(FSMTransistion.AllConsumableShapesConsumed, goToState, controller)
        {
            m_Consumed = consumed;

            m_MarkCompleteJob = CM_Job.Make(MarkShouldTransition()).Repeatable();
        }
Beispiel #5
0
 public PlayerOffScreenWithShapesRemainingReason(FSMTransistion identifier, IStateTransitioner controller,
                                                 IConsumerListener consumed, bool shapesRemaining, FSMStateID goToState)
     : base(identifier, goToState, controller)
 {
     m_Consumed = consumed;
     m_ShouldShapesBeRemaining = shapesRemaining;
     m_StatusListener          = new PlayerStatusChangeListener();
 }
Beispiel #6
0
        public override Status SetBufferCount(int bufferCount)
        {
            IConsumerListener listener = null;

            lock (Core.Lock)
            {
                if (Core.IsAbandoned)
                {
                    return(Status.NoInit);
                }

                if (bufferCount > BufferSlotArray.NumBufferSlots)
                {
                    return(Status.BadValue);
                }

                for (int slot = 0; slot < Core.Slots.Length; slot++)
                {
                    if (Core.Slots[slot].BufferState == BufferState.Dequeued)
                    {
                        return(Status.BadValue);
                    }
                }

                if (bufferCount == 0)
                {
                    Core.OverrideMaxBufferCount = 0;
                    Core.SignalDequeueEvent();

                    return(Status.Success);
                }

                int minBufferSlots = Core.GetMinMaxBufferCountLocked(false);

                if (bufferCount < minBufferSlots)
                {
                    return(Status.BadValue);
                }

                Core.Queue.Clear();
                Core.FreeAllBuffersLocked();
                Core.OverrideMaxBufferCount = bufferCount;
                Core.SignalDequeueEvent();
                Core.SignalWaitBufferFreeEvent();

                listener = Core.ConsumerListener;
            }

            listener?.OnBuffersReleased();

            return(Status.Success);
        }
Beispiel #7
0
        public ConsumerBase(BufferQueueConsumer consumer, bool controlledByApp, IConsumerListener listener)
        {
            for (int i = 0; i < Slots.Length; i++)
            {
                Slots[i] = new Slot();
            }

            IsAbandoned = false;
            Consumer    = consumer;
            _listener   = listener;

            Status connectStatus = consumer.Connect(this, controlledByApp);

            if (connectStatus != Status.Success)
            {
                throw new InvalidOperationException();
            }
        }
Beispiel #8
0
        public Status Connect(IConsumerListener consumerListener, bool controlledByApp)
        {
            if (consumerListener == null)
            {
                return(Status.BadValue);
            }

            lock (Core.Lock)
            {
                if (Core.IsAbandoned)
                {
                    return(Status.NoInit);
                }

                Core.ConsumerListener        = consumerListener;
                Core.ConsumerControlledByApp = controlledByApp;
            }

            return(Status.Success);
        }
Beispiel #9
0
        public override Status QueueBuffer(int slot, ref QueueBufferInput input, out QueueBufferOutput output)
        {
            output = default;

            switch (input.ScalingMode)
            {
            case NativeWindowScalingMode.Freeze:
            case NativeWindowScalingMode.ScaleToWindow:
            case NativeWindowScalingMode.ScaleCrop:
            case NativeWindowScalingMode.Unknown:
            case NativeWindowScalingMode.NoScaleCrop:
                break;

            default:
                return(Status.BadValue);
            }

            BufferItem item = new BufferItem();

            IConsumerListener frameAvailableListener = null;
            IConsumerListener frameReplaceListener   = null;

            lock (Core.Lock)
            {
                if (Core.IsAbandoned)
                {
                    return(Status.NoInit);
                }

                int maxBufferCount = Core.GetMaxBufferCountLocked(input.Async != 0);

                if (input.Async != 0 && Core.OverrideMaxBufferCount != 0 && Core.OverrideMaxBufferCount < maxBufferCount)
                {
                    return(Status.BadValue);
                }

                if (slot < 0 || slot >= Core.Slots.Length || !Core.IsOwnedByProducerLocked(slot))
                {
                    return(Status.BadValue);
                }

                if (!Core.Slots[slot].RequestBufferCalled)
                {
                    Logger.PrintError(LogClass.SurfaceFlinger, $"Slot {slot} was queued without requesting a buffer");

                    return(Status.BadValue);
                }

                input.Crop.Intersect(Core.Slots[slot].GraphicBuffer.Object.ToRect(), out Rect croppedRect);

                if (croppedRect != input.Crop)
                {
                    return(Status.BadValue);
                }

                Core.Slots[slot].Fence       = input.Fence;
                Core.Slots[slot].BufferState = BufferState.Queued;
                Core.FrameCounter++;
                Core.Slots[slot].FrameNumber      = Core.FrameCounter;
                Core.Slots[slot].QueueTime        = TimeSpanType.FromTimeSpan(ARMeilleure.State.ExecutionContext.ElapsedTime);
                Core.Slots[slot].PresentationTime = TimeSpanType.Zero;

                item.AcquireCalled             = Core.Slots[slot].AcquireCalled;
                item.Crop                      = input.Crop;
                item.Transform                 = input.Transform;
                item.TransformToDisplayInverse = (input.Transform & NativeWindowTransform.InverseDisplay) == NativeWindowTransform.InverseDisplay;
                item.ScalingMode               = input.ScalingMode;
                item.Timestamp                 = input.Timestamp;
                item.IsAutoTimestamp           = input.IsAutoTimestamp != 0;
                item.SwapInterval              = input.SwapInterval;
                item.FrameNumber               = Core.FrameCounter;
                item.Slot                      = slot;
                item.Fence                     = input.Fence;
                item.IsDroppable               = Core.DequeueBufferCannotBlock || input.Async != 0;

                item.GraphicBuffer.Set(Core.Slots[slot].GraphicBuffer);
                item.GraphicBuffer.Object.IncrementNvMapHandleRefCount(Core.Owner);

                Core.BufferHistoryPosition = (Core.BufferHistoryPosition + 1) % BufferQueueCore.BufferHistoryArraySize;

                Core.BufferHistory[Core.BufferHistoryPosition] = new BufferInfo
                {
                    FrameNumber = Core.FrameCounter,
                    QueueTime   = Core.Slots[slot].QueueTime,
                    State       = BufferState.Queued
                };

                _stickyTransform = input.StickyTransform;

                if (Core.Queue.Count == 0)
                {
                    Core.Queue.Add(item);

                    frameAvailableListener = Core.ConsumerListener;
                }
                else
                {
                    BufferItem frontItem = Core.Queue[0];

                    if (frontItem.IsDroppable)
                    {
                        if (Core.StillTracking(ref frontItem))
                        {
                            Core.Slots[slot].BufferState = BufferState.Free;
                            Core.Slots[slot].FrameNumber = 0;
                        }

                        Core.Queue.RemoveAt(0);
                        Core.Queue.Insert(0, item);

                        frameReplaceListener = Core.ConsumerListener;
                    }
                    else
                    {
                        Core.Queue.Add(item);

                        frameAvailableListener = Core.ConsumerListener;
                    }
                }

                Core.BufferHasBeenQueued = true;
                Core.SignalDequeueEvent();

                Core.CheckSystemEventsLocked(maxBufferCount);

                output = new QueueBufferOutput
                {
                    Width             = (uint)Core.DefaultWidth,
                    Height            = (uint)Core.DefaultHeight,
                    TransformHint     = Core.TransformHint,
                    NumPendingBuffers = (uint)Core.Queue.Count
                };

                _callbackTicket = _nextCallbackTicket++;
            }

            lock (_callbackLock)
            {
                while (_callbackTicket != _currentCallbackTicket)
                {
                    Monitor.Wait(_callbackLock);
                }

                frameAvailableListener?.OnFrameAvailable(ref item);
                frameReplaceListener?.OnFrameReplaced(ref item);

                _currentCallbackTicket++;

                Monitor.PulseAll(_callbackLock);
            }

            return(Status.Success);
        }
Beispiel #10
0
        public override Status SetBufferCount(int bufferCount)
        {
            IConsumerListener listener = null;

            lock (Core.Lock)
            {
                if (Core.IsAbandoned)
                {
                    return(Status.NoInit);
                }

                if (bufferCount > BufferSlotArray.NumBufferSlots)
                {
                    return(Status.BadValue);
                }

                for (int slot = 0; slot < Core.Slots.Length; slot++)
                {
                    if (Core.Slots[slot].BufferState == BufferState.Dequeued)
                    {
                        return(Status.BadValue);
                    }
                }

                if (bufferCount == 0)
                {
                    Core.OverrideMaxBufferCount = 0;
                    Core.SignalDequeueEvent();

                    return(Status.Success);
                }

                int minBufferSlots = Core.GetMinMaxBufferCountLocked(false);

                if (bufferCount < minBufferSlots)
                {
                    return(Status.BadValue);
                }

                int preallocatedBufferCount = GetPreallocatedBufferCountLocked();

                if (preallocatedBufferCount <= 0)
                {
                    Core.Queue.Clear();
                    Core.FreeAllBuffersLocked();
                }
                else if (preallocatedBufferCount < bufferCount)
                {
                    Logger.Error?.Print(LogClass.SurfaceFlinger, "Not enough buffers. Try with more pre-allocated buffers");

                    return(Status.Success);
                }

                Core.OverrideMaxBufferCount = bufferCount;

                Core.SignalDequeueEvent();
                Core.SignalWaitBufferFreeEvent();

                listener = Core.ConsumerListener;
            }

            listener?.OnBuffersReleased();

            return(Status.Success);
        }
Beispiel #11
0
 public ShowConsumedShapesAction(IConsumerListener consumables)
 {
     m_Consumables   = consumables;
     m_ShowShapesJob = CM_Job.Make(ShowShapes()).Repeatable();
 }