Files
MicrosoftIris/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs
T

290 lines
8.1 KiB
C#
Raw Normal View History

2022-03-03 08:40:19 -06:00
// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.Render.Extensions.ImageCacheItem
// Assembly: UIX.RenderApi, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: D47658B8-A8EA-43D6-8837-ECE823BFFFC1
// Assembly location: C:\Program Files\Zune\UIX.RenderApi.dll
using System;
using System.Collections;
namespace Microsoft.Iris.Render.Extensions
{
public class ImageCacheItem : IDisposable
{
private static TimeSpan s_tsUpdateThreshhold = new TimeSpan(0, 0, 2);
private bool m_fObjectDisposed;
protected ImageRequirements m_req;
protected Size m_size;
protected BitmapInformation m_info;
protected IntPtr m_buffer;
protected uint m_length;
private int m_countLoadsInProgress;
private bool m_fFullLoadRequested;
private ArrayList m_prevLoadInfos;
private DateTime m_dtLastUsed;
public ImageCacheItem(
IRenderSession renderSession,
string identifier,
IntPtr buffer,
uint length,
Size maxSize,
bool flippable,
bool antialiasEdges)
: this(renderSession, identifier, maxSize, flippable, antialiasEdges)
{
2026-07-26 17:50:43 -05:00
m_buffer = buffer;
m_length = length;
2022-03-03 08:40:19 -06:00
}
public ImageCacheItem(
IRenderSession renderSession,
string identifier,
Size maxSize,
bool flippable,
bool antialiasEdges)
: this(renderSession, identifier)
{
2026-07-26 17:50:43 -05:00
m_req = new ImageRequirements();
m_req.MaximumSize = maxSize;
m_req.Flippable = flippable;
m_req.AntialiasEdges = antialiasEdges;
2022-03-03 08:40:19 -06:00
}
protected ImageCacheItem(IRenderSession renderSession, string identifier)
{
2026-07-26 17:50:43 -05:00
Identifier = identifier;
RenderImage = renderSession.CreateImage(this, Identifier, ReloadImage);
UpdateLastUsedTime();
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
~ImageCacheItem() => Dispose(false);
2022-03-03 08:40:19 -06:00
public void Dispose()
{
2026-07-26 17:50:43 -05:00
Dispose(true);
2022-03-03 08:40:19 -06:00
GC.SuppressFinalize(this);
}
private void Dispose(bool fInDispose)
{
if (!fInDispose)
return;
2026-07-26 17:50:43 -05:00
OnDispose();
2022-03-03 08:40:19 -06:00
}
protected virtual void OnDispose()
{
2026-07-26 17:50:43 -05:00
if (RenderImage != null)
2022-03-03 08:40:19 -06:00
{
2026-07-26 17:50:43 -05:00
RenderImage.UnregisterUsage(this);
RenderImage = null;
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
if (m_info != null)
2022-03-03 08:40:19 -06:00
{
2026-07-26 17:50:43 -05:00
m_info.Dispose();
m_info = null;
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
m_fObjectDisposed = true;
2022-03-03 08:40:19 -06:00
}
public virtual void ReleaseImage()
{
2026-07-26 17:50:43 -05:00
if (RenderImage == null)
2022-03-03 08:40:19 -06:00
return;
2026-07-26 17:50:43 -05:00
RenderImage.UnregisterUsage(this);
RenderImage = null;
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
public int UsageCount { get; private set; }
2022-03-03 08:40:19 -06:00
public void RegisterUsage(object user)
{
2026-07-26 17:50:43 -05:00
AssertValidState();
++UsageCount;
UpdateLastUsedTime();
2022-03-03 08:40:19 -06:00
}
public void UnregisterUsage(object user)
{
2026-07-26 17:50:43 -05:00
AssertValidState();
--UsageCount;
UpdateLastUsedTime();
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
public string Identifier { get; }
2022-03-03 08:40:19 -06:00
2026-07-26 17:50:43 -05:00
public IImage RenderImage { get; private set; }
2022-03-03 08:40:19 -06:00
public Size ImageSize
{
get
{
2026-07-26 17:50:43 -05:00
if (m_size.IsZero)
LoadBuffer();
return m_size;
2022-03-03 08:40:19 -06:00
}
}
2026-07-26 17:50:43 -05:00
public bool HasLoadsInProgress => m_countLoadsInProgress > 0;
2022-03-03 08:40:19 -06:00
2026-07-26 17:50:43 -05:00
public bool InUse => RenderImage != null && RenderImage.UsageCount > 1 || UsageCount > 0;
2022-03-03 08:40:19 -06:00
public virtual void RemoveData()
{
2026-07-26 17:50:43 -05:00
if (HasLoadsInProgress)
2022-03-03 08:40:19 -06:00
{
2026-07-26 17:50:43 -05:00
m_prevLoadInfos ??= new ArrayList();
m_prevLoadInfos.Add(m_info);
m_size = Size.Zero;
2022-03-03 08:40:19 -06:00
}
else
{
2026-07-26 17:50:43 -05:00
m_size = Size.Zero;
m_info?.Dispose();
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
m_info = null;
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
public virtual void StartLoad() => LoadBuffer();
2022-03-03 08:40:19 -06:00
protected void SetBuffer(IntPtr buffer, uint length)
{
2026-07-26 17:50:43 -05:00
m_buffer = buffer;
m_length = length;
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
protected void SetSize(Size size) => m_size = size;
2022-03-03 08:40:19 -06:00
internal void ReloadImage(ContentNotification notification, IImage image, IntPtr data)
{
switch (notification)
{
case ContentNotification.Acquire:
2026-07-26 17:50:43 -05:00
if (RenderImage == null)
2022-03-03 08:40:19 -06:00
break;
2026-07-26 17:50:43 -05:00
m_fFullLoadRequested = true;
LoadBuffer();
2022-03-03 08:40:19 -06:00
break;
case ContentNotification.Release:
2026-07-26 17:50:43 -05:00
EndLoadImageData();
2022-03-03 08:40:19 -06:00
break;
}
}
private void LoadBuffer()
{
2026-07-26 17:50:43 -05:00
if (!EnsureBuffer())
2022-03-03 08:40:19 -06:00
return;
2026-07-26 17:50:43 -05:00
ProcessBuffer();
2022-03-03 08:40:19 -06:00
}
protected bool ProcessBuffer()
{
2026-07-26 17:50:43 -05:00
UpdateLastUsedTime();
return !m_fFullLoadRequested ? DoHeaderLoad() : BeginLoadImageData();
2022-03-03 08:40:19 -06:00
}
private bool BeginLoadImageData()
{
2026-07-26 17:50:43 -05:00
if (!DoImageLoad())
2022-03-03 08:40:19 -06:00
return false;
2026-07-26 17:50:43 -05:00
++m_countLoadsInProgress;
2022-03-03 08:40:19 -06:00
return true;
}
private void EndLoadImageData()
{
2026-07-26 17:50:43 -05:00
AssertValidState();
--m_countLoadsInProgress;
OnImageLoadComplete();
if (!HasLoadsInProgress)
2022-03-03 08:40:19 -06:00
{
2026-07-26 17:50:43 -05:00
if (m_info != null)
2022-03-03 08:40:19 -06:00
{
2026-07-26 17:50:43 -05:00
m_info.Dispose();
m_info = null;
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
if (m_prevLoadInfos != null)
2022-03-03 08:40:19 -06:00
{
2026-07-26 17:50:43 -05:00
foreach (BitmapInformation prevLoadInfo in m_prevLoadInfos)
2022-03-03 08:40:19 -06:00
prevLoadInfo?.Dispose();
2026-07-26 17:50:43 -05:00
m_prevLoadInfos.Clear();
m_prevLoadInfos = null;
2022-03-03 08:40:19 -06:00
}
}
2026-07-26 17:50:43 -05:00
UpdateLastUsedTime();
2022-03-03 08:40:19 -06:00
}
protected virtual bool EnsureBuffer() => true;
protected virtual bool DoHeaderLoad()
{
2026-07-26 17:50:43 -05:00
if (m_buffer == IntPtr.Zero
|| m_length <= 0U
|| !ImageLoader.LoadHeader(m_buffer, (int)m_length, m_req, out var header))
2022-03-03 08:40:19 -06:00
return false;
2026-07-26 17:50:43 -05:00
SetSize(header.sizeActualPxl);
2022-03-03 08:40:19 -06:00
return true;
}
protected virtual bool DoImageLoad()
{
BitmapInformation bitmapInfo = null;
2026-07-26 17:50:43 -05:00
var loadSuccess = false;
if (RenderImage != null)
2022-03-03 08:40:19 -06:00
{
2026-07-26 17:50:43 -05:00
if (m_buffer != IntPtr.Zero)
{
loadSuccess = ImageLoader.FromBuffer(RenderImage, m_buffer, (int)m_length, m_req.MaximumSize,
m_req.Flippable, m_req.AntialiasEdges, m_req.BorderWidth, m_req.BorderColor,
out bitmapInfo);
}
else
{
loadSuccess = ImageLoader.FromFile(RenderImage, RenderImage.Identifier, m_req.MaximumSize,
m_req.Flippable,m_req.AntialiasEdges, m_req.BorderWidth, m_req.BorderColor,
out bitmapInfo);
}
2022-03-03 08:40:19 -06:00
}
2026-07-26 17:50:43 -05:00
if (!loadSuccess)
return false;
m_info = bitmapInfo;
SetSize(m_info.imageInfo.Header.sizeActualPxl);
return true;
2022-03-03 08:40:19 -06:00
}
protected virtual void OnImageLoadComplete()
{
}
2026-07-26 17:50:43 -05:00
internal ImageCache ImageCacheOwner { get; set; }
2022-03-03 08:40:19 -06:00
protected void UpdateLastUsedTime()
{
2026-07-26 17:50:43 -05:00
AssertValidState();
if (DateTime.UtcNow - m_dtLastUsed <= s_tsUpdateThreshhold)
2022-03-03 08:40:19 -06:00
return;
2026-07-26 17:50:43 -05:00
m_dtLastUsed = DateTime.UtcNow;
ImageCacheOwner?.UpdateLastUsedItem(this);
2022-03-03 08:40:19 -06:00
}
public bool IsOlder(DateTime dtCompare)
{
2026-07-26 17:50:43 -05:00
AssertValidState();
return m_dtLastUsed < dtCompare;
2022-03-03 08:40:19 -06:00
}
protected void AssertValidState()
{
}
2026-07-26 17:50:43 -05:00
public override string ToString() => Identifier;
2022-03-03 08:40:19 -06:00
}
}