Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

229 lines
6.9 KiB

//=========== Copyright Valve Corporation, All rights reserved. ===============//
//
// Purpose:
//=============================================================================//
#ifndef IMAGESOURCE_H
#define IMAGESOURCE_H
#ifdef _WIN32
#pragma once
#endif
#include "panorama/data/iimagesource.h"
#include "panorama/controls/panelptr.h"
#include "tier1/utlbuffer.h"
#include "tier1/fileio.h"
#include "tier1/utlmap.h"
#include "refcount.h"
#include "../../panorama/uifileresource.h"
#include "tier1/utldelegate.h"
namespace panorama
{
// Helper to determine byte size of a pixel in a given format
int GetFormatPixelBytes( EImageFormat format );
class CMovie;
class IUIRenderEngine;
class IUITexture;
class CImageData;
// Helper for converting rgba8 to a8 throwing out rgb channels
void ConvertRGBA8ToA8( CUtlBuffer &bufIn, CUtlBuffer &bufOut, uint32 unWide, uint32 unTall );
class CImageProxySource;
class CImageLoaderTask;
#if defined( SOURCE2_PANORAMA )
class CLoadFromVTexTask;
#endif
enum ESourceFormats
{
k_ESourceFormatUnknown,
k_ESourceFormatTGA,
k_ESourceFormatPNG,
k_ESourceFormatJPG,
k_ESourceFormatRawRGBA,
k_ESourceFormatGIF,
k_ESourceFormatVTEX
};
class CImageData;
typedef void (ImageDecodeCallback_t)( bool bSuccess, CImageData *pNewImage, CUtlBuffer *pBufDecoded );
class CImageDecodeWorkItem
{
public:
CImageDecodeWorkItem( IUIRenderEngine *pRenderEngine, CUtlBuffer &bufDataInMayModify, const char *pchFilePath, int nWide, int nTall, int nResizeWidth, int nResizeHeight,
EImageFormat formatOut, bool bAllowAnimation, CUtlDelegate< ImageDecodeCallback_t > del );
~CImageDecodeWorkItem();
void RunWorkItem();
void DispatchResult();
private:
bool m_bSuccess;
IUIRenderEngine *m_pSurface;
CUtlBuffer *m_pBuffer;
CUtlString m_strFilePath;
int m_nWide;
int m_nTall;
int m_nResizeWidth;
int m_nResizeHeight;
EImageFormat m_eFormat;
bool m_bAllowAnimation;
CImageData *m_pNewImage;
CUtlDelegate< ImageDecodeCallback_t > m_Del;
};
class CImageDecodeWorkThreadPool;
class CImageDecodeThread : public CThread
{
public:
CImageDecodeThread( CImageDecodeWorkThreadPool *pParent )
{
m_bExit = false;
m_pParent = pParent;
}
~CImageDecodeThread()
{
}
void Stop() { m_bExit = true; }
virtual int Run() OVERRIDE;
private:
volatile bool m_bExit;
CImageDecodeWorkThreadPool *m_pParent;
};
class CImageDecodeWorkThreadPool
{
public:
CImageDecodeWorkThreadPool();
~CImageDecodeWorkThreadPool();
// Run frame on main thread
void RunFrame();
void AddWorkItem( CImageDecodeWorkItem *pWorkItem );
private:
friend class CImageDecodeThread;
CImageDecodeThread * m_pWorkThreads[1];
CThreadMutex m_AsyncIoLock;
CThreadEvent m_ThreadEvent;
CUtlLinkedList< CImageDecodeWorkItem *, int > m_llAsyncIORequests;
CUtlLinkedList< CImageDecodeWorkItem *, int > m_llAsyncIOResults;
};
//
// A container of images we have loaded
//
class CImageResourceManager : public IUIImageManager
{
public:
CImageResourceManager( IUIRenderEngine *pSurface );
~CImageResourceManager();
virtual void Shutdown();
virtual IImageSource *LoadImageFromURL( const IUIPanel *pPanel, const char *pchResourceURLDefault, const char *pchResourceURL, bool bPrioritizeLoad, EImageFormat imgFormatOut, int32 nResizeWidth = panorama::k_ResizeNone, int32 nResizeHeight = panorama::k_ResizeNone, bool bAllowAnimation = true );
virtual IImageSource *LoadImageFileFromMemory( const IUIPanel *pPanel, const char *pchResourceURLDefault, const CUtlBuffer &bufFile, int nResizeWidth = panorama::k_ResizeNone, int nResizeHeight = panorama::k_ResizeNone, bool bAllowAnimation = true );
virtual IImageSource *LoadImageFromMemory( const IUIPanel *pPanel, const char *pchResourceURLDefault, const CUtlBuffer &bufRGBA, int nWide, int nTall, EImageFormat imgFormatIn = k_EImageFormatR8G8B8A8, int nResizeWidth = panorama::k_ResizeNone, int nResizeHeight = panorama::k_ResizeNone, bool bAllowAnimation = true );
virtual CUtlString GetPchImageSourcePath( IImageSource *pImageSource ) OVERRIDE;
virtual void ReloadChangedFile( const char *pchFile ) OVERRIDE;
virtual void ReloadChangedImage( IImageSource *pImageToReload ) OVERRIDE;
bool OnImageUnreferenced( CImageProxySource *pImage );
void RunFrame();
void QueueImageDecodeWorkItem( CImageDecodeWorkItem *pWorkItem );
#ifdef DBGFLAG_VALIDATE
virtual void Validate( CValidator &validator, const tchar *pchName );
#endif
private:
IImageSource *LoadImageInternal( const IUIPanel *pPanel, CFileResource &fileResourceDefault, CFileResource &fileResource, bool bPrioritizeLoad, EImageFormat imgFormatOut, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
CImageProxySource *GetDefaultImage( CFileResource &fileDefault, EImageFormat imgFormatOut, bool bAllowAnimation );
friend class CLoadFileURLTask;
friend class CLoadFileLocalTask;
friend class CImageLoaderTask;
#if defined( SOURCE2_PANORAMA )
friend class CLoadFromVTexTask;
#endif
// Internally adds image to our tracking maps
void AddImageToManager( CFileResource &resource, CImageProxySource *pImageProxy, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
bool RemoveImageFromManager( IImageSource *pImage );
// Loads a resource, returns vector index
bool OnImageLoaded( CFileResource & resource, CImageData *pImage, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
bool OnFailedImageLoad( CFileResource & resource, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
void AddLoad( CFileResource &resource, EImageFormat eFormat, bool bPrioritizeLoad, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
// Synchronous load only used for initial global default image
bool LoadLocalFileSynchronous( CFileResource &resource, EImageFormat eFormat, bool bAllowAnimation );
#if defined( SOURCE2_PANORAMA )
bool FixupFileResourceToCompiledImage( CFileResource &fileResource );
#endif
struct UrlImageKey_t
{
CFileResource fileResource;
int32 nTargetWidth;
int32 nTargetHeight;
bool bAllowAnimation;
// Sort on size only
bool operator <( const UrlImageKey_t &l ) const
{
if ( nTargetWidth < l.nTargetWidth )
return true;
else if ( nTargetWidth > l.nTargetWidth )
return false;
if ( nTargetHeight < l.nTargetHeight )
return true;
else if ( nTargetHeight > l.nTargetHeight )
return false;
if ( bAllowAnimation && !l.bAllowAnimation )
return true;
else if ( !bAllowAnimation && l.bAllowAnimation )
return false;
return fileResource < l.fileResource;
}
};
CUtlMap< UrlImageKey_t, CImageProxySource *, int, CDefLess< UrlImageKey_t > > m_mapImagesByURL;
CUtlMap< IImageSource *, UrlImageKey_t, int, CDefLess< IImageSource *> > m_mapAllImages;
CUtlVector< CImageLoaderTask * > m_vecLoaderTasksToStart;
CUtlRBTree< CImageLoaderTask *, int, CDefLess< CImageLoaderTask * > > m_treeLoadTasks;
IUIRenderEngine *m_pSurface;
CImageDecodeWorkThreadPool *m_pImageDecodePool;
bool m_bInited;
};
} // namespace panorama
#endif // IMAGESOURCE_H