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
This commit is contained in:
Stefano Ceccherini 2007-04-26 20:23:10 +00:00
parent 5240f11543
commit effcdf2e6a
1 changed files with 44 additions and 11 deletions

View File

@ -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;
@ -343,9 +345,9 @@ BGLView::DirectConnected(direct_buffer_info *info)
}
case B_DIRECT_STOP:
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);
}