mirror of
https://github.com/ZuneDev/Xune.git
synced 2026-07-27 13:13:10 -07:00
275 lines
9.3 KiB
C#
275 lines
9.3 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Microsoft.Iris.Render.Graphics.Image
|
|
// 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 Microsoft.Iris.Render.Common;
|
|
using Microsoft.Iris.Render.Internal;
|
|
using Microsoft.Iris.Render.Protocol;
|
|
using Microsoft.Iris.Render.Remote;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Microsoft.Iris.Render.Graphics
|
|
{
|
|
internal class Image : SharedResource, IImage, ISharedRenderObject, ISurfaceContentOwner
|
|
{
|
|
private SurfaceManager m_surfaceManager;
|
|
private Surface m_surface;
|
|
private ImageFormat m_imageFormat;
|
|
private Size m_sizeImage;
|
|
private Size m_sizeGutterPxl;
|
|
private DataBufferTracker m_dataTracker;
|
|
private ContentNotifyHandler m_handlerContent;
|
|
private string m_stIdentifier;
|
|
private ImageLoadInfo m_loadInfo;
|
|
private bool m_insideReleaseCallback;
|
|
|
|
internal Image(
|
|
RenderSession session,
|
|
SurfaceManager surfaceManager,
|
|
string identifier,
|
|
ContentNotifyHandler handler,
|
|
Size sizeGutter)
|
|
: base(session)
|
|
{
|
|
session.AssertOwningThread();
|
|
this.m_session = session;
|
|
this.m_surfaceManager = surfaceManager;
|
|
this.m_stIdentifier = identifier;
|
|
this.m_handlerContent = handler;
|
|
this.m_sizeGutterPxl = sizeGutter;
|
|
}
|
|
|
|
protected override void Dispose(bool fInDispose)
|
|
{
|
|
try
|
|
{
|
|
if (fInDispose && this.m_dataTracker != null)
|
|
MessagingSession.Current.ReturnDataBufferTracker(this.m_dataTracker);
|
|
this.m_surface = (Surface) null;
|
|
this.m_surfaceManager = (SurfaceManager) null;
|
|
this.m_dataTracker = (DataBufferTracker) null;
|
|
this.m_handlerContent = (ContentNotifyHandler) null;
|
|
this.m_session = (RenderSession) null;
|
|
}
|
|
finally
|
|
{
|
|
base.Dispose(fInDispose);
|
|
}
|
|
}
|
|
|
|
internal Size Size => this.m_sizeImage;
|
|
|
|
internal ImageFormat Format => this.m_imageFormat;
|
|
|
|
internal Surface Surface => this.m_surface;
|
|
|
|
internal string Identifier => this.m_stIdentifier;
|
|
|
|
internal Size GutterSize
|
|
{
|
|
get => this.m_sizeGutterPxl;
|
|
set
|
|
{
|
|
if (value.Width <= this.m_sizeGutterPxl.Width && value.Height <= this.m_sizeGutterPxl.Height)
|
|
return;
|
|
this.m_sizeGutterPxl.Width = Math.Max(value.Width, this.m_sizeGutterPxl.Width);
|
|
this.m_sizeGutterPxl.Height = Math.Max(value.Height, this.m_sizeGutterPxl.Height);
|
|
if (!this.InUse)
|
|
return;
|
|
this.AcquireContent();
|
|
}
|
|
}
|
|
|
|
void ISurfaceContentOwner.OnSurfaceDisposed(Surface surface)
|
|
{
|
|
if (this.m_surface != surface)
|
|
return;
|
|
this.m_surface = (Surface) null;
|
|
}
|
|
|
|
void ISurfaceContentOwner.OnRestoreContent(Surface surface)
|
|
{
|
|
if (this.m_surface != surface)
|
|
return;
|
|
this.AcquireContent();
|
|
}
|
|
|
|
Size IImage.Size => this.m_sizeImage;
|
|
|
|
ImageFormat IImage.Format => this.m_imageFormat;
|
|
|
|
string IImage.Identifier => this.m_stIdentifier;
|
|
|
|
bool IImage.LoadContent(
|
|
ImageFormat imageFormat,
|
|
Size sizeImage,
|
|
int nStride,
|
|
IntPtr rgData)
|
|
{
|
|
this.m_session.AssertOwningThread();
|
|
bool flag1 = false;
|
|
bool flag2 = false;
|
|
DataBuffer buffer = (DataBuffer) null;
|
|
try
|
|
{
|
|
SurfaceFormat nFormat = SurfaceFormatInfo.FromImageFormat(imageFormat);
|
|
if (nFormat == SurfaceFormat.RGB32)
|
|
nFormat = SurfaceFormat.ARGB32;
|
|
if (this.m_surface != null && (this.m_imageFormat != imageFormat || this.m_sizeImage != sizeImage || this.m_sizeGutterPxl != this.m_surface.GutterSize))
|
|
{
|
|
if (this.InUse)
|
|
this.m_surface.RemoveActiveUser((object) this);
|
|
this.m_surface = (Surface) null;
|
|
}
|
|
if (this.m_surface == null)
|
|
{
|
|
this.m_surface = this.m_surfaceManager.RequestSurface((ISurfaceContentOwner) this, nFormat, sizeImage, this.m_sizeGutterPxl);
|
|
flag2 = true;
|
|
if (this.InUse)
|
|
this.m_surface.AddActiveUser((object) this);
|
|
}
|
|
IntPtr num1 = IntPtr.Zero;
|
|
if (this.m_session.IsForeignByteOrderOnWindowing)
|
|
{
|
|
int bitsPerPixel = SurfaceFormatInfo.GetBitsPerPixel(nFormat);
|
|
int num2 = sizeImage.Height * nStride;
|
|
num1 = Marshal.AllocHGlobal(num2);
|
|
Memory.ConvertEndian(num1, rgData, num2, bitsPerPixel);
|
|
}
|
|
this.m_imageFormat = imageFormat;
|
|
this.m_sizeImage = sizeImage;
|
|
uint cbSize = (uint) (nStride * this.m_sizeImage.Height);
|
|
buffer = this.m_session.BuildDataBuffer(num1 == IntPtr.Zero ? rgData : num1, cbSize);
|
|
this.Track(buffer, num1, rgData, nStride);
|
|
buffer.Commit();
|
|
++this.m_loadInfo.nLoadsInProgress;
|
|
ImageHeader header;
|
|
header.sizeActualPxl = this.m_sizeImage;
|
|
header.sizeOriginalPxl = this.m_sizeImage;
|
|
header.nStride = nStride;
|
|
header.nFormat = nFormat;
|
|
this.m_session.LoadSurface(buffer, this.m_surface, header);
|
|
if (flag2 && this.ContentReloadedEvent != null)
|
|
this.ContentReloadedEvent(this);
|
|
flag1 = true;
|
|
return flag1;
|
|
}
|
|
finally
|
|
{
|
|
if (!flag1)
|
|
{
|
|
if (buffer != null)
|
|
this.StopTracking(buffer);
|
|
this.m_surface = (Surface) null;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal event Image.ContentReloadedHandler ContentReloadedEvent;
|
|
|
|
private void AcquireContent()
|
|
{
|
|
Debug2.Validate(!this.m_insideReleaseCallback, typeof (InvalidOperationException), "AcquireContent must not be called while inside ContentNotify(Release) callback");
|
|
ContentNotifyHandler handlerContent = this.m_handlerContent;
|
|
if (this.m_handlerContent != null)
|
|
{
|
|
if (this.m_loadInfo != null && this.m_loadInfo.nLoadsInProgress > 0)
|
|
{
|
|
++this.m_loadInfo.nSystemLoadRequests;
|
|
((IImage) this).LoadContent(this.m_imageFormat, this.m_sizeImage, this.m_loadInfo.nStride, this.m_loadInfo.rgAppData);
|
|
}
|
|
else
|
|
this.m_handlerContent(ContentNotification.Acquire, (IImage) this, IntPtr.Zero);
|
|
}
|
|
Surface surface = this.m_surface;
|
|
}
|
|
|
|
protected override void OnUsageChange(bool fUsed)
|
|
{
|
|
if (fUsed)
|
|
{
|
|
if (this.m_surface == null)
|
|
this.AcquireContent();
|
|
else
|
|
this.m_surface.AddActiveUser((object) this);
|
|
}
|
|
else
|
|
{
|
|
if (this.m_surface == null)
|
|
return;
|
|
this.m_surface.RemoveActiveUser((object) this);
|
|
}
|
|
}
|
|
|
|
private void Track(DataBuffer buffer, IntPtr rgConvertData, IntPtr rgAppData, int nStride)
|
|
{
|
|
ImageLoadInfo imageLoadInfo;
|
|
if (this.m_loadInfo != null && this.m_loadInfo.rgAppData == rgAppData && this.m_loadInfo.nStride == nStride)
|
|
{
|
|
imageLoadInfo = this.m_loadInfo;
|
|
}
|
|
else
|
|
{
|
|
imageLoadInfo = new ImageLoadInfo();
|
|
imageLoadInfo.imageOwner = this;
|
|
imageLoadInfo.nLoadsInProgress = 0;
|
|
imageLoadInfo.nSystemLoadRequests = 0;
|
|
imageLoadInfo.handlerNotify = this.m_handlerContent;
|
|
imageLoadInfo.rgAppData = rgAppData;
|
|
imageLoadInfo.nStride = nStride;
|
|
if (this.m_dataTracker != null)
|
|
{
|
|
MessagingSession.Current.ReturnDataBufferTracker(this.m_dataTracker);
|
|
this.m_dataTracker = (DataBufferTracker) null;
|
|
}
|
|
this.m_dataTracker = MessagingSession.Current.CreateDataBufferTracker((object) this);
|
|
}
|
|
DataBufferCleanupInfo bufferCleanupInfo = new DataBufferCleanupInfo();
|
|
bufferCleanupInfo.rgConvertData = rgConvertData;
|
|
bufferCleanupInfo.imageLoadInfo = imageLoadInfo;
|
|
DataBufferTracker.CleanupEventHandler handler = new DataBufferTracker.CleanupEventHandler(Image.OnDataBufferConsumed);
|
|
this.m_dataTracker.Track(buffer, handler, (object) bufferCleanupInfo);
|
|
this.m_loadInfo = imageLoadInfo;
|
|
}
|
|
|
|
private void StopTracking(DataBuffer buffer)
|
|
{
|
|
if (this.m_dataTracker == null)
|
|
return;
|
|
this.m_dataTracker.Release(buffer, DataBufferTracker.Users.Valid);
|
|
}
|
|
|
|
private static void OnDataBufferConsumed(object sender, DataBufferTracker.CleanupEventArgs args)
|
|
{
|
|
DataBufferCleanupInfo contextData = (DataBufferCleanupInfo) args.ContextData;
|
|
ImageLoadInfo imageLoadInfo = contextData.imageLoadInfo;
|
|
--imageLoadInfo.nLoadsInProgress;
|
|
if (imageLoadInfo.nSystemLoadRequests > 0)
|
|
{
|
|
--imageLoadInfo.nSystemLoadRequests;
|
|
}
|
|
else
|
|
{
|
|
if (imageLoadInfo.handlerNotify != null)
|
|
{
|
|
imageLoadInfo.imageOwner.m_insideReleaseCallback = true;
|
|
imageLoadInfo.handlerNotify(ContentNotification.Release, (IImage) imageLoadInfo.imageOwner, imageLoadInfo.rgAppData);
|
|
imageLoadInfo.imageOwner.m_insideReleaseCallback = false;
|
|
}
|
|
imageLoadInfo.rgAppData = IntPtr.Zero;
|
|
imageLoadInfo.handlerNotify = (ContentNotifyHandler) null;
|
|
imageLoadInfo.imageOwner = (Image) null;
|
|
}
|
|
if (!(contextData.rgConvertData != IntPtr.Zero))
|
|
return;
|
|
Marshal.FreeHGlobal(contextData.rgConvertData);
|
|
contextData.rgConvertData = IntPtr.Zero;
|
|
}
|
|
|
|
internal delegate void ContentReloadedHandler(Image image);
|
|
}
|
|
}
|