mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 22:27:05 +00:00
229 lines
6.9 KiB
C++
229 lines
6.9 KiB
C++
//=========== 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
|