Skip to content

Commit 49ebda1

Browse files
author
Pier-Olivier Boulianne
committed
WIP: fix issues, and starting to add linux support
1 parent 3ab1b8d commit 49ebda1

19 files changed

Lines changed: 752 additions & 281 deletions
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#include "lpch.h"
2+
#include "Lux/Utilities/FileSystem.h"
3+
#include "Lux/Asset/AssetManager.h"
4+
5+
#include "Lux/Core/Application.h"
6+
7+
#include <GLFW/glfw3.h>
8+
9+
#include <sys/inotify.h>
10+
#include <pthread.h>
11+
#include <signal.h>
12+
#include <unistd.h>
13+
#include <errno.h>
14+
15+
#include <filesystem>
16+
#include <thread>
17+
18+
namespace Lux {
19+
20+
static std::filesystem::path s_PersistentStoragePath;
21+
22+
FileStatus FileSystem::TryOpenFile(const std::filesystem::path& filepath)
23+
{
24+
int res = access(filepath.c_str(), F_OK);
25+
26+
if (!res) return FileStatus::Success;
27+
28+
switch (errno) {
29+
default: return FileStatus::OtherError;
30+
31+
case ENOENT: [[fallthrough]];
32+
case ENOTDIR: return FileStatus::Invalid;
33+
34+
case EPERM: [[fallthrough]];
35+
case EACCES: return FileStatus::Locked;
36+
}
37+
}
38+
39+
bool FileSystem::WriteBytes(const std::filesystem::path& filepath, const Buffer& buffer)
40+
{
41+
std::ofstream stream(filepath, std::ios::binary | std::ios::trunc);
42+
43+
if (!stream)
44+
{
45+
stream.close();
46+
return false;
47+
}
48+
49+
stream.write((char*)buffer.Data, buffer.Size);
50+
stream.close();
51+
52+
return true;
53+
}
54+
55+
Buffer FileSystem::ReadBytes(const std::filesystem::path& filepath)
56+
{
57+
Buffer buffer;
58+
59+
std::ifstream stream(filepath, std::ios::binary | std::ios::ate);
60+
LUX_CORE_ASSERT(stream);
61+
62+
auto end = stream.tellg();
63+
stream.seekg(0, std::ios::beg);
64+
auto size = end - stream.tellg();
65+
LUX_CORE_ASSERT(size != 0);
66+
67+
buffer.Allocate((uint32_t)size);
68+
stream.read((char*)buffer.Data, buffer.Size);
69+
stream.close();
70+
71+
return buffer;
72+
}
73+
74+
std::filesystem::path FileSystem::GetPersistentStoragePath()
75+
{
76+
if (!s_PersistentStoragePath.empty())
77+
return s_PersistentStoragePath;
78+
79+
s_PersistentStoragePath = HasEnvironmentVariable("HAZEL_DIR") ? GetEnvironmentVariable("HAZEL_DIR") : "..";
80+
s_PersistentStoragePath /= "Hazelnut";
81+
82+
if (!std::filesystem::exists(s_PersistentStoragePath))
83+
std::filesystem::create_directory(s_PersistentStoragePath);
84+
85+
return s_PersistentStoragePath;
86+
}
87+
88+
bool FileSystem::HasEnvironmentVariable(const std::string& key)
89+
{
90+
return !GetEnvironmentVariable(key).empty();
91+
}
92+
93+
bool FileSystem::SetEnvironmentVariable(const std::string& key, const std::string& value)
94+
{
95+
// NOTE(Emily): This looks horrible but the provided string *becomes* the environment for `putenv`
96+
// TODO(Emily): Persistent environment variables
97+
putenv((new std::string(std::format("{}={}", key, value)))->data());
98+
return true;
99+
}
100+
101+
std::string FileSystem::GetEnvironmentVariable(const std::string& key)
102+
{
103+
const char* value = getenv(key.c_str());
104+
if (value)
105+
return std::string(value);
106+
else
107+
return {};
108+
}
109+
110+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include "lpch.h"
2+
#include "Lux/Core/RenderThread.h"
3+
4+
#include "Lux/Renderer/Renderer.h"
5+
6+
#include <condition_variable>
7+
#include <mutex>
8+
9+
namespace Lux {
10+
11+
struct RenderThreadData
12+
{
13+
std::mutex m_CriticalSection;
14+
std::condition_variable m_ConditionVariable;
15+
16+
RenderThread::State m_State = RenderThread::State::Idle;
17+
};
18+
19+
static std::thread::id s_RenderThreadID;
20+
21+
RenderThread::RenderThread(ThreadingPolicy coreThreadingPolicy)
22+
: m_RenderThread("Render Thread"), m_ThreadingPolicy(coreThreadingPolicy)
23+
{
24+
m_Data = new RenderThreadData();
25+
}
26+
27+
RenderThread::~RenderThread()
28+
{
29+
delete m_Data;
30+
s_RenderThreadID = std::thread::id();
31+
}
32+
33+
void RenderThread::Run()
34+
{
35+
m_IsRunning = true;
36+
if (m_ThreadingPolicy == ThreadingPolicy::MultiThreaded)
37+
m_RenderThread.Dispatch(Renderer::RenderThreadFunc, this);
38+
39+
s_RenderThreadID = m_RenderThread.GetID();
40+
}
41+
42+
void RenderThread::Terminate()
43+
{
44+
m_IsRunning = false;
45+
Pump();
46+
47+
if (m_ThreadingPolicy == ThreadingPolicy::MultiThreaded)
48+
m_RenderThread.Join();
49+
50+
s_RenderThreadID = std::thread::id();
51+
}
52+
53+
void RenderThread::Wait(State waitForState)
54+
{
55+
if (m_ThreadingPolicy == ThreadingPolicy::SingleThreaded)
56+
return;
57+
58+
std::unique_lock lock(m_Data->m_CriticalSection);
59+
while (m_Data->m_State != waitForState)
60+
{
61+
m_Data->m_ConditionVariable.wait(lock);
62+
}
63+
}
64+
65+
void RenderThread::WaitAndSet(State waitForState, State setToState)
66+
{
67+
if (m_ThreadingPolicy == ThreadingPolicy::SingleThreaded)
68+
return;
69+
70+
std::unique_lock lock(m_Data->m_CriticalSection);
71+
while (m_Data->m_State != waitForState)
72+
{
73+
m_Data->m_ConditionVariable.wait(lock);
74+
}
75+
m_Data->m_State = setToState;
76+
m_Data->m_ConditionVariable.notify_all();
77+
}
78+
79+
void RenderThread::Set(State setToState)
80+
{
81+
if (m_ThreadingPolicy == ThreadingPolicy::SingleThreaded)
82+
return;
83+
84+
std::unique_lock lock(m_Data->m_CriticalSection);
85+
m_Data->m_State = setToState;
86+
m_Data->m_ConditionVariable.notify_all();
87+
}
88+
89+
void RenderThread::NextFrame()
90+
{
91+
m_AppThreadFrame++;
92+
Renderer::SwapQueues();
93+
}
94+
95+
void RenderThread::BlockUntilRenderComplete()
96+
{
97+
if (m_ThreadingPolicy == ThreadingPolicy::SingleThreaded)
98+
return;
99+
100+
Wait(State::Idle);
101+
}
102+
103+
void RenderThread::Kick()
104+
{
105+
if (m_ThreadingPolicy == ThreadingPolicy::MultiThreaded)
106+
{
107+
Set(State::Kick);
108+
}
109+
else
110+
{
111+
Renderer::WaitAndRender(this);
112+
}
113+
}
114+
115+
void RenderThread::Pump()
116+
{
117+
NextFrame();
118+
Kick();
119+
BlockUntilRenderComplete();
120+
}
121+
122+
bool RenderThread::IsCurrentThreadRT()
123+
{
124+
// NOTE(Yan): for debugging
125+
// HZ_CORE_VERIFY(s_RenderThreadID != std::thread::id());
126+
return s_RenderThreadID == std::this_thread::get_id();
127+
}
128+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "lpch.h"
2+
#include "Lux/Core/Thread.h"
3+
4+
#include <pthread.h>
5+
6+
namespace Lux {
7+
8+
Thread::Thread(const std::string& name)
9+
: m_Name(name)
10+
{
11+
}
12+
13+
void Thread::SetName(const std::string& name)
14+
{
15+
pthread_setname_np(m_Thread.native_handle(), name.c_str());
16+
}
17+
18+
void Thread::Join()
19+
{
20+
m_Thread.join();
21+
}
22+
23+
// TODO(Emily): `ThreadSignal`
24+
25+
std::thread::id Thread::GetID() const
26+
{
27+
return m_Thread.get_id();
28+
}
29+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.

Core/Source/Lux/Asset/AssetImporter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Lux {
1111

1212
using AssetImportFunction = std::function<Ref<Asset>(AssetHandle, const AssetMetadata&)>;
1313
static std::map<AssetType, AssetImportFunction> s_AssetImportFunctions = {
14+
{AssetType::Texture, TextureImporter::ImportTexture },
1415
{ AssetType::Scene, SceneImporter::ImportScene },
1516
{ AssetType::Audio, AudioImporter::ImportAudio },/*
1617
{ AssetType::ObjModel, ObjModelImporter::ImportObjModel },

Core/Source/Lux/Asset/TextureImporter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
#include <iostream>
1010

1111
namespace Lux {
12+
Ref<Texture2D> TextureImporter::ImportTexture(AssetHandle handle, const AssetMetadata& metadata)
13+
{
14+
LUX_PROFILE_FUNCTION("TextureImporter::ImportTexture");
1215

16+
return LoadTexture2D(metadata.FilePath);
17+
}
1318
Ref<Texture2D> TextureImporter::LoadTexture2D(const std::filesystem::path& path, bool srgb)
1419
{
1520
TextureSpecification spec;

Core/Source/Lux/Asset/TextureImporter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include "AssetMetadata.h"
4+
35
#include "Lux/Renderer/Texture.h"
46

57
#include <filesystem>
@@ -9,6 +11,8 @@ namespace Lux {
911
class TextureImporter
1012
{
1113
public:
14+
static Ref<Texture2D> ImportTexture(AssetHandle handle, const AssetMetadata& metadata);
15+
1216
static Ref<Texture2D> LoadTexture2D(const std::filesystem::path& path, bool srgb = true);
1317
static Buffer ToBufferFromFile(const std::filesystem::path& path, ImageFormat& outFormat, uint32_t& outWidth, uint32_t& outHeight);
1418
static Buffer ToBufferFromMemory(Buffer buffer, ImageFormat& outFormat, uint32_t& outWidth, uint32_t& outHeight);

Core/Source/Lux/Renderer/DeviceManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ const DeviceCreationParameters& DeviceManager::GetDeviceParams()
307307

308308
void DeviceManager::WindowPosCallback(int x, int y)
309309
{
310-
#ifdef _WINDOWS
310+
#if defined(LUX_PLATFORM_WINDOWS)
311311
if (m_DeviceParams.enablePerMonitorDPI)
312312
{
313313
HWND hwnd = glfwGetWin32Window(m_Window);

0 commit comments

Comments
 (0)