Skip to content

Commit

Permalink
performance: Use GLsync to wait commandbuffer GPU process on GLCore/G…
Browse files Browse the repository at this point in the history
…LES (#943)

* wip

* fix

* format
  • Loading branch information
karasusan authored Aug 31, 2023
1 parent dbae916 commit bdd6793
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 15 deletions.
73 changes: 63 additions & 10 deletions Plugin~/WebRTCPlugin/GraphicsDevice/OpenGL/OpenGLGraphicsDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,19 @@ namespace webrtc
OpenGLTexture2D* srcTexture = static_cast<OpenGLTexture2D*>(src);
OpenGLTexture2D* dstTexture = static_cast<OpenGLTexture2D*>(dst);
const GLuint srcName = srcTexture->GetTexture();
const GLuint dstName = dstTexture->GetTexture();
return CopyResource(dstName, srcName);
return CopyResource(dstTexture, srcName);
}

bool OpenGLGraphicsDevice::CopyResourceFromNativeV(ITexture2D* dst, void* nativeTexturePtr)
{
OpenGLTexture2D* dstTexture = static_cast<OpenGLTexture2D*>(dst);
OpenGLTexture2D* texture2D = static_cast<OpenGLTexture2D*>(dst);
const GLuint srcName = reinterpret_cast<uintptr_t>(nativeTexturePtr);
const GLuint dstName = dstTexture->GetTexture();
return CopyResource(dstName, srcName);
return CopyResource(texture2D, srcName);
}

bool OpenGLGraphicsDevice::CopyResource(GLuint dstName, GLuint srcName)
bool OpenGLGraphicsDevice::CopyResource(OpenGLTexture2D* texture, GLuint srcName)
{
const GLuint dstName = texture->GetTexture();
if (srcName == dstName)
{
RTC_LOG(LS_INFO) << "Same texture";
Expand Down Expand Up @@ -174,10 +173,15 @@ namespace webrtc
dstSize.height(),
1);

// todo(kazuki): "glFinish" is used to sync GPU for waiting to copy the texture buffer.
// But this command affects graphics performance.
glFinish();

// Create sync object.
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
RTC_LOG(LS_INFO) << "glFenceSync returns error " << error;
return false;
}
texture->SetSync(sync);
return true;
}

Expand Down Expand Up @@ -273,5 +277,54 @@ namespace webrtc
#endif
}

bool OpenGLGraphicsDevice::WaitSync(const ITexture2D* texture, uint64_t nsTimeout)
{
if (!OpenGLContext::CurrentContext())
contexts_.push_back(OpenGLContext::CreateGLContext(mainContext_.get()));

const OpenGLTexture2D* glTexture2D = static_cast<const OpenGLTexture2D*>(texture);
GLsync sync = glTexture2D->GetSync();
if (sync == 0)
{
RTC_LOG(LS_INFO) << "The sync object is already reset.";
return true;
}
GLenum ret = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, nsTimeout);
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
RTC_LOG(LS_INFO) << "glClientWaitSync returns error " << error;
return false;
}

switch (ret)
{
case GL_CONDITION_SATISFIED:
case GL_ALREADY_SIGNALED:
return true;
}
RTC_LOG(LS_INFO) << "glClientWaitSync returns " << ret;
return false;
}

bool OpenGLGraphicsDevice::ResetSync(const ITexture2D* texture)
{
const OpenGLTexture2D* glTexture2D = static_cast<const OpenGLTexture2D*>(texture);
GLsync sync = glTexture2D->GetSync();
if (sync == 0)
{
RTC_LOG(LS_INFO) << "The sync object is already reset.";
return true;
}
glDeleteSync(sync);
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
RTC_LOG(LS_INFO) << "glDeleteSync returns error " << error;
return false;
}
return true;
}

} // end namespace webrtc
} // end namespace unity
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ namespace webrtc
rtc::scoped_refptr<webrtc::I420Buffer> ConvertRGBToI420(ITexture2D* tex) override;
bool CopyResourceFromNativeV(ITexture2D* dest, void* nativeTexturePtr) override;
std::unique_ptr<GpuMemoryBufferHandle> Map(ITexture2D* texture) override;
bool WaitSync(const ITexture2D* texture, uint64_t nsTimeout = 0) override;
bool ResetSync(const ITexture2D* texture) override;

#if CUDA_PLATFORM
bool IsCudaSupport() override { return m_isCudaSupport; }
CUcontext GetCUcontext() override { return m_cudaContext.GetContext(); }
NV_ENC_BUFFER_FORMAT GetEncodeBufferFormat() override { return NV_ENC_BUFFER_FORMAT_ABGR; }
#endif

private:
bool CopyResource(GLuint dstName, GLuint srcName);
bool CopyResource(OpenGLTexture2D* texture, GLuint srcName);
void ReleaseTexture(OpenGLTexture2D* texture);
#if CUDA_PLATFORM
CudaContext m_cudaContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ namespace unity
{
namespace webrtc
{

//---------------------------------------------------------------------------------------------------------------------

OpenGLTexture2D::OpenGLTexture2D(uint32_t w, uint32_t h, GLuint tex, ReleaseOpenGLTextureCallback callback)
: ITexture2D(w, h)
, m_texture(tex)
, m_pbo(0)
, m_sync(0)
, m_callback(callback)
{
RTC_DCHECK(m_texture);
Expand Down
4 changes: 4 additions & 0 deletions Plugin~/WebRTCPlugin/GraphicsDevice/OpenGL/OpenGLTexture2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ namespace webrtc
GLuint GetTexture() const { return m_texture; }
void Release();

void SetSync(GLsync sync) { m_sync = sync; }
GLsync GetSync() const { return m_sync; }

private:
GLuint m_texture;
GLuint m_pbo;
GLsync m_sync;
std::vector<byte> m_buffer;
ReleaseOpenGLTextureCallback m_callback;
};
Expand Down

0 comments on commit bdd6793

Please sign in to comment.