diff --git a/CloneSource.cpp b/CloneSource.cpp index 07e53da..18d1b1e 100644 --- a/CloneSource.cpp +++ b/CloneSource.cpp @@ -161,7 +161,7 @@ void CloneSource::update(float dt) if ( images_.empty() || now - elapsed_.front() < delay_ + (dt * 0.001) ) { // create a FBO if none can be reused (from above) and test for RAM in GPU - if (garbage_image_ == nullptr && ( images_.empty() || FrameBuffer::shouldHaveEnoughMemory(origin_->frame()->resolution(), origin_->frame()->use_alpha()) ) ) + if (garbage_image_ == nullptr && ( images_.empty() || Rendering::shouldHaveEnoughMemory(origin_->frame()->resolution(), origin_->frame()->use_alpha()) ) ) garbage_image_ = new FrameBuffer( origin_->frame()->resolution(), origin_->frame()->use_alpha() ); // image available if (garbage_image_ != nullptr) { diff --git a/FrameBuffer.cpp b/FrameBuffer.cpp index 9944211..288aade 100644 --- a/FrameBuffer.cpp +++ b/FrameBuffer.cpp @@ -35,10 +35,6 @@ #define FRAMEBUFFER_DEBUG #endif -#define GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 0x9048 -#define GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX 0x9049 -#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC - const char* FrameBuffer::aspect_ratio_name[5] = { "4:3", "3:2", "16:10", "16:9", "21:9" }; glm::vec2 FrameBuffer::aspect_ratio_size[5] = { glm::vec2(4.f,3.f), glm::vec2(3.f,2.f), glm::vec2(16.f,10.f), glm::vec2(16.f,9.f) , glm::vec2(21.f,9.f) }; const char* FrameBuffer::resolution_name[5] = { "720", "1080", "1200", "1440", "2160" }; @@ -363,7 +359,7 @@ void FrameBuffer::checkFramebufferStatus() if ( framebufferMemoryInKB > 8000 ) { // Obtain RAM usage in GPU (if possible) - glm::ivec2 RAM = getGPUMemoryInformation(); + glm::ivec2 RAM = Rendering::getGPUMemoryInformation(); // bad case: not enough RAM, we should warn the user if ( RAM.x < framebufferMemoryInKB * 3 ) { @@ -388,64 +384,6 @@ void FrameBuffer::checkFramebufferStatus() } -// RAM usage in GPU -// returns { CurAvailMemoryInKB, TotalMemoryInKB } -// MAX values means the info in not available -glm::ivec2 FrameBuffer::getGPUMemoryInformation() -{ - glm::ivec2 ret(INT_MAX, INT_MAX); - - // Detect method to get info - static int meminfomode = -1; - if (meminfomode<0) { - // initialized - meminfomode = 0; - GLint numExtensions = 0; - glGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions ); - for (int i = 0; i < numExtensions; ++i){ - const GLubyte *ccc = glGetStringi(GL_EXTENSIONS, i); - // NVIDIA extension available - if ( strcmp( (const char*)ccc, "GL_NVX_gpu_memory_info") == 0 ){ - meminfomode = 1; - break; - } - // ATI extension available - else if ( strcmp( (const char*)ccc, "GL_ATI_meminfo") == 0 ){ - meminfomode = 2; - break; - } - } - - } - - // NVIDIA - if (meminfomode == 1) { - static GLint nTotalMemoryInKB = -1; - if (nTotalMemoryInKB<0) - glGetIntegerv( GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX, &nTotalMemoryInKB ); - ret.y = nTotalMemoryInKB; - - glGetIntegerv( GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX, &ret.x ); - } - // ATI - else if (meminfomode == 2) { - glGetIntegerv( GL_TEXTURE_FREE_MEMORY_ATI, &ret.x ); - } - - return ret; -} - - -bool FrameBuffer::shouldHaveEnoughMemory(glm::vec3 resolution, bool useAlpha, bool multiSampling) -{ - glm::ivec2 RAM = getGPUMemoryInformation(); - - // approximation of RAM needed for such FBO - GLint framebufferMemoryInKB = ( resolution.x * resolution.x * (useAlpha?4:3) * (multiSampling?2:1) ) / 1024; - - return ( RAM.x > framebufferMemoryInKB * 3 ); -} - glm::mat4 FrameBuffer::projection() const { diff --git a/FrameBuffer.h b/FrameBuffer.h index 4285a07..a44673d 100644 --- a/FrameBuffer.h +++ b/FrameBuffer.h @@ -44,9 +44,6 @@ public: static float resolution_height[5]; static glm::vec3 getResolutionFromParameters(int ar, int h); static glm::ivec2 getParametersFromResolution(glm::vec3 res); - // memory management - static glm::ivec2 getGPUMemoryInformation(); - static bool shouldHaveEnoughMemory(glm::vec3 resolution, bool useAlpha = false, bool multiSampling = false); FrameBuffer(glm::vec3 resolution, bool useAlpha = false, bool multiSampling = false); FrameBuffer(uint width, uint height, bool useAlpha = false, bool multiSampling = false); diff --git a/RenderingManager.cpp b/RenderingManager.cpp index 7acd4bc..dec2d39 100644 --- a/RenderingManager.cpp +++ b/RenderingManager.cpp @@ -467,6 +467,71 @@ void Rendering::requestScreenshot() } +// RAM usage in GPU +// returns { CurAvailMemoryInKB, TotalMemoryInKB } +// MAX values means the info in not available + +#define GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 0x9048 +#define GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX 0x9049 +#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC + +glm::ivec2 Rendering::getGPUMemoryInformation() +{ + glm::ivec2 ret(INT_MAX, INT_MAX); + + // Detect method to get info + static int meminfomode = -1; + if (meminfomode<0) { + // initialized + meminfomode = 0; + GLint numExtensions = 0; + glGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions ); + for (int i = 0; i < numExtensions; ++i){ + const GLubyte *ccc = glGetStringi(GL_EXTENSIONS, i); + // NVIDIA extension available + if ( strcmp( (const char*)ccc, "GL_NVX_gpu_memory_info") == 0 ){ + meminfomode = 1; + break; + } + // ATI extension available + else if ( strcmp( (const char*)ccc, "GL_ATI_meminfo") == 0 ){ + meminfomode = 2; + break; + } + } + + } + + // NVIDIA + if (meminfomode == 1) { + static GLint nTotalMemoryInKB = -1; + if (nTotalMemoryInKB<0) + glGetIntegerv( GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX, &nTotalMemoryInKB ); + ret.y = nTotalMemoryInKB; + + glGetIntegerv( GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX, &ret.x ); + } + // ATI + else if (meminfomode == 2) { + glGetIntegerv( GL_TEXTURE_FREE_MEMORY_ATI, &ret.x ); + } + + return ret; +} + + +bool Rendering::shouldHaveEnoughMemory(glm::vec3 resolution, bool useAlpha, bool multiSampling) +{ + glm::ivec2 RAM = getGPUMemoryInformation(); + + // approximation of RAM needed for such FBO + GLint framebufferMemoryInKB = ( resolution.x * resolution.x * (useAlpha?4:3) * (multiSampling?2:1) ) / 1024; + + return ( RAM.x > framebufferMemoryInKB * 3 ); +} + + + // custom surface with a new VAO class WindowSurface : public Primitive { diff --git a/RenderingManager.h b/RenderingManager.h index c9517a5..b9e295a 100644 --- a/RenderingManager.h +++ b/RenderingManager.h @@ -147,6 +147,10 @@ public: // project from scene coordinate to window glm::vec2 project(glm::vec3 scene_coordinate, glm::mat4 modelview = glm::mat4(1.f), bool to_framebuffer = true); + // memory management + static glm::ivec2 getGPUMemoryInformation(); + static bool shouldHaveEnoughMemory(glm::vec3 resolution, bool useAlpha = false, bool multiSampling = false); + #ifdef USE_GST_OPENGL_SYNC_HANDLER // for opengl pipeline in gstreamer static void LinkPipeline( GstPipeline *pipeline );