Graphics module Initial (And some more fixes embedded)

This commit is contained in:
IlushaShurupov 2023-07-23 10:51:21 +03:00 committed by Ilya Shurupov
parent 98132ca2f5
commit f52b351cac
23 changed files with 456 additions and 31 deletions

View file

@ -20,7 +20,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Checkout submodules # checkout rest - name: Setup externals
shell: bash shell: bash
run: | run: |
# If your submodules are configured to use SSH instead of HTTPS please uncomment the following line # If your submodules are configured to use SSH instead of HTTPS please uncomment the following line
@ -29,11 +29,15 @@ jobs:
git submodule sync --recursive git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
- name: Install LLVM sudo apt-get install python3 python-is-python3
run: sudo apt-get install -y llvm sudo apt install libx11-dev
cd Externals/glew/
make extensions
- name: Set LLVM Toolchain - name: Set LLVM Toolchain
run: | run: |
sudo apt-get install -y llvm
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 10 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 10
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 20 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 20

12
.gitmodules vendored
View file

@ -1,3 +1,15 @@
[submodule "Externals/asio"] [submodule "Externals/asio"]
path = Externals/asio path = Externals/asio
url = https://github.com/IlyaShurupov/asio.git url = https://github.com/IlyaShurupov/asio.git
[submodule "Externals/glfw"]
path = Externals/glfw
url = https://github.com/IlyaShurupov/glfw.git
[submodule "Externals/imgui"]
path = Externals/imgui
url = https://github.com/IlyaShurupov/imgui.git
[submodule "Externals/glew"]
path = Externals/glew
url = https://github.com/IlyaShurupov/glew.git
[submodule "Externals/nanovg"]
path = Externals/nanovg
url = https://github.com/IlyaShurupov/nanovg.git

View file

