2021-07-11 22:59:29 -05:00
// 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
{
2021-07-11 23:04:40 -05:00
internal class Image : SharedResource , IImage , ISharedRenderObject , ISurfaceContentOwner
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
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 ;
2021-07-11 22:59:29 -05:00
2021-07-11 23:04:40 -05:00
internal Image (
RenderSession session ,
SurfaceManager surfaceManager ,
string identifier ,
ContentNotifyHandler handler ,
Size sizeGutter )
: base ( session )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
session . AssertOwningThread ();
this . m_session = session ;
this . m_surfaceManager = surfaceManager ;
this . m_stIdentifier = identifier ;
this . m_handlerContent = handler ;
this . m_sizeGutterPxl = sizeGutter ;
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
protected override void Dispose ( bool fInDispose )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
try
{
if ( fInDispose && this . m_dataTracker != null )
MessagingSession . Current . ReturnDataBufferTracker ( this . m_dataTracker );
2021-07-11 23:07:04 -05:00
this . m_surface = null ;
this . m_surfaceManager = null ;
this . m_dataTracker = null ;
this . m_handlerContent = null ;
this . m_session = null ;
2021-07-11 23:04:40 -05:00
}
finally
{
base . Dispose ( fInDispose );
}
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
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
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
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 ();
}
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
void ISurfaceContentOwner . OnSurfaceDisposed ( Surface surface )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
if ( this . m_surface != surface )
return ;
2021-07-11 23:07:04 -05:00
this . m_surface = null ;
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
void ISurfaceContentOwner . OnRestoreContent ( Surface surface )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
if ( this . m_surface != surface )
return ;
this . AcquireContent ();
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
Size IImage . Size => this . m_sizeImage ;
2021-07-11 22:59:29 -05:00
2021-07-11 23:04:40 -05:00
ImageFormat IImage . Format => this . m_imageFormat ;
string IImage . Identifier => this . m_stIdentifier ;
bool IImage . LoadContent (
ImageFormat imageFormat ,
Size sizeImage ,
int nStride ,
2021-07-15 22:00:36 -05:00
byte [] rgData )
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
this . m_session . AssertOwningThread ();
bool flag1 = false ;
bool flag2 = false ;
2021-07-11 23:07:04 -05:00
DataBuffer buffer = null ;
2021-07-11 23:04:40 -05:00
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 )
2021-07-11 23:07:04 -05:00
this . m_surface . RemoveActiveUser ( this );
this . m_surface = null ;
2021-07-11 23:04:40 -05:00
}
if ( this . m_surface == null )
{
2021-07-11 23:07:04 -05:00
this . m_surface = this . m_surfaceManager . RequestSurface ( this , nFormat , sizeImage , this . m_sizeGutterPxl );
2021-07-11 23:04:40 -05:00
flag2 = true ;
if ( this . InUse )
2021-07-11 23:07:04 -05:00
this . m_surface . AddActiveUser ( this );
2021-07-11 23:04:40 -05:00
}
2021-07-15 22:00:36 -05:00
byte [] num1 = null ;
2021-07-11 23:04:40 -05:00
if ( this . m_session . IsForeignByteOrderOnWindowing )
{
int bitsPerPixel = SurfaceFormatInfo . GetBitsPerPixel ( nFormat );
int num2 = sizeImage . Height * nStride ;
2021-07-15 22:00:36 -05:00
num1 = new byte [ num2 ];
// TODO: Does this need to be re-implemented?
throw new NotImplementedException ();
//Memory.ConvertEndian(num1, rgData, num2, bitsPerPixel);
2021-07-11 23:04:40 -05:00
}
this . m_imageFormat = imageFormat ;
this . m_sizeImage = sizeImage ;
uint cbSize = ( uint )( nStride * this . m_sizeImage . Height );
2021-07-15 22:00:36 -05:00
buffer = this . m_session . BuildDataBuffer ( num1 == null ? rgData : num1 , cbSize );
2021-07-11 23:04:40 -05:00
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 );
2021-07-11 23:07:04 -05:00
this . m_surface = null ;
2021-07-11 23:04:40 -05:00
}
}
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
internal event Image . ContentReloadedHandler ContentReloadedEvent ;
2021-07-11 22:59:29 -05:00
2021-07-11 23:04:40 -05:00
private void AcquireContent ()
2021-07-11 22:59:29 -05:00
{
2021-07-11 23:04:40 -05:00
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
2021-07-15 22:00:36 -05:00
this . m_handlerContent ( ContentNotification . Acquire , this , null );
2021-07-11 23:04:40 -05:00
}
Surface surface = this . m_surface ;
2021-07-11 22:59:29 -05:00
}
2021-07-11 23:04:40 -05:00
protected override void OnUsageChange ( bool fUsed )
{
if ( fUsed )
{
if ( this . m_surface == null )
this . AcquireContent ();
else
2021-07-11 23:07:04 -05:00
this . m_surface . AddActiveUser ( this );
2021-07-11 23:04:40 -05:00
}
else
{
if ( this . m_surface == null )
return ;
2021-07-11 23:07:04 -05:00
this . m_surface . RemoveActiveUser ( this );
2021-07-11 23:04:40 -05:00
}
}
2021-07-15 22:00:36 -05:00
private void Track ( DataBuffer buffer , byte [] rgConvertData , byte [] rgAppData , int nStride )
2021-07-11 23:04:40 -05:00
{
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 );
2021-07-11 23:07:04 -05:00
this . m_dataTracker = null ;
2021-07-11 23:04:40 -05:00
}
2021-07-11 23:07:04 -05:00
this . m_dataTracker = MessagingSession . Current . CreateDataBufferTracker ( this );
2021-07-11 23:04:40 -05:00
}
DataBufferCleanupInfo bufferCleanupInfo = new DataBufferCleanupInfo ();
bufferCleanupInfo . rgConvertData = rgConvertData ;
bufferCleanupInfo . imageLoadInfo = imageLoadInfo ;
2021-07-11 23:07:04 -05:00
DataBufferTracker . CleanupEventHandler handler = new DataBufferTracker . CleanupEventHandler ( OnDataBufferConsumed );
this . m_dataTracker . Track ( buffer , handler , bufferCleanupInfo );
2021-07-11 23:04:40 -05:00
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 ;
2021-07-11 23:07:04 -05:00
imageLoadInfo . handlerNotify ( ContentNotification . Release , imageLoadInfo . imageOwner , imageLoadInfo . rgAppData );
2021-07-11 23:04:40 -05:00
imageLoadInfo . imageOwner . m_insideReleaseCallback = false ;
}
2021-07-15 22:00:36 -05:00
imageLoadInfo . rgAppData = null ;
2021-07-11 23:07:04 -05:00
imageLoadInfo . handlerNotify = null ;
imageLoadInfo . imageOwner = null ;
2021-07-11 23:04:40 -05:00
}
2021-07-15 22:00:36 -05:00
if (!( contextData . rgConvertData != null ))
2021-07-11 23:04:40 -05:00
return ;
2021-07-15 22:00:36 -05:00
contextData . rgConvertData = null ;
2021-07-11 23:04:40 -05:00
}
internal delegate void ContentReloadedHandler ( Image image );
}
2021-07-11 22:59:29 -05:00
}