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; direct_buffer_info *direct_info;
bool direct_connected; bool direct_connected;
bool enable_direct_mode; bool enable_direct_mode;
sem_id draw_sem;
int32 draw_lock;
glview_direct_info(); glview_direct_info();
~glview_direct_info(); ~glview_direct_info();
@ -154,9 +156,12 @@ BGLView::ErrorCallback(unsigned long errorCode)
void void
BGLView::Draw(BRect updateRect) BGLView::Draw(BRect updateRect)
{ {
if (fRenderer) if (fRenderer) {
return fRenderer->Draw(updateRect); lock_draw();
fRenderer->Draw(updateRect);
unlock_draw();
return;
}
// TODO: auto-size and center the string // TODO: auto-size and center the string
MovePenTo(8, 32); MovePenTo(8, 32);
DrawString("No OpenGL renderer available!"); DrawString("No OpenGL renderer available!");
@ -296,20 +301,17 @@ BGLView::GetSupportedSuites(BMessage *data)
void void
BGLView::DirectConnected(direct_buffer_info *info) 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*/) { if (!m_clip_info/* && m_direct_connection_disabled*/) {
m_clip_info = new glview_direct_info(); m_clip_info = new glview_direct_info();
} }
glview_direct_info *glviewDirectInfo = (glview_direct_info *)m_clip_info; glview_direct_info *glviewDirectInfo = (glview_direct_info *)m_clip_info;
direct_buffer_info *localInfo = glviewDirectInfo->direct_info; direct_buffer_info *localInfo = glviewDirectInfo->direct_info;
//direct_info_locker->Lock();
switch(info->buffer_state & B_DIRECT_MODE_MASK) { switch(info->buffer_state & B_DIRECT_MODE_MASK) {
case B_DIRECT_START: case B_DIRECT_START:
glviewDirectInfo->direct_connected = true; glviewDirectInfo->direct_connected = true;
unlock_draw();
case B_DIRECT_MODIFY: case B_DIRECT_MODIFY:
{ {
localInfo->buffer_state = info->buffer_state; localInfo->buffer_state = info->buffer_state;
@ -343,9 +345,9 @@ BGLView::DirectConnected(direct_buffer_info *info)
} }
case B_DIRECT_STOP: case B_DIRECT_STOP:
glviewDirectInfo->direct_connected = false; glviewDirectInfo->direct_connected = false;
lock_draw();
break; break;
} }
//direct_info_locker->Unlock();
if (fRenderer) if (fRenderer)
fRenderer->DirectConnected(localInfo); 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 ---------- //---- virtual reserved methods ----------
void BGLView::_ReservedGLView1() {} void BGLView::_ReservedGLView1() {}
@ -521,11 +551,14 @@ glview_direct_info::glview_direct_info()
direct_info = (direct_buffer_info *)calloc(1, B_PAGE_SIZE); direct_info = (direct_buffer_info *)calloc(1, B_PAGE_SIZE);
direct_connected = false; direct_connected = false;
enable_direct_mode = false; enable_direct_mode = false;
draw_sem = create_sem(0, "glview_draw_sem");
draw_lock = 0;
} }
glview_direct_info::~glview_direct_info() glview_direct_info::~glview_direct_info()
{ {
free(direct_info); free(direct_info);
delete_sem(draw_sem);
} }