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.

228 lines
6.9 KiB

  1. //=========== Copyright Valve Corporation, All rights reserved. ===============//
  2. //
  3. // Purpose:
  4. //=============================================================================//
  5. #ifndef IMAGESOURCE_H
  6. #define IMAGESOURCE_H
  7. #ifdef _WIN32
  8. #pragma once
  9. #endif
  10. #include "panorama/data/iimagesource.h"
  11. #include "panorama/controls/panelptr.h"
  12. #include "tier1/utlbuffer.h"
  13. #include "tier1/fileio.h"
  14. #include "tier1/utlmap.h"
  15. #include "refcount.h"
  16. #include "../../panorama/uifileresource.h"
  17. #include "tier1/utldelegate.h"
  18. namespace panorama
  19. {
  20. // Helper to determine byte size of a pixel in a given format
  21. int GetFormatPixelBytes( EImageFormat format );
  22. class CMovie;
  23. class IUIRenderEngine;
  24. class IUITexture;
  25. class CImageData;
  26. // Helper for converting rgba8 to a8 throwing out rgb channels
  27. void ConvertRGBA8ToA8( CUtlBuffer &bufIn, CUtlBuffer &bufOut, uint32 unWide, uint32 unTall );
  28. class CImageProxySource;
  29. class CImageLoaderTask;
  30. #if defined( SOURCE2_PANORAMA )
  31. class CLoadFromVTexTask;
  32. #endif
  33. enum ESourceFormats
  34. {
  35. k_ESourceFormatUnknown,
  36. k_ESourceFormatTGA,
  37. k_ESourceFormatPNG,
  38. k_ESourceFormatJPG,
  39. k_ESourceFormatRawRGBA,
  40. k_ESourceFormatGIF,
  41. k_ESourceFormatVTEX
  42. };
  43. class CImageData;
  44. typedef void (ImageDecodeCallback_t)( bool bSuccess, CImageData *pNewImage, CUtlBuffer *pBufDecoded );
  45. class CImageDecodeWorkItem
  46. {
  47. public:
  48. CImageDecodeWorkItem( IUIRenderEngine *pRenderEngine, CUtlBuffer &bufDataInMayModify, const char *pchFilePath, int nWide, int nTall, int nResizeWidth, int nResizeHeight,
  49. EImageFormat formatOut, bool bAllowAnimation, CUtlDelegate< ImageDecodeCallback_t > del );
  50. ~CImageDecodeWorkItem();
  51. void RunWorkItem();
  52. void DispatchResult();
  53. private:
  54. bool m_bSuccess;
  55. IUIRenderEngine *m_pSurface;
  56. CUtlBuffer *m_pBuffer;
  57. CUtlString m_strFilePath;
  58. int m_nWide;
  59. int m_nTall;
  60. int m_nResizeWidth;
  61. int m_nResizeHeight;
  62. EImageFormat m_eFormat;
  63. bool m_bAllowAnimation;
  64. CImageData *m_pNewImage;
  65. CUtlDelegate< ImageDecodeCallback_t > m_Del;
  66. };
  67. class CImageDecodeWorkThreadPool;
  68. class CImageDecodeThread : public CThread
  69. {
  70. public:
  71. CImageDecodeThread( CImageDecodeWorkThreadPool *pParent )
  72. {
  73. m_bExit = false;
  74. m_pParent = pParent;
  75. }
  76. ~CImageDecodeThread()
  77. {
  78. }
  79. void Stop() { m_bExit = true; }
  80. virtual int Run() OVERRIDE;
  81. private:
  82. volatile bool m_bExit;
  83. CImageDecodeWorkThreadPool *m_pParent;
  84. };
  85. class CImageDecodeWorkThreadPool
  86. {
  87. public:
  88. CImageDecodeWorkThreadPool();
  89. ~CImageDecodeWorkThreadPool();
  90. // Run frame on main thread
  91. void RunFrame();
  92. void AddWorkItem( CImageDecodeWorkItem *pWorkItem );
  93. private:
  94. friend class CImageDecodeThread;
  95. CImageDecodeThread * m_pWorkThreads[1];
  96. CThreadMutex m_AsyncIoLock;
  97. CThreadEvent m_ThreadEvent;
  98. CUtlLinkedList< CImageDecodeWorkItem *, int > m_llAsyncIORequests;
  99. CUtlLinkedList< CImageDecodeWorkItem *, int > m_llAsyncIOResults;
  100. };
  101. //
  102. // A container of images we have loaded
  103. //
  104. class CImageResourceManager : public IUIImageManager
  105. {
  106. public:
  107. CImageResourceManager( IUIRenderEngine *pSurface );
  108. ~CImageResourceManager();
  109. virtual void Shutdown();
  110. 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 );
  111. 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 );
  112. 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 );
  113. virtual CUtlString GetPchImageSourcePath( IImageSource *pImageSource ) OVERRIDE;
  114. virtual void ReloadChangedFile( const char *pchFile ) OVERRIDE;
  115. virtual void ReloadChangedImage( IImageSource *pImageToReload ) OVERRIDE;
  116. bool OnImageUnreferenced( CImageProxySource *pImage );
  117. void RunFrame();
  118. void QueueImageDecodeWorkItem( CImageDecodeWorkItem *pWorkItem );
  119. #ifdef DBGFLAG_VALIDATE
  120. virtual void Validate( CValidator &validator, const tchar *pchName );
  121. #endif
  122. private:
  123. IImageSource *LoadImageInternal( const IUIPanel *pPanel, CFileResource &fileResourceDefault, CFileResource &fileResource, bool bPrioritizeLoad, EImageFormat imgFormatOut, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
  124. CImageProxySource *GetDefaultImage( CFileResource &fileDefault, EImageFormat imgFormatOut, bool bAllowAnimation );
  125. friend class CLoadFileURLTask;
  126. friend class CLoadFileLocalTask;
  127. friend class CImageLoaderTask;
  128. #if defined( SOURCE2_PANORAMA )
  129. friend class CLoadFromVTexTask;
  130. #endif
  131. // Internally adds image to our tracking maps
  132. void AddImageToManager( CFileResource &resource, CImageProxySource *pImageProxy, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
  133. bool RemoveImageFromManager( IImageSource *pImage );
  134. // Loads a resource, returns vector index
  135. bool OnImageLoaded( CFileResource & resource, CImageData *pImage, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
  136. bool OnFailedImageLoad( CFileResource & resource, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
  137. void AddLoad( CFileResource &resource, EImageFormat eFormat, bool bPrioritizeLoad, int32 nResizeWidth, int32 nResizeHeight, bool bAllowAnimation );
  138. // Synchronous load only used for initial global default image
  139. bool LoadLocalFileSynchronous( CFileResource &resource, EImageFormat eFormat, bool bAllowAnimation );
  140. #if defined( SOURCE2_PANORAMA )
  141. bool FixupFileResourceToCompiledImage( CFileResource &fileResource );
  142. #endif
  143. struct UrlImageKey_t
  144. {
  145. CFileResource fileResource;
  146. int32 nTargetWidth;
  147. int32 nTargetHeight;
  148. bool bAllowAnimation;
  149. // Sort on size only
  150. bool operator <( const UrlImageKey_t &l ) const
  151. {
  152. if ( nTargetWidth < l.nTargetWidth )
  153. return true;
  154. else if ( nTargetWidth > l.nTargetWidth )
  155. return false;
  156. if ( nTargetHeight < l.nTargetHeight )
  157. return true;
  158. else if ( nTargetHeight > l.nTargetHeight )
  159. return false;
  160. if ( bAllowAnimation && !l.bAllowAnimation )
  161. return true;
  162. else if ( !bAllowAnimation && l.bAllowAnimation )
  163. return false;
  164. return fileResource < l.fileResource;
  165. }
  166. };
  167. CUtlMap< UrlImageKey_t, CImageProxySource *, int, CDefLess< UrlImageKey_t > > m_mapImagesByURL;
  168. CUtlMap< IImageSource *, UrlImageKey_t, int, CDefLess< IImageSource *> > m_mapAllImages;
  169. CUtlVector< CImageLoaderTask * > m_vecLoaderTasksToStart;
  170. CUtlRBTree< CImageLoaderTask *, int, CDefLess< CImageLoaderTask * > > m_treeLoadTasks;
  171. IUIRenderEngine *m_pSurface;
  172. CImageDecodeWorkThreadPool *m_pImageDecodePool;
  173. bool m_bInited;
  174. };
  175. } // namespace panorama
  176. #endif // IMAGESOURCE_H