void ProduceResultsInternal(IConsumer <T> consumer, IProducerContext producerContext) { IProducerListener producerListener = producerContext.Listener; producerListener.OnProducerFinishWithSuccess(producerContext.Id, PRODUCER_NAME, null); _inputProducer.ProduceResults(new ThrottlerConsumer(this, consumer), producerContext); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext context) { IProducerListener listener = context.Listener; IPostprocessor postprocessor = context.ImageRequest.Postprocessor; PostprocessorConsumer basePostprocessorConsumer = new PostprocessorConsumer(this, consumer, listener, context.Id, postprocessor, context); IConsumer <CloseableReference <CloseableImage> > postprocessorConsumer; if (postprocessor.GetType() == typeof(IRepeatedPostprocessor)) { postprocessorConsumer = new RepeatedPostprocessorConsumer( basePostprocessorConsumer, (IRepeatedPostprocessor)postprocessor, context); } else { postprocessorConsumer = new SingleUsePostprocessorConsumer(basePostprocessorConsumer); } _inputProducer.ProduceResults(postprocessorConsumer, context); }
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; }
public void Initialize() { // Initializes the mock data _producerListener = new ProducerListenerImpl( (_, __) => { }, (_, __, ___) => { }, (_, __, ___) => { }, (_, __, ___, ____) => { }, (_, __, ___) => { }, (_) => { return(false); }); _consumer = new BaseConsumerImpl <object>( (result, isLast) => { ++_consumerOnNewResultCount; _consumerInternalResult = result; _consumerInternalIsLast = isLast; }, (_) => { }, () => { }, (_) => { }); _producerContext = new SettableProducerContext( IMAGE_REQUEST, REQUEST_ID, _producerListener, new object(), RequestLevel.FULL_FETCH, false, true, Priority.MEDIUM); _nullProducer = new NullProducer <object>(); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults(IConsumer <T> consumer, IProducerContext producerContext) { IProducerListener producerListener = producerContext.Listener; producerListener.OnProducerStart(producerContext.Id, PRODUCER_NAME); bool delayRequest; lock (_gate) { if (_numCurrentRequests >= _maxSimultaneousRequests) { _pendingRequests.Enqueue( new Tuple <IConsumer <T>, IProducerContext>(consumer, producerContext)); delayRequest = true; } else { _numCurrentRequests++; delayRequest = false; } } if (!delayRequest) { ProduceResultsInternal(consumer, producerContext); } }
/// <summary> /// Instantiates the <see cref="StatefulProducerRunnableImpl{T}"/>. /// </summary> public StatefulProducerRunnableImpl( IConsumer <T> consumer, IProducerListener producerListener, string producerName, string requestId, Action <T> onSuccessFunc, Action <Exception> onFailureFunc, Action onCancellation, Func <T, IDictionary <string, string> > getExtraMapOnSuccessFunc, Func <Exception, IDictionary <string, string> > getExtraMapOnFailureFunc, Func <IDictionary <string, string> > getExtraMapOnCancellationFunc, Action <T> disposeResultFunc, Func <Task <T> > getResultFunc) : base( consumer, producerListener, producerName, requestId) { _onSuccessFunc = onSuccessFunc; _onFailureFunc = onFailureFunc; _onCancellation = onCancellation; _getExtraMapOnSuccessFunc = getExtraMapOnSuccessFunc; _getExtraMapOnFailureFunc = getExtraMapOnFailureFunc; _getExtraMapOnCancellationFunc = getExtraMapOnCancellationFunc; _disposeResultFunc = disposeResultFunc; _getResultFunc = getResultFunc; }
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; }
public Status ReleaseBuffer(int slot, ulong frameNumber, ref AndroidFence fence) { if (slot < 0 || slot >= Core.Slots.Length) { return(Status.BadValue); } IProducerListener listener = null; lock (Core.Lock) { if (Core.Slots[slot].FrameNumber != frameNumber) { return(Status.StaleBufferSlot); } foreach (BufferItem item in Core.Queue) { if (item.Slot == slot) { return(Status.BadValue); } } if (Core.Slots[slot].BufferState == BufferState.Acquired) { Core.Slots[slot].BufferState = BufferState.Free; Core.Slots[slot].Fence = fence; listener = Core.ProducerListener; } else if (Core.Slots[slot].NeedsCleanupOnRelease) { Core.Slots[slot].NeedsCleanupOnRelease = false; return(Status.StaleBufferSlot); } else { return(Status.BadValue); } Core.Slots[slot].GraphicBuffer.Object.DecrementNvMapHandleRefCount(Core.Owner); Core.CheckSystemEventsLocked(Core.GetMaxBufferCountLocked(true)); Core.SignalDequeueEvent(); } listener?.OnBufferReleased(); return(Status.Success); }
/// <summary> /// Instantiates the <see cref="StatefulProducerRunnable{T}"/>. /// </summary> public StatefulProducerRunnable( IConsumer <T> consumer, IProducerListener producerListener, string producerName, string requestId) { _consumer = consumer; _producerListener = producerListener; _producerName = producerName; _requestId = requestId; _producerListener.OnProducerStart(_requestId, _producerName); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <EncodedImage> consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; StatefulProducerRunnable <EncodedImage> cancellableProducerRunnable = new StatefulProducerRunnableImpl <EncodedImage>( consumer, listener, ProducerName, requestId, null, null, null, null, null, null, (result) => { EncodedImage.CloseSafely(result); }, async() => { EncodedImage encodedImage = await GetEncodedImage(imageRequest) .ConfigureAwait(false); if (encodedImage == null) { return(null); } await encodedImage.ParseMetaDataAsync().ConfigureAwait(false); return(encodedImage); }); producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { cancellableProducerRunnable.Cancel(); }, () => { }, () => { }, () => { })); _executor.Execute(cancellableProducerRunnable.Runnable); }
/// <summary> /// Instantiates the <see cref="ProgressiveDecoder"/>. /// </summary> public ProgressiveDecoder( DecodeProducer parent, IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) : base(consumer) { _parent = parent; _producerContext = producerContext; _producerListener = producerContext.Listener; _imageDecodeOptions = producerContext.ImageRequest.ImageDecodeOptions; _isFinished = false; Func <EncodedImage, bool, Task> job = (encodedImage, isLast) => { if (encodedImage != null) { if (_parent._downsampleEnabled) { ImageRequest request = producerContext.ImageRequest; if (_parent._downsampleEnabledForNetwork || !UriUtil.IsNetworkUri(request.SourceUri)) { encodedImage.SampleSize = DownsampleUtil.DetermineSampleSize( request, encodedImage); } } return(DoDecode(encodedImage, isLast)); } return(Task.CompletedTask); }; _jobScheduler = new JobScheduler( _parent._executor, job, _imageDecodeOptions.MinDecodeIntervalMs); _producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { }, () => { }, () => { if (_producerContext.IsIntermediateResultExpected) { _jobScheduler.ScheduleJob(); } }, () => { })); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults(IConsumer <T> consumer, IProducerContext context) { IProducerListener producerListener = context.Listener; string requestId = context.Id; StatefulProducerRunnable <T> statefulRunnable = new StatefulProducerRunnableImpl <T>( consumer, producerListener, PRODUCER_NAME, requestId, (T ignored) => { producerListener.OnProducerFinishWithSuccess(requestId, PRODUCER_NAME, null); _inputProducer.ProduceResults(consumer, context); }, null, null, (_) => { return(default(IDictionary <string, string>)); }, (_) => { return(default(IDictionary <string, string>)); }, () => { return(default(IDictionary <string, string>)); }, null, () => { return(Task.FromResult(default(T))); }); context.AddCallbacks( new BaseProducerContextCallbacks( () => { statefulRunnable.Cancel(); _threadHandoffProducerQueue.Remove(statefulRunnable.Runnable); }, () => { }, () => { }, () => { })); _threadHandoffProducerQueue.AddToQueueOrExecute(statefulRunnable.Runnable); }
internal static IDictionary <string, string> GetExtraMap( IProducerListener listener, string requestId, bool valueFound) { if (!listener.RequiresExtraMap(requestId)) { return(null); } var extraMap = new Dictionary <string, string>() { { VALUE_FOUND, valueFound.ToString() } }; return(new ReadOnlyDictionary <string, string>(extraMap)); }
private IDictionary <string, string> GetExtraMap( IProducerListener listener, string requestId, IPostprocessor postprocessor) { if (!listener.RequiresExtraMap(requestId)) { return(null); } var extraMap = new Dictionary <string, string>() { { POSTPROCESSOR, postprocessor.Name } }; return(new ReadOnlyDictionary <string, string>(extraMap)); }
public override Status Disconnect(NativeWindowApi api) { IProducerListener producerListener = null; Status status = Status.BadValue; lock (Core.Lock) { Core.WaitWhileAllocatingLocked(); if (Core.IsAbandoned) { return(Status.Success); } switch (api) { case NativeWindowApi.NVN: case NativeWindowApi.CPU: case NativeWindowApi.Media: case NativeWindowApi.Camera: if (Core.ConnectedApi == api) { Core.Queue.Clear(); Core.FreeAllBuffersLocked(); Core.SignalDequeueEvent(); producerListener = Core.ProducerListener; Core.ProducerListener = null; Core.ConnectedApi = NativeWindowApi.NoApi; Core.SignalWaitBufferFreeEvent(); Core.SignalFrameAvailableEvent(); status = Status.Success; } break; } } producerListener?.OnBufferReleased(); return(status); }
public override Status Connect(IProducerListener listener, NativeWindowApi api, bool producerControlledByApp, out QueueBufferOutput output) { output = new QueueBufferOutput(); lock (Core.Lock) { if (Core.IsAbandoned || Core.ConsumerListener == null) { return(Status.NoInit); } if (Core.ConnectedApi != NativeWindowApi.NoApi) { return(Status.BadValue); } Core.BufferHasBeenQueued = false; Core.DequeueBufferCannotBlock = Core.ConsumerControlledByApp && producerControlledByApp; switch (api) { case NativeWindowApi.NVN: case NativeWindowApi.CPU: case NativeWindowApi.Media: case NativeWindowApi.Camera: Core.ProducerListener = listener; Core.ConnectedApi = api; output.Width = (uint)Core.DefaultWidth; output.Height = (uint)Core.DefaultHeight; output.TransformHint = Core.TransformHint; output.NumPendingBuffers = (uint)Core.Queue.Count; if (NxSettings.Settings.TryGetValue("nv!nvn_no_vsync_capability", out object noVSyncCapability) && (bool)noVSyncCapability) { output.TransformHint |= NativeWindowTransform.NoVSyncCapability; } return(Status.Success); default: return(Status.BadValue); } } }
public void Initialize() { // Initializes the mock data _producerListener = new ProducerListenerImpl( (_, __) => { }, (_, __, ___) => { }, (_, __, ___) => { }, (_, __, ___, ____) => { }, (_, __, ___) => { }, (_) => { return(false); }); _consumer = new BaseConsumerImpl <EncodedImage>( (_, __) => { }, (_) => { }, () => { }, (_) => { }); }
/// <summary> /// Instantiates the <see cref="SettableProducerContext"/>. /// </summary> public SettableProducerContext( ImageRequest imageRequest, string id, IProducerListener producerListener, object callerContext, int lowestPermittedRequestLevel, bool isPrefetch, bool isIntermediateResultExpected, int priority) : base( imageRequest, id, producerListener, callerContext, lowestPermittedRequestLevel, isPrefetch, isIntermediateResultExpected, priority) { }
internal PostprocessorConsumer( PostprocessorProducer parent, IConsumer <CloseableReference <CloseableImage> > consumer, IProducerListener listener, string requestId, IPostprocessor postprocessor, IProducerContext producerContext) : base(consumer) { _parent = parent; _listener = listener; _requestId = requestId; _postprocessor = postprocessor; producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { MaybeNotifyOnCancellation(); }, () => { }, () => { }, () => { })); }
/// <summary> /// Instantiates the <see cref="BaseProducerContext"/> /// </summary> public BaseProducerContext( ImageRequest imageRequest, string id, IProducerListener producerListener, object callerContext, int lowestPermittedRequestLevel, bool isPrefetch, bool isIntermediateResultExpected, int priority) { _imageRequest = imageRequest; _id = id; _producerListener = producerListener; _callerContext = callerContext; _lowestPermittedRequestLevel = lowestPermittedRequestLevel; _isPrefetch = isPrefetch; _priority = priority; _isIntermediateResultExpected = isIntermediateResultExpected; _isCancelled = false; _callbacks = new List <IProducerContextCallbacks>(); }
public void OnTransact(uint code, uint flags, Parcel inputParcel, Parcel outputParcel) { Status status = Status.Success; int slot; AndroidFence fence; QueueBufferInput queueInput; QueueBufferOutput queueOutput; NativeWindowApi api; AndroidStrongPointer <GraphicBuffer> graphicBuffer; AndroidStrongPointer <AndroidFence> strongFence; switch ((TransactionCode)code) { case TransactionCode.RequestBuffer: slot = inputParcel.ReadInt32(); status = RequestBuffer(slot, out graphicBuffer); outputParcel.WriteStrongPointer(ref graphicBuffer); outputParcel.WriteStatus(status); break; case TransactionCode.SetBufferCount: int bufferCount = inputParcel.ReadInt32(); status = SetBufferCount(bufferCount); outputParcel.WriteStatus(status); break; case TransactionCode.DequeueBuffer: bool async = inputParcel.ReadBoolean(); uint width = inputParcel.ReadUInt32(); uint height = inputParcel.ReadUInt32(); PixelFormat format = inputParcel.ReadUnmanagedType <PixelFormat>(); uint usage = inputParcel.ReadUInt32(); status = DequeueBuffer(out int dequeueSlot, out fence, async, width, height, format, usage); strongFence = new AndroidStrongPointer <AndroidFence>(fence); outputParcel.WriteInt32(dequeueSlot); outputParcel.WriteStrongPointer(ref strongFence); outputParcel.WriteStatus(status); break; case TransactionCode.DetachBuffer: slot = inputParcel.ReadInt32(); status = DetachBuffer(slot); outputParcel.WriteStatus(status); break; case TransactionCode.DetachNextBuffer: status = DetachNextBuffer(out graphicBuffer, out fence); strongFence = new AndroidStrongPointer <AndroidFence>(fence); outputParcel.WriteStrongPointer(ref graphicBuffer); outputParcel.WriteStrongPointer(ref strongFence); outputParcel.WriteStatus(status); break; case TransactionCode.AttachBuffer: graphicBuffer = inputParcel.ReadStrongPointer <GraphicBuffer>(); status = AttachBuffer(out slot, graphicBuffer); outputParcel.WriteInt32(slot); outputParcel.WriteStatus(status); break; case TransactionCode.QueueBuffer: slot = inputParcel.ReadInt32(); queueInput = inputParcel.ReadFlattenable <QueueBufferInput>(); status = QueueBuffer(slot, ref queueInput, out queueOutput); outputParcel.WriteUnmanagedType(ref queueOutput); outputParcel.WriteStatus(status); break; case TransactionCode.CancelBuffer: slot = inputParcel.ReadInt32(); fence = inputParcel.ReadFlattenable <AndroidFence>(); CancelBuffer(slot, ref fence); outputParcel.WriteStatus(Status.Success); break; case TransactionCode.Query: NativeWindowAttribute what = inputParcel.ReadUnmanagedType <NativeWindowAttribute>(); status = Query(what, out int outValue); outputParcel.WriteInt32(outValue); outputParcel.WriteStatus(status); break; case TransactionCode.Connect: bool hasListener = inputParcel.ReadBoolean(); IProducerListener listener = null; if (hasListener) { throw new NotImplementedException("Connect with a strong binder listener isn't implemented"); } api = inputParcel.ReadUnmanagedType <NativeWindowApi>(); bool producerControlledByApp = inputParcel.ReadBoolean(); status = Connect(listener, api, producerControlledByApp, out queueOutput); outputParcel.WriteUnmanagedType(ref queueOutput); outputParcel.WriteStatus(status); break; case TransactionCode.Disconnect: api = inputParcel.ReadUnmanagedType <NativeWindowApi>(); status = Disconnect(api); outputParcel.WriteStatus(status); break; case TransactionCode.SetPreallocatedBuffer: slot = inputParcel.ReadInt32(); graphicBuffer = inputParcel.ReadStrongPointer <GraphicBuffer>(); status = SetPreallocatedBuffer(slot, graphicBuffer); outputParcel.WriteStatus(status); break; default: throw new NotImplementedException($"Transaction {(TransactionCode)code} not implemented"); } if (status != Status.Success) { Logger.PrintError(LogClass.SurfaceFlinger, $"Error returned by transaction {(TransactionCode)code}: {status}"); } }
public abstract Status Connect(IProducerListener listener, NativeWindowApi api, bool producerControlledByApp, out QueueBufferOutput output);
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <EncodedImage> consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; StatefulProducerRunnable <EncodedImage> cancellableProducerRunnable = new StatefulProducerRunnableImpl <EncodedImage>( consumer, listener, PRODUCER_NAME, requestId, null, null, null, (result) => { IDictionary <string, string> extraMap = new Dictionary <string, string>() { { CREATED_THUMBNAIL, (result != null).ToString() } }; return(new ReadOnlyDictionary <string, string>(extraMap)); }, null, null, (result) => { EncodedImage.CloseSafely(result); }, async() => { Uri sourceUri = imageRequest.SourceUri; StorageFile file = await StorageFile .GetFileFromApplicationUriAsync(sourceUri) .AsTask() .ConfigureAwait(false); using (var fileStream = await file.OpenReadAsync().AsTask().ConfigureAwait(false)) { byte[] bytes = await BitmapUtil .GetThumbnailAsync(fileStream) .ConfigureAwait(false); if (bytes != null) { IPooledByteBuffer pooledByteBuffer = _pooledByteBufferFactory.NewByteBuffer(bytes); return(await BuildEncodedImage(pooledByteBuffer, fileStream) .ConfigureAwait(false)); } else { return(null); } } }); producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { cancellableProducerRunnable.Cancel(); }, () => { }, () => { }, () => { })); _executor.Execute(cancellableProducerRunnable.Runnable); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; listener.OnProducerStart(requestId, ProducerName); ImageRequest imageRequest = producerContext.ImageRequest; object callerContext = producerContext.CallerContext; ICacheKey cacheKey = _cacheKeyFactory.GetBitmapCacheKey(imageRequest, callerContext); IDictionary <string, string> extraMap = default(IDictionary <string, string>); CloseableReference <CloseableImage> cachedReference = _memoryCache.Get(cacheKey); if (cachedReference != null) { bool isFinal = cachedReference.Get().QualityInfo.IsOfFullQuality; if (isFinal) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1f); } consumer.OnNewResult(cachedReference, isFinal); cachedReference.Dispose(); if (isFinal) { return; } } if (producerContext.LowestPermittedRequestLevel >= RequestLevel.BITMAP_MEMORY_CACHE) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnNewResult(null, true); return; } extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; IConsumer <CloseableReference <CloseableImage> > wrappedConsumer = WrapConsumer(consumer, cacheKey); listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(wrappedConsumer, producerContext); }
private void OnFinishDiskReads( Task <EncodedImage> task, IConsumer <EncodedImage> consumer, BufferedDiskCache preferredCache, ICacheKey preferredCacheKey, IProducerContext producerContext) { string requestId = producerContext.Id; IProducerListener listener = producerContext.Listener; if (IsTaskCancelled(task)) { listener.OnProducerFinishWithCancellation(requestId, PRODUCER_NAME, null); consumer.OnCancellation(); } else if (task.IsFaulted) { listener.OnProducerFinishWithFailure(requestId, PRODUCER_NAME, task.Exception, null); MaybeStartInputProducer( consumer, new DiskCacheConsumer( _defaultBufferedDiskCache, _smallImageBufferedDiskCache, _chooseCacheByImageSize, _forceSmallCacheThresholdBytes, consumer, preferredCache, preferredCacheKey), producerContext); } else { EncodedImage cachedReference = task.Result; if (cachedReference != null) { listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, GetExtraMap(listener, requestId, true)); consumer.OnProgressUpdate(1); consumer.OnNewResult(cachedReference, true); cachedReference.Dispose(); } else { listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, GetExtraMap(listener, requestId, false)); MaybeStartInputProducer( consumer, new DiskCacheConsumer( _defaultBufferedDiskCache, _smallImageBufferedDiskCache, _chooseCacheByImageSize, _forceSmallCacheThresholdBytes, consumer, preferredCache, preferredCacheKey), producerContext); } } }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <EncodedImage> consumer, IProducerContext producerContext) { string requestId = producerContext.Id; IProducerListener listener = producerContext.Listener; listener.OnProducerStart(requestId, PRODUCER_NAME); ImageRequest imageRequest = producerContext.ImageRequest; ICacheKey cacheKey = _cacheKeyFactory.GetEncodedCacheKey( imageRequest, producerContext.CallerContext); CloseableReference <IPooledByteBuffer> cachedReference = _memoryCache.Get(cacheKey); IDictionary <string, string> extraMap = default(IDictionary <string, string>); try { if (cachedReference != null) { EncodedImage cachedEncodedImage = new EncodedImage(cachedReference); try { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1f); consumer.OnNewResult(cachedEncodedImage, true); return; } finally { EncodedImage.CloseSafely(cachedEncodedImage); } } if (producerContext.LowestPermittedRequestLevel >= RequestLevel.ENCODED_MEMORY_CACHE) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnNewResult(null, true); return; } IConsumer <EncodedImage> consumerOfInputProducer = new EncodedMemoryCacheConsumer(_memoryCache, consumer, cacheKey); extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(consumerOfInputProducer, producerContext); } finally { CloseableReference <IPooledByteBuffer> .CloseSafely(cachedReference); } }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; object callerContext = producerContext.CallerContext; // If there's no postprocessor or the postprocessor doesn't // require caching, forward results. IPostprocessor postprocessor = imageRequest.Postprocessor; if (postprocessor == null || postprocessor.PostprocessorCacheKey == null) { _inputProducer.ProduceResults(consumer, producerContext); return; } listener.OnProducerStart(requestId, ProducerName); ICacheKey cacheKey = _cacheKeyFactory.GetPostprocessedBitmapCacheKey( imageRequest, callerContext); CloseableReference <CloseableImage> cachedReference = _memoryCache.Get(cacheKey); var extraMap = default(Dictionary <string, string>); if (cachedReference != null) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1.0f); consumer.OnNewResult(cachedReference, true); cachedReference.Dispose(); } else { bool isRepeatedProcessor = postprocessor.GetType() == typeof(IRepeatedPostprocessor); IConsumer <CloseableReference <CloseableImage> > cachedConsumer = new CachedPostprocessorConsumer( consumer, cacheKey, isRepeatedProcessor, _memoryCache); extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(cachedConsumer, producerContext); } }
public void Initialize() { // Initializes mock data _consumer = new BaseConsumerImpl <IDisposable>( (result, isLast) => { ++_consumerOnNewResultCount; _consumerInternalResult = result; _consumerInternalIsLast = isLast; }, (error) => { ++_consumerOnFailureCount; _consumerInternalException = error; }, () => { ++_consumerOnCancellationCount; }, (_) => { }); _producerListener = new ProducerListenerImpl( (requestId, producerName) => { ++_onProducerStartCount; _internalRequestId = requestId; _internalProducerName = producerName; }, (_, __, ___) => { }, (requestId, producerName, extraMap) => { ++_onProducerFinishWithSuccessCount; _internalRequestId = requestId; _internalProducerName = producerName; _internalExtraMap = extraMap; }, (requestId, producerName, error, extraMap) => { ++_onProducerFinishWithFailureCount; _internalRequestId = requestId; _internalProducerName = producerName; _internalException = error; _internalExtraMap = extraMap; }, (requestId, producerName, extraMap) => { ++_onProducerFinishWithCancellationCount; _internalRequestId = requestId; _internalProducerName = producerName; _internalExtraMap = extraMap; }, (_) => { return(_requiresExtraMap); }); _resultSupplier = new SupplierImpl <IDisposable>(() => { if (_throwExceptionInResultSupplierGet) { throw EXCEPTION; } return(RESULT); }); _successMap = new Dictionary <string, string>(); _successMap.Add("state", "success"); _failureMap = new Dictionary <string, string>(); _failureMap.Add("state", "failure"); _cancellationMap = new Dictionary <string, string>(); _cancellationMap.Add("state", "cancelled"); _statefulProducerRunnable = new StatefulProducerRunnableImpl <IDisposable>( _consumer, _producerListener, PRODUCER_NAME, REQUEST_ID, null, null, null, (_) => { return(_successMap); }, (_) => { return(_failureMap); }, () => { return(_cancellationMap); }, (IDisposable result) => { try { result.Dispose(); } catch (Exception e) { throw new Exception("Unexpected IOException", e); } }, () => { return(Task.FromResult(_resultSupplier.Get())); }); _throwExceptionInResultSupplierGet = false; _requiresExtraMap = false; }
public void Initialize() { // Initializes mock data _inputProducer = new ProducerImpl <object>((consumer, producerContext) => { _internalConsumer = consumer; _internalProducerContext = (SettableProducerContext)producerContext; _completion.Set(); }); _consumer = new BaseConsumerImpl <object>( (_, __) => { }, (_) => { }, () => { ++_consumerOnCancellationCount; _completion.Set(); }, (_) => { }); _producerListener = new ProducerListenerImpl( (requestId, producerName) => { ++_onProducerStartCount; _internalRequestId = requestId; _internalProducerName = producerName; }, (_, __, ___) => { ++_onProducerEventCount; }, (requestId, producerName, extraMap) => { ++_onProducerFinishWithSuccessCount; _internalRequestId = requestId; _internalProducerName = producerName; _internalExtraMap = extraMap; }, (_, __, ___, ____) => { ++_onProducerFinishWithFailureCount; _completion.Set(); }, (requestId, producerName, extraMap) => { ++_onProducerFinishWithCancellationCount; _internalRequestId = requestId; _internalProducerName = producerName; _internalExtraMap = extraMap; }, (_) => { ++_requiresExtraMapCount; return(false); }); _producerContext = new SettableProducerContext( IMAGE_REQUEST, REQUEST_ID, _producerListener, new object(), RequestLevel.FULL_FETCH, false, true, Priority.MEDIUM); _testExecutorService = new MockSerialExecutorService(); _threadHandoffProducer = new ThreadHandoffProducer <object>( _inputProducer, new ThreadHandoffProducerQueue(_testExecutorService)); _completion = new ManualResetEvent(false); }
public void Initialize() { _testExecutor = Executors.NewFixedThreadPool(MAX_DEGREE_OF_PARALLELISM); _poolFactory = new PoolFactory(PoolConfig.NewBuilder().Build()); _pooledByteBufferFactory = _poolFactory.PooledByteBufferFactory; _byteArrayPool = _poolFactory.SmallByteArrayPool; _producerListener = new ProducerListenerImpl( (_, __) => { }, (requestId, producerName, eventName) => { if (eventName.Equals(NetworkFetchProducer.INTERMEDIATE_RESULT_PRODUCER_EVENT)) { ++_intermediateResultProducerEventCalls; } }, (_, __, ___) => { ++_onProducerFinishWithSuccessFuncCalls; }, (requestId, producerName, error, extraMap) => { _internalRequestId = requestId; _internalProducerName = producerName; _internalError = error; _internalExtraMap = extraMap; ++_onProducerFinishWithFailureFuncCalls; }, (_, __, ___) => { ++_onProducerFinishWithCancellationFuncCalls; }, (_) => { return(false); }); _consumer = new BaseConsumerImpl <EncodedImage>( (_, isLast) => { ++_onNewResultImplCalls; if (isLast) { _completion.Set(); } }, (_) => { _completion.Set(); }, () => { _completion.Set(); }, (_) => { }); _networkFetchProducer = new NetworkFetchProducer( _pooledByteBufferFactory, _byteArrayPool, _networkFetcher); _completion = new ManualResetEvent(false); }