|
|
//=========== 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
|