From effcdf2e6a41cac6bf43f133e9b7a85c61e8f69c Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Thu, 26 Apr 2007 20:23:10 +0000 Subject: [PATCH] Implemented locking for BGLView direct mode. Tested with GLTeapot and GLDirectTest. Seems to work fine git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20844 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/opengl/GLView.cpp | 55 ++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/src/kits/opengl/GLView.cpp b/src/kits/opengl/GLView.cpp index 6f4a224c42..d5f5ec61e8 100644 --- a/src/kits/opengl/GLView.cpp +++ b/src/kits/opengl/GLView.cpp @@ -45,6 +45,8 @@ struct glview_direct_info { direct_buffer_info *direct_info; bool direct_connected; bool enable_direct_mode; + sem_id draw_sem; + int32 draw_lock; glview_direct_info(); ~glview_direct_info(); @@ -154,9 +156,12 @@ BGLView::ErrorCallback(unsigned long errorCode) void BGLView::Draw(BRect updateRect) { - if (fRenderer) - return fRenderer->Draw(updateRect); - + if (fRenderer) { + lock_draw(); + fRenderer->Draw(updateRect); + unlock_draw(); + return; + } // TODO: auto-size and center the string MovePenTo(8, 32); DrawString("No OpenGL renderer available!"); @@ -296,20 +301,17 @@ BGLView::GetSupportedSuites(BMessage *data) void BGLView::DirectConnected(direct_buffer_info *info) { - // TODO: Locking !!!!! - // TODO: We should probably prevent the renderer to draw anything - // (lock_draw() ??) while we are in this method - if (!m_clip_info/* && m_direct_connection_disabled*/) { m_clip_info = new glview_direct_info(); } glview_direct_info *glviewDirectInfo = (glview_direct_info *)m_clip_info; direct_buffer_info *localInfo = glviewDirectInfo->direct_info; - //direct_info_locker->Lock(); + switch(info->buffer_state & B_DIRECT_MODE_MASK) { case B_DIRECT_START: glviewDirectInfo->direct_connected = true; + unlock_draw(); case B_DIRECT_MODIFY: { localInfo->buffer_state = info->buffer_state; @@ -342,11 +344,11 @@ BGLView::DirectConnected(direct_buffer_info *info) break; } case B_DIRECT_STOP: - glviewDirectInfo->direct_connected = false; + glviewDirectInfo->direct_connected = false; + lock_draw(); break; } - //direct_info_locker->Unlock(); - + if (fRenderer) fRenderer->DirectConnected(localInfo); } @@ -364,6 +366,34 @@ BGLView::EnableDirectMode(bool enabled) } +void +BGLView::lock_draw() +{ + glview_direct_info *info = (glview_direct_info *)m_clip_info; + + if (!info || !info->enable_direct_mode) + return; + + if (atomic_add(&info->draw_lock, 1) > 0) { + while (acquire_sem(info->draw_sem) == B_INTERRUPTED) + ; + } +} + + +void +BGLView::unlock_draw() +{ + glview_direct_info *info = (glview_direct_info *)m_clip_info; + + if (!info || !info->enable_direct_mode) + return; + + if (atomic_add(&info->draw_lock, -1) > 1) + release_sem(info->draw_sem); +} + + //---- virtual reserved methods ---------- void BGLView::_ReservedGLView1() {} @@ -521,11 +551,14 @@ glview_direct_info::glview_direct_info() direct_info = (direct_buffer_info *)calloc(1, B_PAGE_SIZE); direct_connected = false; enable_direct_mode = false; + draw_sem = create_sem(0, "glview_draw_sem"); + draw_lock = 0; } glview_direct_info::~glview_direct_info() { free(direct_info); + delete_sem(draw_sem); }