Surface.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Core/Reference.h>
  6. #include <Jolt/Core/Color.h>
  7. #include <Jolt/Core/StringTools.h>
  8. /// Possible lock modes of a Surface
  9. enum class ESurfaceLockMode : uint
  10. {
  11. None = 0 << 0, ///< Not locked, cannot be used as a parameter
  12. Read = 1 << 0,
  13. Write = 2 << 0,
  14. ReadWrite = Read | Write,
  15. };
  16. /// Possible surface formats, most significant bit (MSB) first
  17. enum class ESurfaceFormat : uint
  18. {
  19. A4L4, ///< 4 bit alpha, 4 bit luminance (grayscale)
  20. L8, ///< 8 bit luminance (grayscale)
  21. A8, ///< 8 bit alpha
  22. A8L8, ///< 8 bit luminance and 8 bit alpha
  23. R5G6B5, ///< 16 bit RGB
  24. X1R5G5B5, ///< 16 bit RGB
  25. X4R4G4B4, ///< 16 bit RGB
  26. A1R5G5B5, ///< 16 bit RGBA
  27. A4R4G4B4, ///< 16 bit RGBA
  28. R8G8B8, ///< 24 bit RGB
  29. B8G8R8, ///< 24 bit BGR
  30. X8R8G8B8, ///< 32 bit RGB
  31. X8B8G8R8, ///< 32 bit RGB
  32. A8R8G8B8, ///< 32 bit RGBA
  33. A8B8G8R8, ///< 32 bit BGRA
  34. Invalid, ///< Invalid value
  35. Count = Invalid, ///< Number of pixel formats
  36. };
  37. /// Description of a surface format
  38. class FormatDescription
  39. {
  40. public:
  41. /// Constructor
  42. FormatDescription(const char *inFormatName, int inBitsPerPixel, int inNumberOfComponents, ESurfaceFormat inClosest8BitFormat, ESurfaceFormat inClosestAlphaFormat, uint32 inRedMask, uint32 inGreenMask, uint32 inBlueMask, uint32 inAlphaMask);
  43. /// General properties
  44. const string_view & GetFormatName() const { return mFormatName; }
  45. int GetBytesPerPixel() const { return (mBitsPerPixel + 7) >> 3; }
  46. int GetNumberOfComponents() const { return mNumberOfComponents; }
  47. ESurfaceFormat GetClosest8BitFormat() const { return mClosest8BitFormat; }
  48. ESurfaceFormat GetClosestAlphaFormat() const { return mClosestAlphaFormat; }
  49. /// Bitcounts for the various components of the image
  50. int GetBitsPerPixel() const { return mBitsPerPixel; }
  51. int GetRedBitsPerPixel() const { return CountBits(mRedMask); }
  52. int GetGreenBitsPerPixel() const { return CountBits(mGreenMask); }
  53. int GetBlueBitsPerPixel() const { return CountBits(mBlueMask); }
  54. int GetAlphaBitsPerPixel() const { return CountBits(mAlphaMask); }
  55. int GetComponentBitCount(int inComponent) const { return CountBits(GetComponentMask(inComponent)); }
  56. /// Bitmasks indicating the various components of the image
  57. uint32 GetRedMask() const { return mRedMask; }
  58. uint32 GetGreenMask() const { return mGreenMask; }
  59. uint32 GetBlueMask() const { return mBlueMask; }
  60. uint32 GetAlphaMask() const { return mAlphaMask; }
  61. uint32 GetComponentMask(int inComponent) const { return *(&mRedMask + inComponent); }
  62. /// Convert a single color
  63. uint32 Encode(ColorArg inColor) const;
  64. const Color Decode(uint32 inColor) const;
  65. private:
  66. string_view mFormatName; ///< User displayable String describing the format
  67. int mBitsPerPixel; ///< Number of bits per pixel
  68. int mNumberOfComponents; ///< Number of color components per pixel
  69. ESurfaceFormat mClosest8BitFormat; ///< Closest matching format that has 8 bit color components
  70. ESurfaceFormat mClosestAlphaFormat; ///< Closest matching format that has an alpha channel
  71. uint32 mRedMask; ///< Bitmasks indicating which bits are used by which color components
  72. uint32 mGreenMask;
  73. uint32 mBlueMask;
  74. uint32 mAlphaMask;
  75. };
  76. /// Get the description for a specific surface format
  77. const FormatDescription & GetFormatDescription(ESurfaceFormat inFormat);
  78. /// Class that contains an image in arbitrary format
  79. class Surface : public RefTarget<Surface>
  80. {
  81. public:
  82. /// Constructor
  83. Surface(int inWidth, int inHeight, ESurfaceFormat inFormat);
  84. virtual ~Surface();
  85. /// Type of the image data
  86. const FormatDescription & GetFormatDescription() const { return ::GetFormatDescription(mFormat); }
  87. const string_view & GetFormatName() const { return GetFormatDescription().GetFormatName(); }
  88. int GetBytesPerPixel() const { return GetFormatDescription().GetBytesPerPixel(); }
  89. int GetNumberOfComponents() const { return GetFormatDescription().GetNumberOfComponents(); }
  90. ESurfaceFormat GetClosest8BitFormat() const { return GetFormatDescription().GetClosest8BitFormat(); }
  91. int GetBitsPerPixel() const { return GetFormatDescription().GetBitsPerPixel(); }
  92. int GetRedBitsPerPixel() const { return GetFormatDescription().GetRedBitsPerPixel(); }
  93. int GetGreenBitsPerPixel() const { return GetFormatDescription().GetGreenBitsPerPixel(); }
  94. int GetBlueBitsPerPixel() const { return GetFormatDescription().GetBlueBitsPerPixel(); }
  95. int GetAlphaBitsPerPixel() const { return GetFormatDescription().GetAlphaBitsPerPixel(); }
  96. int GetComponentBitCount(int inComponent) const { return GetFormatDescription().GetComponentBitCount(inComponent); }
  97. uint32 GetRedMask() const { return GetFormatDescription().GetRedMask(); }
  98. uint32 GetGreenMask() const { return GetFormatDescription().GetGreenMask(); }
  99. uint32 GetBlueMask() const { return GetFormatDescription().GetBlueMask(); }
  100. uint32 GetAlphaMask() const { return GetFormatDescription().GetAlphaMask(); }
  101. uint32 GetComponentMask(int inComponent) const { return GetFormatDescription().GetComponentMask(inComponent); }
  102. /// Get properties of this surface
  103. inline ESurfaceFormat GetFormat() const { return mFormat; }
  104. inline int GetWidth() const { return mWidth; }
  105. inline int GetHeight() const { return mHeight; }
  106. /// Sets the image to a specific color
  107. void Clear(ColorArg inColor = Color::sBlack);
  108. /// Locking functions
  109. void Lock(ESurfaceLockMode inMode) const;
  110. void UnLock() const;
  111. /// Current lock state
  112. inline ESurfaceLockMode GetLockMode() const { return mLockMode; }
  113. inline bool IsLocked() const { return mLockMode != ESurfaceLockMode::None; }
  114. inline bool IsLockedForRead() const { return (uint(mLockMode) & uint(ESurfaceLockMode::Read)) != 0; }
  115. inline bool IsLockedForWrite() const { return (uint(mLockMode) & uint(ESurfaceLockMode::Write)) != 0; }
  116. inline bool IsLockedForReadWrite() const { return IsLockedForRead() && IsLockedForWrite(); }
  117. /// Access to the image data
  118. inline const uint8 * GetData() const { JPH_ASSERT(IsLockedForRead()); return mData; }
  119. inline uint8 * GetData() { JPH_ASSERT(IsLockedForWrite()); return mData; }
  120. inline int GetStride() const { JPH_ASSERT(IsLocked()); return mStride; }
  121. inline int GetLength() const { JPH_ASSERT(IsLocked()); return mLength; }
  122. /// Get start of a specific scanline
  123. inline const uint8 * GetScanLine(int inScanLine) const { JPH_ASSERT(inScanLine >= 0 && inScanLine < GetHeight()); return GetData() + inScanLine * GetStride(); }
  124. inline uint8 * GetScanLine(int inScanLine) { JPH_ASSERT(inScanLine >= 0 && inScanLine < GetHeight()); return GetData() + inScanLine * GetStride(); }
  125. protected:
  126. /// These functions must be overridden by the hardware buffer
  127. virtual void HardwareLock() const = 0;
  128. virtual void HardwareUnLock() const = 0;
  129. /// Data
  130. ESurfaceFormat mFormat; ///< Pixel format of the surface
  131. int mWidth; ///< Width of the image
  132. int mHeight; ///< Height of the image
  133. mutable int mLength; ///< Length in bytes of the image
  134. mutable ESurfaceLockMode mLockMode;
  135. mutable int mStride; ///< Width of one scanline in bytes
  136. mutable uint8 * mData; ///< Pointer to image data, starting at top-left of locked rectangle
  137. };
  138. /// Class that contains an image in arbitrary format, backed by normal memory (not device specific)
  139. class SoftwareSurface : public Surface
  140. {
  141. public:
  142. /// Constructor
  143. SoftwareSurface(int inWidth, int inHeight, ESurfaceFormat inFormat, int inStride = 0);
  144. virtual ~SoftwareSurface() override;
  145. protected:
  146. /// These functions must be overridden by the hardware buffer
  147. virtual void HardwareLock() const override;
  148. virtual void HardwareUnLock() const override;
  149. uint8 * mPixelData;
  150. int mPixelStride;
  151. int mPixelLength;
  152. };