@ -22,6 +22,8 @@ HeapAllocGlobal::~HeapAllocGlobal() = default;
tp::MemHead* tp::HeapAllocGlobal::mEntry = nullptr; tp::MemHead* tp::HeapAllocGlobal::mEntry = nullptr;
tp::ualni tp::HeapAllocGlobal::mNumAllocations = 0; tp::ualni tp::HeapAllocGlobal::mNumAllocations = 0;
tp::Mutex tp::HeapAllocGlobal::mMutex;
bool tp::HeapAllocGlobal::mIgnore;
// ----------------------- Debug Implementation ---------------------------- // // ----------------------- Debug Implementation ---------------------------- //
// |----------------| // |----------------|
@ -38,7 +40,8 @@ namespace tp {
struct MemHead { struct MemHead {
MemHead* mPrev; MemHead* mPrev;
MemHead* mNext; MemHead* mNext;
ualni mBlockSize; uhalni mBlockSize;
uhalni mIgnored;
#ifdef MEM_STACK_TRACE #ifdef MEM_STACK_TRACE
const CallStackCapture::CallStack* mCallStack; const CallStackCapture::CallStack* mCallStack;
#endif #endif
@ -69,12 +72,15 @@ void* HeapAllocGlobal::allocate(ualni aBlockSize) {
auto wrap_bottom = data + aBlockSize; auto wrap_bottom = data + aBlockSize;
if (!head) { return nullptr; } if (!head) { return nullptr; }
head->mBlockSize = aBlockSize; head->mBlockSize = aBlockSize;
head->mIgnored = mIgnore;
// 2) Link with existing blocks // 2) Link with existing blocks
mMutex.lock();
mNumAllocations++; mNumAllocations++;
if (mEntry) { if (mEntry) {
DEBUG_ASSERT(!mEntry->mNext) DEBUG_ASSERT(mEntry->mNext == nullptr)
head->mNext = nullptr; head->mNext = nullptr;
head->mPrev = mEntry; head->mPrev = mEntry;
mEntry->mNext = head; mEntry->mNext = head;
@ -84,15 +90,18 @@ void* HeapAllocGlobal::allocate(ualni aBlockSize) {
} }
mEntry = head; mEntry = head;
// 3) Wrap fill
memSetVal(wrap_top, WRAP_SIZE, WRAP_VAL);
memSetVal(wrap_bottom, WRAP_SIZE, WRAP_VAL);
// 4) Trace the stack // 3) Trace the stack
#ifdef MEM_STACK_TRACE #ifdef MEM_STACK_TRACE
head->mCallStack = gCSCapture->getSnapshot(); head->mCallStack = gCSCapture->getSnapshot();
#endif #endif
mMutex.unlock();
// 4) Wrap fill
memSetVal(wrap_top, WRAP_SIZE, WRAP_VAL);
memSetVal(wrap_bottom, WRAP_SIZE, WRAP_VAL);
// 5) clear data // 5) clear data
#ifdef MEM_CLEAR_ON_ALLOC #ifdef MEM_CLEAR_ON_ALLOC
memSetVal(data, aBlockSize, CLEAR_ALLOC_VAL); memSetVal(data, aBlockSize, CLEAR_ALLOC_VAL);
@ -102,6 +111,8 @@ void* HeapAllocGlobal::allocate(ualni aBlockSize) {
} }
void HeapAllocGlobal::deallocate(void* aPtr) { void HeapAllocGlobal::deallocate(void* aPtr) {
if (!aPtr) return;
// 1) Restore the pointers // 1) Restore the pointers
auto head = ((MemHead*)((int1*)aPtr - WRAP_SIZE)) - 1; auto head = ((MemHead*)((int1*)aPtr - WRAP_SIZE)) - 1;
auto wrap_top = (int1*)(head + 1); auto wrap_top = (int1*)(head + 1);
@ -109,6 +120,7 @@ void HeapAllocGlobal::deallocate(void* aPtr) {
auto wrap_bottom = data + head->mBlockSize; auto wrap_bottom = data + head->mBlockSize;
// 2) Unlink with blocks // 2) Unlink with blocks
mMutex.lock();
mNumAllocations--; mNumAllocations--;
DEBUG_ASSERT(!mEntry->mNext) DEBUG_ASSERT(!mEntry->mNext)
if (head->mNext) head->mNext->mPrev = head->mPrev; if (head->mNext) head->mNext->mPrev = head->mPrev;
@ -116,34 +128,42 @@ void HeapAllocGlobal::deallocate(void* aPtr) {
if (head == mEntry) { if (head == mEntry) {
mEntry = head->mPrev; mEntry = head->mPrev;
} }
mMutex.unlock();
// 3) Check the wrap if (!head->mIgnored) {
if (memCompareVal(wrap_top, WRAP_SIZE, WRAP_VAL)) { // 3) Check the wrap
CallStackCapture::printSnapshot(head->mCallStack); if (memCompareVal(wrap_top, WRAP_SIZE, WRAP_VAL)) {
ASSERT(!"Allocated Block Wrap Corrupted!") CallStackCapture::printSnapshot(head->mCallStack);
ASSERT(!"Allocated Block Wrap Corrupted!")
}
if (memCompareVal(wrap_bottom, WRAP_SIZE, WRAP_VAL)) {
CallStackCapture::printSnapshot(head->mCallStack);
ASSERT(!"Allocated Block Wrap Corrupted!")
}
// 4) clear data
#ifdef MEM_CLEAR_ON_ALLOC
memSetVal(data, head->mBlockSize, CLEAR_DEALLOC_VAL);
#endif
} }
if (memCompareVal(wrap_bottom, WRAP_SIZE, WRAP_VAL)) {
CallStackCapture::printSnapshot(head->mCallStack);
ASSERT(!"Allocated Block Wrap Corrupted!")
}
// 4) clear data
#ifdef MEM_CLEAR_ON_ALLOC
memSetVal(data, head->mBlockSize, CLEAR_DEALLOC_VAL);
#endif
// 5) free the block // 5) free the block
free(head); free(head);
} }
bool HeapAllocGlobal::checkLeaks() { bool HeapAllocGlobal::checkLeaks() {
ualni ignoredCount = 0;
for (auto iter = mEntry; iter; iter = iter->mPrev) {
ignoredCount += iter->mIgnored;
}
// 1) Check for not deallocated memory // 1) Check for not deallocated memory
if (mNumAllocations) { if (mNumAllocations && ignoredCount != mNumAllocations) {
#ifdef MEM_STACK_TRACE #ifdef MEM_STACK_TRACE
for (auto iter = mEntry; iter; iter = iter->mPrev) { for (auto iter = mEntry; iter; iter = iter->mPrev) {
CallStackCapture::printSnapshot(iter->mCallStack); if (!iter->mIgnored) CallStackCapture::printSnapshot(iter->mCallStack);
} }
#endif #endif
@ -153,6 +173,18 @@ bool HeapAllocGlobal::checkLeaks() {
return false; return false;
} }
void HeapAllocGlobal::startIgnore() {
mMutex.lock();
mIgnore = true;
mMutex.unlock();
}
void HeapAllocGlobal::stopIgnore() {
mMutex.lock();
mIgnore = false;
mMutex.unlock();
}
HeapAllocGlobal::~HeapAllocGlobal() = default; HeapAllocGlobal::~HeapAllocGlobal() = default;
#endif #endif

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Module.hpp" #include "Module.hpp"
#include "Multithreading.hpp"
namespace tp { namespace tp {
@ -9,6 +10,8 @@ namespace tp {
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
static ualni mNumAllocations; static ualni mNumAllocations;
static struct MemHead* mEntry; static struct MemHead* mEntry;
static Mutex mMutex;
static bool mIgnore;
#endif #endif
public: public:
@ -20,6 +23,9 @@ namespace tp {
static void deallocate(void* aPtr); static void deallocate(void* aPtr);
static bool checkLeaks(); static bool checkLeaks();
static void startIgnore();
static void stopIgnore();
public: public:
[[nodiscard]] bool checkWrap() const { return false; } [[nodiscard]] bool checkWrap() const { return false; }
void checkValid() {} void checkValid() {}

View file

@ -18,4 +18,9 @@ add_subdirectory(Allocators)
add_subdirectory(Strings) add_subdirectory(Strings)
add_subdirectory(Tokenizer) add_subdirectory(Tokenizer)
add_subdirectory(CommandLine) add_subdirectory(CommandLine)
set(EXTERNALS ../Externals)
add_subdirectory(Externals)
add_subdirectory(Connection) add_subdirectory(Connection)
add_subdirectory(Graphics)

View file

@ -1,6 +1,5 @@
#include "Tests.hpp" #include "Tests.hpp"
#include "Testing.hpp"
int main() { int main() {

28
Externals/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,28 @@
add_subdirectory(glew/build/cmake/)
target_compile_definitions(glew_s PUBLIC GLEW_NO_GLU)
add_subdirectory(glfw)
project(Imgui)
set(${PROJECT_NAME}_SOURCES
imgui/imgui.cpp
imgui/imgui_draw.cpp
imgui/imgui_tables.cpp
imgui/imgui_widgets.cpp
imgui/backends/imgui_impl_glfw.cpp
imgui/backends/imgui_impl_opengl3.cpp
)
add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_SOURCES})
include_directories(${PROJECT_NAME} ./glfw/include)
target_include_directories(${PROJECT_NAME} PUBLIC ./imgui/ ./imgui/backends/)
project(Nanovg)
set(${PROJECT_NAME}_SOURCES
nanovg/src/nanovg.c
)
add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ./nanovg/src/ ./nanovg/obsolete/)

1
Externals/glew vendored Submodule

@ -0,0 +1 @@
Subproject commit a98195b83df746202bdf5a6f92e9d4e86b497045

1
Externals/glfw vendored Submodule

@ -0,0 +1 @@
Subproject commit 3eaf1255b29fdf5c2895856c7be7d7185ef2b241

1
Externals/imgui vendored Submodule

@ -0,0 +1 @@
Subproject commit 1109de38277fd2d14d4dca4c1cb8d4a2c4ff0f95

1
Externals/nanovg vendored Submodule

@ -0,0 +1 @@
Subproject commit 7544c114e83db7cf67bd1c9e012349b70caacc2f

34
Graphics/CMakeLists.txt Normal file
View file

@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.2)
set(CMAKE_CXX_STANDARD 23)
project(Graphics)
### ---------------------- Externals --------------------- ###
set(BINDINGS_INCLUDE ${EXTERNALS}/glfw/include ${EXTERNALS}/glew/include)
set(BINDINGS_LIBS glfw glew_s Imgui Nanovg)
### ---------------------- Static Library --------------------- ###
file(GLOB SOURCES "./private/*.cpp" "./private/*/*.cpp")
file(GLOB HEADERS "./public/*.hpp")
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
target_include_directories(${PROJECT_NAME} PRIVATE ${BINDINGS_INCLUDE})
target_link_libraries(${PROJECT_NAME} PUBLIC Strings)
target_link_libraries(${PROJECT_NAME} PRIVATE ${BINDINGS_LIBS})
### -------------------------- Examples -------------------------- ###
add_executable(${PROJECT_NAME}Example ./examples/Example.cpp)
target_link_libraries(${PROJECT_NAME}Example ${PROJECT_NAME} ${BINDINGS_LIBS})
target_include_directories(${PROJECT_NAME}Example PRIVATE ${BINDINGS_INCLUDE})
### -------------------------- Tests -------------------------- ###
enable_testing()
file(GLOB TEST_SOURCES "./tests/*.cpp")
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/lib)

View file

@ -0,0 +1,274 @@
#include "Allocators.hpp"
// -------- OpenGL -------- //
#include <GL/glew.h>
// -------- Window Context -------- //
#include <GLFW/glfw3.h>
// -------- Debug UI -------- //
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
// -------- Canvas -------- //
#define NANOVG_GL3_IMPLEMENTATION
//#include <nanovg.h>
//#include <nanovg_gl.h>
#include <cstdio>
class Showoff {
class GL {
// Showoff data
GLuint vao{};
GLuint vbo{};
GLfloat vertices[9] = {
-0.5f, -0.5f, 0.0f, // Left vertex
0.5f, -0.5f, 0.0f, // Right vertex
0.0f, 0.5f, 0.0f // Top vertex
};
public:
GL() = default;
void init() {
// Create a Vertex Array Object (VAO)
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object (VBO)
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Set up vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*) nullptr);
glEnableVertexAttribArray(0);
}
void deinit() {
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}
static void beginDraw() {
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
static void endDraw() {
}
};
class GUI {
ImGuiIO* io{};
ImGuiContext* ctx{};
public:
GUI() = default;
void init(GLFWwindow* window) {
IMGUI_CHECKVERSION();
ctx = ImGui::CreateContext();
io = &ImGui::GetIO();
// Initialize ImGui with GLFW and OpenGL
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
}
void deinit() {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void beginDraw() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// ImGui code goes here
ImGui::Begin("Window");
ImGui::End();
}
void endDraw() {
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
};
/*
class Canvas {
NVGcontext* vg;
float width;
float height;
public:
Canvas() = default;
void init(int aWidth, int aHeight) {
width = aWidth;
height = aHeight;
vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
}
void deinit() {
// Cleanup
nvgDeleteGL3(vg);
}
void beginDraw() {
// Start NanoVG rendering
nvgBeginFrame(vg, width, height, 1.0);
// Clear the screen
nvgBeginPath(vg);
nvgRect(vg, 0, 0, width, height);
nvgFillColor(vg, nvgRGBf(0.2f, 0.2f, 0.2f));
nvgFill(vg);
// Draw a rectangle
nvgBeginPath(vg);
nvgRect(vg, 200, 200, 300, 200);
nvgFillColor(vg, nvgRGBf(0.8f, 0.4f, 0.1f));
nvgFill(vg);
// End NanoVG rendering
nvgEndFrame(vg);
}
void endDraw() {
// End NanoVG rendering
nvgEndFrame(vg);
}
};
*/
public:
Showoff() = default;
void init(GLFWwindow* window, int aWidth, int aHeight) {
gui.init(window);
gl.init();
// canvas.init(aWidth, aHeight);
}
void deinit() {
gui.deinit();
gl.deinit();
// canvas.deinit();
}
void draw() {
gl.beginDraw();
// canvas.beginDraw();
gui.beginDraw();
gui.endDraw();
// canvas.endDraw();
gl.endDraw();
}
private:
GUI gui{};
GL gl{};
// Canvas canvas{};
};
class Window {
Window(int width, int height, const char* title) {
// Create a window and OpenGL context
window = glfwCreateWindow(width, height, title, nullptr, nullptr);
if (!window) {
printf("Failed to create GLFW window\n");
return;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
if (glewInit() != GLEW_OK) {
printf("Failed to initialize GLEW\n");
return;
}
showoff.init(window, width, height);
}
~Window() {
showoff.deinit();
glfwDestroyWindow(window);
}
public:
static Window* createWindow(int width, int height, const char* title) {
static int count = 1;
if (!count) {
printf("Window class is a singleton\n");
return nullptr;
}
count--;
// Initialize GLFW
if (!glfwInit()) {
printf("Failed to initialize GLFW\n");
return nullptr;
}
// Set the GLFW error callback
glfwSetErrorCallback([] (int error, const char* description) {
printf("GLFW Error: %i %s\n", error, description);
});
return new Window(width, height, title);
}
static void destroyWindow(Window* window) {
delete window;
glfwTerminate();
}
public:
void renderLoop() {
while (!glfwWindowShouldClose(window)) {
showoff.draw();
// Swap buffers and poll events
glfwSwapBuffers(window);
glfwPollEvents();
}
}
private:
GLFWwindow* window;
Showoff showoff;
};
int main() {
tp::ModuleManifest* deps[] = { &tp::gModuleAllocators, nullptr };
tp::ModuleManifest testModule("Example", nullptr, nullptr, deps);
if (!testModule.initialize()) {
return 1;
}
{
//tp::HeapAllocGlobal::startIgnore();
auto window = Window::createWindow(800, 600, "Window 1");
//tp::HeapAllocGlobal::stopIgnore();
if (window) {
window->renderLoop();
}
Window::destroyWindow(window);
}
testModule.deinitialize();
}

View file

View file

View file

View file

@ -0,0 +1,8 @@
//
// Created by ilusha on 22.07.23.
//
#ifndef TYPES_WINDOW_HPP
#define TYPES_WINDOW_HPP
#endif//TYPES_WINDOW_HPP

3
Graphics/tests/tests.cpp Normal file
View file

@ -0,0 +1,3 @@
int main() {
}

View file

@ -1,6 +1,5 @@
#include "Logging.hpp" #include "Logging.hpp"
#include "Allocators.hpp"
#include <cstdio> #include <cstdio>

View file

@ -222,7 +222,6 @@ namespace tp {
// all NFA states that are reachable from initial DFA State for specific symbol in alphabet // all NFA states that are reachable from initial DFA State for specific symbol in alphabet
struct DState { struct DState {
struct DTransition { struct DTransition {
DState* state = nullptr; DState* state = nullptr;
tAlphabetType accepting_code; tAlphabetType accepting_code;
@ -231,7 +230,7 @@ namespace tp {
List<NState*> nStates; List<NState*> nStates;
List<DTransition> transitions; List<DTransition> transitions;
Vertex* dVertex = nullptr; // relevant DFA vertex Vertex* dVertex= nullptr; // relevant DFA vertex
#ifdef ENV_BUILD_DEBUG #ifdef ENV_BUILD_DEBUG
ualni debug_idx = 0; ualni debug_idx = 0;

View file

@ -1,4 +1,3 @@
#include "Testing.hpp" #include "Testing.hpp"
#include "Tokenizer.hpp" #include "Tokenizer.hpp"
#include <cstdio> #include <cstdio>

View file

@ -3,7 +3,7 @@
#include "Environment.hpp" #include "Environment.hpp"
#include "Map.hpp" #include "Map.hpp"
#define MAX_CALL_DEPTH_CAPTURE 16 #define MAX_CALL_DEPTH_CAPTURE 128
#define MAX_CALL_CAPTURES_MEM_SIZE_MB 16 #define MAX_CALL_CAPTURES_MEM_SIZE_MB 16
#define MAX_DEBUG_INFO_LEN 63 #define MAX_DEBUG_INFO_LEN 63
#define FRAMES_TO_SKIP_START 2 #define FRAMES_TO_SKIP_START 2

View file

@ -0,0 +1,19 @@
#pragma once
#include <pthread.h>
namespace tp {
class Mutex {
pthread_mutex_t mMutex {};
public:
Mutex() = default;
void lock() {
pthread_mutex_lock(&mMutex);
}
void unlock() {
pthread_mutex_unlock(&mMutex);
}
};
}