Files
Xune/UIX.RenderApi.Skia/Microsoft/Iris/Render/Graphics/SurfacePool.cs
T
2021-07-11 23:07:04 -05:00

222 lines
8.2 KiB
C#

// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.Render.Graphics.SurfacePool
// 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.Protocols.Splash.Rendering;
using System;
using System.Collections;
namespace Microsoft.Iris.Render.Graphics
{
internal class SurfacePool : RenderObject, IRenderHandleOwner
{
private GraphicsDevice m_device;
private RenderSession m_session;
private ObjectTracker m_trackerSurfaces;
protected RemoteSurfacePool m_remotePool;
private Size m_sizeStoragePxl;
private bool m_fDestroyWhenEmpty;
private SurfaceFormat m_nFormat;
private SurfacePoolAllocationResult m_nStorage;
private bool m_fPrimaryOwner;
private Effect m_effect;
internal SurfacePool(GraphicsDevice device, SurfaceFormat nFormat, RENDERHANDLE rhExternal) => this.CommonCreate(device, nFormat, rhExternal);
internal SurfacePool(GraphicsDevice device, Size sizeStoragePxl, SurfaceFormat nFormat)
{
Debug2.Validate(sizeStoragePxl.Width > 0 && sizeStoragePxl.Height > 0, typeof(ArgumentException), "Must have positive area");
this.CommonCreate(device, nFormat, RENDERHANDLE.NULL);
this.m_sizeStoragePxl = sizeStoragePxl;
this.m_nStorage = SurfacePoolAllocationResult.NotAllocated;
this.Allocate();
}
private void CommonCreate(
GraphicsDevice device,
SurfaceFormat nFormat,
RENDERHANDLE rhExternal)
{
Debug2.Validate(nFormat != SurfaceFormat.None, typeof(ArgumentException), nameof(nFormat));
Debug2.Validate(device != null, typeof(ArgumentNullException), "Creating a SurfacePool requires a GraphicsDevice");
this.m_device = device;
this.m_session = device.Session;
Debug2.Validate(this.m_session != null, typeof(InvalidOperationException), "Creating a SurfacePool requires a RenderSession");
this.m_session.AssertOwningThread();
this.m_remotePool = null;
this.m_sizeStoragePxl = new Size();
this.m_nFormat = nFormat;
RENDERHANDLE handle = rhExternal;
if (handle == RENDERHANDLE.NULL)
{
handle = this.m_session.RenderingPort.AllocHandle(this);
this.m_fPrimaryOwner = true;
}
try
{
this.CreateRemoteSurfacePool(handle, this.m_fPrimaryOwner);
}
finally
{
if (this.m_remotePool == null)
{
GC.SuppressFinalize(this);
if (this.m_fPrimaryOwner)
this.m_session.RenderingPort.FreeHandle(handle);
}
}
this.m_trackerSurfaces = new ObjectTracker(this.m_session, this);
if (this.m_fPrimaryOwner)
return;
this.m_nStorage = SurfacePoolAllocationResult.Immoveable;
}
protected virtual void CreateRemoteSurfacePool(RENDERHANDLE handle, bool fPrimaryOwner)
{
if (fPrimaryOwner)
{
this.m_device.CreateSurfacePool(this, handle, this.Format);
this.m_remotePool = RemoteSurfacePool.CreateFromHandle(this.m_session.RenderingPort, handle);
}
else
this.m_remotePool = RemoteSurfacePool.CreateFromExternalHandle(this.m_session.RenderingPort, handle, this);
}
protected override void Dispose(bool fInDispose)
{
try
{
if (fInDispose)
{
if (this.m_effect != null)
this.m_effect.UnregisterUsage(this);
this.DisposeAllSurfaces();
this.m_trackerSurfaces.Dispose();
this.m_remotePool.Dispose();
this.m_device.OnSurfacePoolDispose();
}
this.m_effect = null;
this.m_remotePool = null;
this.m_trackerSurfaces = null;
this.m_device = null;
}
finally
{
base.Dispose(fInDispose);
}
}
RENDERHANDLE IRenderHandleOwner.RenderHandle => this.m_remotePool.RenderHandle;
void IRenderHandleOwner.OnDisconnect() => this.m_remotePool = null;
public Size StorageSize => this.m_sizeStoragePxl;
public SurfaceFormat Format => this.m_nFormat;
internal RemoteSurfacePool RemoteStub => this.m_remotePool;
protected RenderSession Session => this.m_session;
internal GraphicsDevice Device => this.m_device;
internal bool DestroyWhenEmpty
{
get => this.m_fDestroyWhenEmpty;
set => this.m_fDestroyWhenEmpty = value;
}
internal IList AllSurfaces
{
get
{
IList list = null;
if (this.m_trackerSurfaces != null)
list = m_trackerSurfaces.LiveObjects;
return list;
}
}
internal SurfacePoolAllocationResult StorageState => this.m_nStorage;
public Effect Effect
{
get => this.m_effect;
set
{
Effect effect = value;
if (this.m_effect == effect)
return;
if (this.m_effect != null)
this.m_effect.UnregisterUsage(this);
this.m_effect = effect;
if (this.m_effect != null)
this.m_effect.RegisterUsage(this);
this.m_remotePool.SendSetEffect(this.m_effect == null ? null : this.m_effect.RemoteStub);
}
}
internal int CreateSurface(Surface spNew, RENDERHANDLE handle)
{
this.m_remotePool.SendCreateSurface(handle);
return this.AttachSurface(spNew);
}
internal int AttachSurface(Surface spNew) => this.m_trackerSurfaces.AddObject(spNew);
internal void DisposeAllSurfaces()
{
if (this.m_trackerSurfaces == null)
return;
ArrayList liveObjects = this.m_trackerSurfaces.LiveObjects;
for (int index = 0; index < liveObjects.Count; ++index)
((SharedRenderObject)liveObjects[index]).UnregisterUsage(this);
}
internal void NotifyDisposeSurface(int nID)
{
if (this.m_trackerSurfaces == null)
return;
this.m_trackerSurfaces.RemoveObject(nID);
if (!this.m_fDestroyWhenEmpty || !this.m_trackerSurfaces.IsEmpty)
return;
this.Dispose();
}
internal void Restore()
{
if (this.m_remotePool == null || !this.m_remotePool.IsValid)
return;
if (!this.m_sizeStoragePxl.IsZero)
this.Allocate();
ArrayList liveObjects = this.m_trackerSurfaces.LiveObjects;
for (int index = 0; index < liveObjects.Count; ++index)
((Surface)liveObjects[index]).RestoreContent();
}
internal static void RemapSurface(Surface surCur, SurfacePool poolNew)
{
SurfacePool surfacePool = surCur.SurfacePool;
if (poolNew == surfacePool)
return;
int surfacePoolInstanceId = surCur.SurfacePoolInstanceID;
surfacePool.NotifyDisposeSurface(surfacePoolInstanceId);
int nNewInstanceID = poolNew.m_trackerSurfaces.AddObject(surCur);
surCur.NotifyNewPool(poolNew, nNewInstanceID);
}
internal void NotifyAllocation(SurfacePoolAllocationResult nResult) => this.m_nStorage = nResult;
private void Allocate()
{
this.m_remotePool.SendAllocate(this.m_sizeStoragePxl);
this.m_nStorage = SurfacePoolAllocationResult.Requested;
}
}
}