From a76cde97bf5bd88426574eeb9a4985b9fb02b565 Mon Sep 17 00:00:00 2001 From: modeco80 Date: Sat, 23 Nov 2024 10:55:52 -0500 Subject: [PATCH] cleanup agent code (slower atm) --- .gitignore | 4 + agent/CollabVMFbcAgent/CollabVMFbcAgent.cpp | 145 +++++++++++++++----- agent/CollabVMFbcAgent/Utils.hpp | 79 +++++++++++ src/main.rs | 2 +- 4 files changed, 192 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index d5cfddd..7af72ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ /target +# for gods sakes visual studio /agent/*.sdf /agent/x64 /agent/**/x64 /agent/ipch +/agent/**/Release +/agent/**/Debug +/agent/*.suo \ No newline at end of file diff --git a/agent/CollabVMFbcAgent/CollabVMFbcAgent.cpp b/agent/CollabVMFbcAgent/CollabVMFbcAgent.cpp index 2aea80a..13e5253 100755 --- a/agent/CollabVMFbcAgent/CollabVMFbcAgent.cpp +++ b/agent/CollabVMFbcAgent/CollabVMFbcAgent.cpp @@ -97,13 +97,12 @@ class cStreamClient { send(tcpSocket, (const char*)&resize, sizeof(resize), 0); } - void SendData(const unique_buffer& data, u32 width, u32 height, const std::vector& tiles) { + void SendData(cSurface& surface, const std::vector& tiles) { tMessageHeader header; header.type = MessageType::Data; // header.datalen = data.get_size() * sizeof(UINT32); header.datalen = sizeof(tDataMessage); - auto* pData = data.data(); // send tile header bool sendFull = false; @@ -122,6 +121,57 @@ class cStreamClient { // send each tile if(!sendFull) { +#if 0 + std::vector> surfs; + + for(auto& tile : tiles) { + surfs.push_back(surface.ClonePiece(tile)); + } + + for(usize i = 0; i < surfs.size(); ++i) { + // things we want! + auto& tile_rect = tiles[i]; + auto& surf = surfs[i]; + //const auto& siz + auto* data = surf->Memory(); + + tTile tile_wire { tile_rect.x, tile_rect.y, tile_rect.width, tile_rect.height }; + + send(tcpSocket, (const char*)&tile_wire, (int)sizeof(tile_wire), 0); + send(tcpSocket, (const char*)&data[0], (int)((tile_rect.width * tile_rect.height) * 4), 0); + } +#endif + + std::vector data; + + for(auto& tile : tiles) { + auto* pData = surface.Memory(); + + tTile tile_wire { tile.x, tile.y, tile.width, tile.height }; + + + data.resize(tile.width * tile.height * 4); + + for (u32 y = 0; y < tile.height; ++y) { + auto* pTileLineStart = &pData[(tile.y + y) * surface.Stride() + tile.x]; + memcpy(&data[y * tile.width], pTileLineStart, tile.width * sizeof(u32)); + } + + // send header + send(tcpSocket, (const char*)&tile_wire, (int)sizeof(tile_wire), 0); + send(tcpSocket, (const char*)&data[0], (int)data.size(), 0); + + + /* + send(tcpSocket, (const char*)&tile_wire, (int)sizeof(tile_wire), 0); + + + for(u32 y = 0; y < tile.height; ++y) { + auto* pTileLineStart = &pData[(tile.y + y) * surface.Stride() + tile.x]; + send(tcpSocket, (const char*)&pTileLineStart[0], tile.width * sizeof(u32), 0); + }*/ + } + #if 0 for(auto& tile : tiles) { tTile tile_wire { tile.x, tile.y, tile.width, tile.height }; @@ -143,11 +193,19 @@ class cStreamClient { send(tcpSocket, (const char*)pTileLineStart, tile.width * sizeof(UINT32), 0); }*/ } + #endif } else { - tTile tDummyTile { 0, 0, width, height }; + auto& size = surface.Size(); + tTile tDummyTile { 0, 0, size.width, size.height }; send(tcpSocket, (const char*)&tDummyTile, sizeof(tDummyTile), 0); - send(tcpSocket, (const char*)&data.data()[0], (i32)(data.get_size() * sizeof(u32)), 0); + + for(auto y = 0; y < size.height; ++y) { + auto* line = &surface.Memory()[y * surface.Stride()]; + send(tcpSocket, (const char*)&line[0], (i32)(size.width * sizeof(u32)), 0); + } + + //send(tcpSocket, (const char*)&data.data()[0], (i32)(data.get_size() * sizeof(u32)), 0); } // send(tcpSocket, (const char*)&data.data()[0], data.get_size() * sizeof(UINT32), 0); @@ -207,13 +265,13 @@ bool nvfbcCreate() { int main(int argc, char** argv) { WSADATA data; - if(WSAStartup(MAKEWORD(2, 2), &data) != NO_ERROR) { + if (WSAStartup(MAKEWORD(2, 2), &data) != NO_ERROR) { return 1; } cStreamClient* client = new cStreamClient(); - if(!client->Connect("192.168.1.149", 9438)) { + if (!client->Connect("192.168.1.149", 9438)) { printf("conn failed\n"); return 1; } @@ -221,12 +279,12 @@ int main(int argc, char** argv) { nvfbcLibrary = new NvFBCLibrary(); //! Load NvFBC - if(!nvfbcLibrary->load()) { + if (!nvfbcLibrary->load()) { fprintf(stderr, "Unable to load the NvFBC library\n"); return -1; } - if(!nvfbcCreate()) { + if (!nvfbcCreate()) { fprintf(stderr, "Unable to create an instance of NvFBC\n"); return -1; } @@ -239,15 +297,15 @@ int main(int argc, char** argv) { BOOL bRecoveryDone = FALSE; NvFBCFrameGrabInfo grabInfo; - unique_buffer buffer; + //unique_buffer buffer; - if(nvfbcSetup()) { + if (nvfbcSetup()) { // Sleep so that ToSysSetUp forces a framebuffer update Sleep(100); NVFBC_TOSYS_GRAB_FRAME_PARAMS fbcSysGrabParams = { 0 }; - std::vector tiles {}; + std::vector tiles{}; // set up grab parameters fbcSysGrabParams.dwVersion = NVFBC_TOSYS_GRAB_FRAME_PARAMS_VER; @@ -260,79 +318,92 @@ int main(int argc, char** argv) { fbcSysGrabParams.pNvFBCFrameGrabInfo = &grabInfo; fbcSysGrabParams.dwWaitTime = 16; - while(true) { + while (true) { // Grab the frame status = nvfbcToSys->NvFBCToSysGrabFrame(&fbcSysGrabParams); - if(status == NVFBC_SUCCESS) { + if (status == NVFBC_SUCCESS) { bRecoveryDone = FALSE; // handle resizing the buffer - if(width != grabInfo.dwWidth || height != grabInfo.dwHeight) { + if (width != grabInfo.dwWidth || height != grabInfo.dwHeight) { width = grabInfo.dwWidth; height = grabInfo.dwHeight; - buffer.resize(grabInfo.dwWidth * grabInfo.dwHeight); + //buffer.resize(grabInfo.dwWidth * grabInfo.dwHeight); firstFrame = true; - client->SendResize(tResizeMessage { width, height }); + client->SendResize(tResizeMessage{ width, height }); } + cSurface surf((u32*)frameBuffer, { width, height }, grabInfo.dwBufferWidth); + +#if 0 // splat the data into an unpadded buffer // REMOVE THIS for(u32 y = 0; y < grabInfo.dwHeight; ++y) { memcpy(&buffer.data()[y * grabInfo.dwWidth], &frameBuffer[(y * grabInfo.dwBufferWidth) * 4], grabInfo.dwWidth * 4); } +#endif tiles.clear(); // diffmap - if(firstFrame == false) { + if (firstFrame == false) { u32 dwDiffMapWidth = (u32)ceil((f32)width / 32); u32 dwDiffMapHeight = (u32)ceil((f32)height / 32); - for(u32 y = 0; y < dwDiffMapHeight; ++y) { - for(u32 x = 0; x < dwDiffMapWidth; ++x) { + for (u32 y = 0; y < dwDiffMapHeight; ++y) { + for (u32 x = 0; x < dwDiffMapWidth; ++x) { auto& bl = diffMap[y * dwDiffMapWidth + x]; - if(bl != 0) { - tiles.push_back(tileRect { - x * (width / dwDiffMapWidth), // x - y * (height / dwDiffMapHeight), // y - width / dwDiffMapWidth, // width - height / dwDiffMapHeight // height + if (bl != 0) { + tiles.push_back(tRect{ + x * (width / dwDiffMapWidth), // x + y * (height / dwDiffMapHeight), // y + width / dwDiffMapWidth, // width + height / dwDiffMapHeight // height }); } } } + + // don't send a frame, just wait + if (tiles.empty()) + continue; } - // send that to the server - client->SendData(buffer, width, height, tiles); - if(firstFrame) + + // send that to the server + //client->SendData(buffer, width, height, tiles); + client->SendData(surf, tiles); + + if (firstFrame) firstFrame = false; - } else { - if(bRecoveryDone == TRUE) { + } + else { + if (bRecoveryDone == TRUE) { fprintf(stderr, "Unable to recover from NvFBC Frame grab failure.\n"); break; } - if(status == NVFBC_ERROR_DYNAMIC_DISABLE) { + if (status == NVFBC_ERROR_DYNAMIC_DISABLE) { fprintf(stderr, "NvFBC disabled. Quitting\n"); break; } // Try to recover the session - if(status == NVFBC_ERROR_INVALIDATED_SESSION) { + if (status == NVFBC_ERROR_INVALIDATED_SESSION) { fprintf(stderr, "Session Invalidated. Attempting recovery\n"); - if(!nvfbcCreate()) { + if (!nvfbcCreate()) { fprintf(stderr, "Unable to re-create NvFBC\n"); break; } - if(nvfbcSetup()) { + if (nvfbcSetup()) { bRecoveryDone = TRUE; - } else { + } + else { fprintf(stderr, "Unable to recover from NvFBC Frame grab failure.\n"); break; } @@ -341,7 +412,7 @@ int main(int argc, char** argv) { } } - if(status != NVFBC_SUCCESS) { + if (status != NVFBC_SUCCESS) { fprintf(stderr, "Unable to setup frame grab.\n"); } @@ -351,4 +422,4 @@ int main(int argc, char** argv) { delete nvfbcLibrary; return 0; -} +} \ No newline at end of file diff --git a/agent/CollabVMFbcAgent/Utils.hpp b/agent/CollabVMFbcAgent/Utils.hpp index 4b1c7f7..1cf5de1 100755 --- a/agent/CollabVMFbcAgent/Utils.hpp +++ b/agent/CollabVMFbcAgent/Utils.hpp @@ -1,6 +1,8 @@ #pragma once #include +#include +#include // common types using u8 = std::uint8_t; @@ -15,6 +17,83 @@ using usize = std::size_t; using f32 = float; using f64 = double; +struct tSize { + u32 width; + u32 height; +}; + +struct tRect { + u32 x; + u32 y; + u32 width; + u32 height; +}; + +struct cSurface { + private: + u32* pBuffer; + tSize size; + u32 stride; + bool owned { false }; + + struct OwnedTag {}; + + public: + cSurface(u32* pBuffer, const tSize& size, u32 stride = -1) { + if(stride == -1) { + this->stride = size.width; + } else { + this->stride = stride; + } + + this->size = size; + this->pBuffer = pBuffer; + this->owned = false; + } + + cSurface(u32* pBuffer, const tSize& size, OwnedTag) { + this->pBuffer = pBuffer; + this->size = size; + owned = true; + } + + ~cSurface() { + if(owned) { + delete[] pBuffer; + this->pBuffer = nullptr; + } + } + + cSurface(const cSurface&) = delete; + cSurface(cSurface&& move) { + this->pBuffer = move.pBuffer; + move.pBuffer = nullptr; + this->size = {}; + this->stride = -1; + this->owned = move.owned; + move.owned = false; + } + + u32 Stride() const { return stride; } + u32 StrideBytes() const { return stride * sizeof(u32); } + + const tSize& Size() const { return size; } + + u32* Memory() { return &this->pBuffer[0]; } + + // creates a new owned cSurface which owns this memory + std::unique_ptr ClonePiece(const tRect& rect) { + auto* pSurfaceMemory = new u32[rect.width * rect.height * sizeof(u32)]; + + for(u32 y = 0; y < rect.height; ++y) { + auto* pTileLineStart = &pBuffer[(rect.y + y) * this->stride + rect.x]; + memcpy(&pSurfaceMemory[y * rect.width], pTileLineStart, rect.width * sizeof(u32)); + } + + return std::unique_ptr(new cSurface(pSurfaceMemory, { rect.width, rect.height }, OwnedTag {})); + } +}; + /// like vector but doesn't grow on its own template struct unique_buffer { diff --git a/src/main.rs b/src/main.rs index c92cea4..230c532 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ fn read_message(stream: &mut TcpStream, argb_buffer: &mut Vec, width: u32) MESSAGETYPE_DATA => { let tile_count = stream.read_u32::().expect("fuck"); - println!("{tile_count} tiles"); +// println!("{tile_count} tiles"); for i in 0..tile_count { // tile rect