mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 14:16:14 +03:00
186 lines
3.7 KiB
C++
186 lines
3.7 KiB
C++
#pragma once
|
|
|
|
#include "Core.h"
|
|
|
|
namespace Flower
|
|
{
|
|
// CPU cache line size, set 64 bytes here.
|
|
constexpr size_t cCPUCacheLineSize = 64;
|
|
|
|
constexpr size_t cFloat32Size = sizeof(float);
|
|
static_assert(cFloat32Size == 4);
|
|
|
|
constexpr size_t cFloat16Size = sizeof(float) / 2;
|
|
static_assert(cFloat16Size == 2);
|
|
|
|
constexpr size_t cFloat64Size = sizeof(double);
|
|
static_assert(cFloat64Size == 8);
|
|
|
|
template<typename T> concept StringStreamable = requires(std::stringstream & ss, const T & value) { ss << value; };
|
|
|
|
// Fast way to get next power of two from v.
|
|
inline uint32_t getNextPOT(uint32_t v)
|
|
{
|
|
v--;
|
|
v |= v >> 1;
|
|
v |= v >> 2;
|
|
v |= v >> 4;
|
|
v |= v >> 8;
|
|
v |= v >> 16;
|
|
v++;
|
|
return v;
|
|
}
|
|
|
|
// halton sequence compute.
|
|
inline float halton(uint64_t index, uint64_t base)
|
|
{
|
|
float f = 1; float r = 0;
|
|
while (index > 0)
|
|
{
|
|
f = f / static_cast<float>(base);
|
|
r = r + f * (index % base);
|
|
index = index / base;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
// halton 2d sequence compute.
|
|
inline glm::vec2 halton2D(uint64_t index, uint64_t baseA, uint64_t baseB)
|
|
{
|
|
return glm::vec2(halton(index, baseA), halton(index, baseB));
|
|
}
|
|
|
|
template <class T> requires StringStreamable<T>
|
|
inline std::string toString(const T& value)
|
|
{
|
|
std::stringstream ss;
|
|
|
|
ss << std::fixed << value;
|
|
return ss.str();
|
|
}
|
|
|
|
inline unsigned char srgbToLinear(unsigned char inSrgb)
|
|
{
|
|
float srgb = inSrgb / 255.0f;
|
|
srgb = glm::max(6.10352e-5f, srgb);
|
|
float lin = srgb > 0.04045f ? glm::pow(srgb * (1.0f / 1.055f) + 0.0521327f, 2.4f) : srgb * (1.0f / 12.92f);
|
|
|
|
return unsigned char(lin * 255.0f);
|
|
}
|
|
|
|
inline unsigned char linearToSrgb(unsigned char inlin)
|
|
{
|
|
float lin = inlin / 255.0f;
|
|
if (lin < 0.00313067f) return unsigned char(lin * 12.92f * 255.0f);
|
|
float srgb = glm::pow(lin, (1.0f / 2.4f)) * 1.055f - 0.055f;
|
|
|
|
return unsigned char(srgb * 255.0f);
|
|
}
|
|
|
|
inline uint32_t getSafeWidthDiv2(uint32_t srcWidth)
|
|
{
|
|
return glm::max(1u, srcWidth / 2);
|
|
}
|
|
|
|
template<typename T> inline T divideRoundingUp(T x, T y)
|
|
{
|
|
return (x + y - (T)1) / y;
|
|
}
|
|
|
|
template<typename T>
|
|
size_t CRCHash(const T& v)
|
|
{
|
|
return CRC::Calculate(&v, sizeof(T), CRC::CRC_32());
|
|
}
|
|
|
|
template<typename T>
|
|
struct CRCHasher
|
|
{
|
|
inline size_t operator()(const T& v) const
|
|
{
|
|
return CRC::Calculate(&v, sizeof(T), CRC::CRC_32());
|
|
}
|
|
};
|
|
|
|
inline size_t hashCombine(size_t lhs, size_t rhs)
|
|
{
|
|
lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2);
|
|
return lhs;
|
|
}
|
|
|
|
inline void sizeSafeCheck(size_t in, size_t max)
|
|
{
|
|
if (in >= max)
|
|
{
|
|
LOG_WARN("Too much element here, exist {0} elements, but only {1} is safe range.", in, max);
|
|
}
|
|
}
|
|
|
|
template<typename T, size_t cLazyFrame>
|
|
class LazyDestroyObject
|
|
{
|
|
private:
|
|
std::mutex m_mutex;
|
|
|
|
size_t m_tickCount = 0;
|
|
std::array<std::unordered_set<std::shared_ptr<T>>, cLazyFrame> m_container;
|
|
|
|
public:
|
|
bool existElement()
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
for (const auto& set : m_container)
|
|
{
|
|
if (!set.empty())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void insert(std::shared_ptr<T> object)
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
m_container[m_tickCount].insert(object);
|
|
}
|
|
|
|
void tick()
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
m_tickCount ++;
|
|
if (m_tickCount >= cLazyFrame)
|
|
{
|
|
m_tickCount = 0;
|
|
}
|
|
|
|
m_container[m_tickCount].clear();
|
|
}
|
|
|
|
void releaseAll()
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
for (auto& container : m_container)
|
|
{
|
|
container.clear();
|
|
}
|
|
}
|
|
|
|
~LazyDestroyObject()
|
|
{
|
|
releaseAll();
|
|
}
|
|
};
|
|
|
|
inline void xorDelta(const void* src, size_t size, void* inout)
|
|
{
|
|
const uint8_t* data = (const uint8_t*)src;
|
|
uint8_t* target = (uint8_t*)inout;
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
{
|
|
target[i] ^= data[i];
|
|
}
|
|
}
|
|
} |