diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index 46cfee8b5d..b1f9b704ce 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -646,6 +646,16 @@ int FEngine::loop() { uint32_t id = std::thread::hardware_concurrency() - 1; while (true) { +#if FILAMENT_ENABLE_FGDBG + // TODO (@feresr): Only for testing purposes, remove + if (debug.fgdbg) { + static int fgdbgMessage = 0; + fgdbgMessage++; + if (fgdbgMessage % 100 == 0) { + debug.fgdbg->sendMessage(fgdbgMessage/100); + } + } +#endif // looks like thread affinity needs to be reset regularly (on Android) JobSystem::setThreadAffinityById(id); if (!execute()) { diff --git a/libs/fgdbg/CMakeLists.txt b/libs/fgdbg/CMakeLists.txt index 40def9101b..28ca017fd9 100644 --- a/libs/fgdbg/CMakeLists.txt +++ b/libs/fgdbg/CMakeLists.txt @@ -17,6 +17,6 @@ set(SRCS src/DebugServer.cpp) # ================================================================================================== add_library(${TARGET} STATIC ${PUBLIC_HDRS} ${SRCS}) -target_link_libraries(${TARGET} PUBLIC utils) +target_link_libraries(${TARGET} PUBLIC civetweb utils) target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR}) include_directories(${PUBLIC_HDR_DIR}) diff --git a/libs/fgdbg/include/fgdbg/DebugServer.h b/libs/fgdbg/include/fgdbg/DebugServer.h index b64fe38c28..cdc2c16605 100644 --- a/libs/fgdbg/include/fgdbg/DebugServer.h +++ b/libs/fgdbg/include/fgdbg/DebugServer.h @@ -17,15 +17,26 @@ #ifndef FGDBG_DEBUGSERVER_H #define FGDBG_DEBUGSERVER_H -namespace filament { -namespace fgdbg { +class CivetServer; + +namespace filament::fgdbg { class DebugServer { public: DebugServer(); ~DebugServer(); + + void sendMessage(int number); + +private: + CivetServer* mServer; + + class RestRequestHandler *mRestRequestHandler = nullptr; + class WebSocketHandler* mWebSocketHandler = nullptr; + + friend class RestRequestHandler; + friend class WebSocketHandler; }; } -} #endif // FGDBG_DEBUGSERVER_H diff --git a/libs/fgdbg/src/DebugServer.cpp b/libs/fgdbg/src/DebugServer.cpp index dd6f200d4c..3f6d6c8ac5 100644 --- a/libs/fgdbg/src/DebugServer.cpp +++ b/libs/fgdbg/src/DebugServer.cpp @@ -15,16 +15,96 @@ */ #include "fgdbg/DebugServer.h" +#include #include +#include + +namespace filament::fgdbg { using namespace utils; -namespace filament::fgdbg { + +static const std::string_view kSuccessHeader = + "HTTP/1.1 200 OK\r\nContent-Type: %s\r\n" + "Connection: close\r\n\r\n"; + +class RestRequestHandler : public CivetHandler { + +public: + RestRequestHandler() = default; + + bool handleGet(CivetServer *server, struct mg_connection *conn) override { + mg_printf(conn, kSuccessHeader.data(), "application/json"); + mg_printf(conn, "{ RestRequestHandler is working! }"); + return true; + } +}; + +class WebSocketHandler : public CivetWebSocketHandler { + +public: + WebSocketHandler() = default; + + bool handleConnection(CivetServer *server, const struct mg_connection *conn) override { + return true; + } + + void handleReadyState(CivetServer *server, struct mg_connection *conn) override { + mConnections.insert(conn); + } + + void handleClose(CivetServer *server, const struct mg_connection *conn) override { + auto *key = const_cast(conn); + mConnections.erase(key); + } + + void send(int number) { + auto string = std::to_string(number); + for (auto connection : mConnections) { + mg_websocket_write(connection, + MG_WEBSOCKET_OPCODE_TEXT, + string.c_str(), + string.length()); + } + } + +private: + tsl::robin_set mConnections; +}; DebugServer::DebugServer() { slog.d << "FrameGraph debug server created" << io::endl; + + //TODO (@feresr): Make port param customizable + const char* kServerOptions[] = { + "listening_ports", "8082", + "num_threads", "10", + "error_log_file", "civetweb.txt", + nullptr + }; + + mServer = new CivetServer(kServerOptions); + if (!mServer->getContext()) { + delete mServer; + mServer = nullptr; + slog.e << "Unable to start fgdbg DebugServer, see civetweb.txt for details." << io::endl; + return; + } + slog.i << "Server started successfully" << io::endl; + + mRestRequestHandler = new RestRequestHandler(); + mWebSocketHandler = new WebSocketHandler(); + + mServer->addHandler("", mRestRequestHandler); + mServer->addWebSocketHandler("", mWebSocketHandler); +} + +void DebugServer::sendMessage(int number) { + mWebSocketHandler->send(number); } DebugServer::~DebugServer() { slog.d << "FrameGraph debug server destroyed" << io::endl; + delete mRestRequestHandler; + delete mWebSocketHandler; } }