File indexing completed on 2024-12-22 04:12:48
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "KisOpenGLSync.h" 0008 0009 namespace Sync { 0010 //For checking sync status 0011 enum SyncStatus { 0012 Signaled, 0013 Unsignaled 0014 }; 0015 0016 #ifndef GL_SYNC_GPU_COMMANDS_COMPLETE 0017 #define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 0018 #endif 0019 #ifndef GL_UNSIGNALED 0020 #define GL_UNSIGNALED 0x9118 0021 #endif 0022 #ifndef GL_SIGNALED 0023 #define GL_SIGNALED 0x9119 0024 #endif 0025 #ifndef GL_SYNC_STATUS 0026 #define GL_SYNC_STATUS 0x9114 0027 #endif 0028 0029 //Function pointers for glFenceSync and glGetSynciv 0030 typedef GLsync (*kis_glFenceSync)(GLenum, GLbitfield); 0031 static kis_glFenceSync k_glFenceSync = 0; 0032 typedef void (*kis_glGetSynciv)(GLsync, GLenum, GLsizei, GLsizei*, GLint*); 0033 static kis_glGetSynciv k_glGetSynciv = 0; 0034 typedef void (*kis_glDeleteSync)(GLsync); 0035 static kis_glDeleteSync k_glDeleteSync = 0; 0036 typedef GLenum (*kis_glClientWaitSync)(GLsync,GLbitfield,GLuint64); 0037 static kis_glClientWaitSync k_glClientWaitSync = 0; 0038 0039 //Initialise the function pointers for glFenceSync and glGetSynciv 0040 //Note: Assumes a current OpenGL context. 0041 void init(QOpenGLContext* ctx) { 0042 #if defined Q_OS_WIN 0043 if (KisOpenGL::supportsFenceSync()) { 0044 #ifdef ENV64BIT 0045 k_glFenceSync = (kis_glFenceSync)ctx->getProcAddress("glFenceSync"); 0046 k_glGetSynciv = (kis_glGetSynciv)ctx->getProcAddress("glGetSynciv"); 0047 k_glDeleteSync = (kis_glDeleteSync)ctx->getProcAddress("glDeleteSync"); 0048 #else 0049 k_glFenceSync = (kis_glFenceSync)ctx->getProcAddress("glFenceSyncARB"); 0050 k_glGetSynciv = (kis_glGetSynciv)ctx->getProcAddress("glGetSyncivARB"); 0051 k_glDeleteSync = (kis_glDeleteSync)ctx->getProcAddress("glDeleteSyncARB"); 0052 #endif 0053 k_glClientWaitSync = (kis_glClientWaitSync)ctx->getProcAddress("glClientWaitSync"); 0054 } 0055 #elif defined Q_OS_LINUX || defined Q_OS_MACOS 0056 if (KisOpenGL::supportsFenceSync()) { 0057 k_glFenceSync = (kis_glFenceSync)ctx->getProcAddress("glFenceSync"); 0058 k_glGetSynciv = (kis_glGetSynciv)ctx->getProcAddress("glGetSynciv"); 0059 k_glDeleteSync = (kis_glDeleteSync)ctx->getProcAddress("glDeleteSync"); 0060 k_glClientWaitSync = (kis_glClientWaitSync)ctx->getProcAddress("glClientWaitSync"); 0061 } 0062 #endif 0063 if (k_glFenceSync == 0 || k_glGetSynciv == 0 || 0064 k_glDeleteSync == 0 || k_glClientWaitSync == 0) { 0065 warnUI << "Could not find sync functions, disabling sync notification."; 0066 } 0067 } 0068 0069 //Get a fence sync object from OpenGL 0070 GLsync getSync() { 0071 if(k_glFenceSync) { 0072 GLsync sync = k_glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 0073 if (KisOpenGL::needsFenceWorkaround()) { 0074 k_glClientWaitSync(sync, 0, 1); 0075 } 0076 return sync; 0077 } 0078 return 0; 0079 } 0080 0081 //Check the status of a sync object 0082 SyncStatus syncStatus(GLsync syncObject) { 0083 if(syncObject && k_glGetSynciv) { 0084 GLint status = -1; 0085 k_glGetSynciv(syncObject, GL_SYNC_STATUS, 1, 0, &status); 0086 return status == GL_SIGNALED ? Sync::Signaled : Sync::Unsignaled; 0087 } 0088 return Sync::Signaled; 0089 } 0090 0091 void deleteSync(GLsync syncObject) { 0092 if(syncObject && k_glDeleteSync) { 0093 k_glDeleteSync(syncObject); 0094 } 0095 } 0096 } 0097 0098 KisOpenGLSync::KisOpenGLSync() 0099 { 0100 m_syncObject = Sync::getSync(); 0101 } 0102 0103 KisOpenGLSync::~KisOpenGLSync() 0104 { 0105 Sync::deleteSync(m_syncObject); 0106 } 0107 0108 bool KisOpenGLSync::isSignaled() 0109 { 0110 return Sync::syncStatus(m_syncObject) == Sync::Signaled; 0111 } 0112 0113 void KisOpenGLSync::init(QOpenGLContext *ctx) 0114 { 0115 Sync::init(ctx); 0116 }