void GLXOSD::osdHandleBufferSwap(Display* display, GLXDrawable drawable) { osdToggledThisFrame = false; frameLogToggledThisFrame = false; unsigned int width = 1; unsigned int height = 1; if (osdVisible && display && drawable) { auto it = drawableHandlers->find(glXGetCurrentContext()); OSDInstance* instance; if (it == drawableHandlers->end()) { instance = new OSDInstance(); drawableHandlers->insert( std::pair<GLXContext, glxosd::OSDInstance*>( glXGetCurrentContext(), instance)); } else { instance = (*it).second; } GlinjectGLLockRAIIHelper raiiHelper; GLint viewport[4]; rgl(GetIntegerv)(GL_VIEWPORT, viewport); width = viewport[2]; height = viewport[3]; if (width < 1 || height < 1) { return; } instance->render(width, height); } if (isFrameLoggingEnabled()) { frameLogTick(drawable); } }
void OSDInstance::render(unsigned int width, unsigned int height) { currentFrameCount++; long currentTimeMilliseconds = getMonotonicTimeNanoseconds() / 1000000ULL; //Refresh the info every 500 milliseconds if (currentTimeMilliseconds - previousTime >= 500) { update(currentTimeMilliseconds); } // Memorise misc. settings GLint program; { rgl(GetIntegerv)(GL_CURRENT_PROGRAM, &program); rgl(UseProgram)(0); } GLint frontFace; { rgl(GetIntegerv)(GL_FRONT_FACE, &frontFace); rgl(FrontFace)(GL_CCW); } GLfloat blendColour[4]; { rgl(GetFloatv)(GL_BLEND_COLOR, blendColour); rgl(BlendColor)(0, 0, 0, 0); } GLboolean colourMask[4]; { rgl(GetBooleanv)(GL_COLOR_WRITEMASK, colourMask); rgl(ColorMask)(1, 1, 1, 1); } GLint blendSrc; GLint blendDst; { rgl(GetIntegerv)(GL_BLEND_SRC, &blendSrc); rgl(GetIntegerv)(GL_BLEND_DST, &blendDst); rgl(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } //Equivalent to glPushAttrib -> glEnable/Disable -> glPopAttrib GLAttribState attribState(rgl(Enable), rgl(Disable), rgl(IsEnabled)); GLAttribState clientAttribState(glEnableClientState, glDisableClientState, rgl(IsEnabled)); { attribState.set(GL_ALPHA_TEST, GL_FALSE); attribState.set(GL_AUTO_NORMAL, GL_FALSE); attribState.set(GL_CULL_FACE, GL_FALSE); attribState.set(GL_COLOR_LOGIC_OP, GL_FALSE); attribState.set(GL_COLOR_TABLE, GL_FALSE); attribState.set(GL_CONVOLUTION_1D, GL_FALSE); attribState.set(GL_CONVOLUTION_2D, GL_FALSE); attribState.set(GL_DEPTH_TEST, GL_FALSE); attribState.set(GL_DITHER, GL_FALSE); attribState.set(GL_FOG, GL_FALSE); attribState.set(GL_HISTOGRAM, GL_FALSE); attribState.set(GL_INDEX_LOGIC_OP, GL_FALSE); attribState.set(GL_LIGHTING, GL_FALSE); attribState.set(GL_NORMALIZE, GL_FALSE); attribState.set(GL_MINMAX, GL_FALSE); attribState.set(GL_SEPARABLE_2D, GL_FALSE); attribState.set(GL_SCISSOR_TEST, GL_FALSE); attribState.set(GL_STENCIL_TEST, GL_FALSE); attribState.set(GL_SAMPLE_ALPHA_TO_COVERAGE, GL_FALSE); attribState.set(GL_MULTISAMPLE, GL_FALSE); attribState.set(GL_POLYGON_OFFSET_POINT, GL_FALSE); attribState.set(GL_POLYGON_OFFSET_LINE, GL_FALSE); attribState.set(GL_POLYGON_OFFSET_FILL, GL_FALSE); attribState.set(GL_SAMPLE_COVERAGE, GL_FALSE); attribState.set(GL_TEXTURE_GEN_Q, GL_FALSE); attribState.set(GL_TEXTURE_GEN_R, GL_FALSE); attribState.set(GL_TEXTURE_GEN_S, GL_FALSE); attribState.set(GL_TEXTURE_GEN_T, GL_FALSE); clientAttribState.set(GL_COLOR_ARRAY, GL_FALSE); clientAttribState.set(GL_EDGE_FLAG_ARRAY, GL_FALSE); clientAttribState.set(GL_INDEX_ARRAY, GL_FALSE); clientAttribState.set(GL_NORMAL_ARRAY, GL_FALSE); clientAttribState.set(GL_TEXTURE_COORD_ARRAY, GL_TRUE); clientAttribState.set(GL_VERTEX_ARRAY, GL_TRUE); } { attribState.set(GL_TEXTURE_CUBE_MAP, GL_FALSE); attribState.set(GL_VERTEX_PROGRAM_ARB, GL_FALSE); attribState.set(GL_FRAGMENT_PROGRAM_ARB, GL_FALSE); attribState.set(GL_BLEND, GL_TRUE); attribState.set(GL_TEXTURE_2D, GL_TRUE); } //Memorise buffer states GLint pixelUnpackBufferBinding = 0, arrayBufferBinding = 0, activeTexture = 0, textureBinding2D = 0, vertexArrayBinding = 0, elementArrayBufferBinding = 0, drawFramebufferBinding = 0, readFramebufferBinding = 0, glPolygonModeFrontAndBack = 0, samplerBinding = 0; rgl(GetIntegerv)(GL_PIXEL_UNPACK_BUFFER_BINDING, &pixelUnpackBufferBinding); rgl(GetIntegerv)(GL_ARRAY_BUFFER_BINDING, &arrayBufferBinding); rgl(GetIntegerv)(GL_ACTIVE_TEXTURE, &activeTexture); rgl(GetIntegerv)(GL_TEXTURE_BINDING_2D, &textureBinding2D); rgl(GetIntegerv)(GL_VERTEX_ARRAY_BINDING, &vertexArrayBinding); rgl(GetIntegerv)(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elementArrayBufferBinding); rgl(GetIntegerv)(GL_DRAW_FRAMEBUFFER_BINDING, &drawFramebufferBinding); rgl(GetIntegerv)(GL_READ_FRAMEBUFFER_BINDING, &readFramebufferBinding); rgl(GetIntegerv)(GL_POLYGON_MODE, &glPolygonModeFrontAndBack); //We are borrowing GL_TEXTURE0, so we need to reset its sampler rgl(ActiveTexture)(GL_TEXTURE0); rgl(GetIntegerv)(GL_SAMPLER_BINDING, &samplerBinding); rgl(BindFramebuffer)(GL_DRAW_FRAMEBUFFER, 0); rgl(BindFramebuffer)(GL_READ_FRAMEBUFFER, 0); rgl(PolygonMode)(GL_FRONT_AND_BACK, GL_FILL); renderText(width, height); //Revert sampler rgl(ActiveTexture)(GL_TEXTURE0); rgl(BindSampler)(0, samplerBinding); //Revert buffer states rgl(ActiveTexture)(activeTexture); rgl(BindTexture)(GL_TEXTURE_2D, textureBinding2D); rgl(BindVertexArray)(vertexArrayBinding); rgl(BindBuffer)(GL_PIXEL_UNPACK_BUFFER, pixelUnpackBufferBinding); rgl(BindBuffer)(GL_ARRAY_BUFFER, arrayBufferBinding); rgl(BindBuffer)(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferBinding); rgl(BindFramebuffer)(GL_DRAW_FRAMEBUFFER, drawFramebufferBinding); rgl(BindFramebuffer)(GL_READ_FRAMEBUFFER, readFramebufferBinding); rgl(PolygonMode)(GL_FRONT_AND_BACK, glPolygonModeFrontAndBack); //Revert misc settings rgl(BlendColor)(blendColour[0], blendColour[1], blendColour[2], blendColour[3]); rgl(BlendFunc)(blendSrc, blendDst); rgl(ColorMask)(colourMask[0], colourMask[1], colourMask[2], colourMask[3]); rgl(FrontFace)(frontFace); rgl(UseProgram)(program); }