abstract base class and implementation using BView and BWindow of an interface to a graphics card, UpdateQueue doesn't work yet, it was going to be used to decouple frame buffer transfers to the front buffer from the drawing in the back buffer

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12056 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-03-26 22:16:29 +00:00
parent 5cdd702901
commit 3294d07b15
6 changed files with 1391 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
// UpdateQueue.cpp
#include <new>
#include <stdio.h>
#include "HWInterface.h"
#include "UpdateQueue.h"
// constructor
UpdateQueue::UpdateQueue(HWInterface* interface)
: fInterface(interface),
fUpdateRegion(),
fUpdateExecutor(-1),
fThreadControl(-1),
fStatus(B_ERROR)
{
fThreadControl = create_sem(0, "update queue control");
if (fThreadControl >= B_OK)
fStatus = B_OK;
else
fStatus = fThreadControl;
if (fStatus == B_OK) {
fUpdateExecutor = spawn_thread(_execute_updates_, "update queue runner",
B_NORMAL_PRIORITY, this);
if (fUpdateExecutor >= B_OK) {
fStatus = B_OK;
resume_thread(fUpdateExecutor);
} else
fStatus = fUpdateExecutor;
}
}
// destructor
UpdateQueue::~UpdateQueue()
{
if (delete_sem(fThreadControl) == B_OK)
wait_for_thread(fUpdateExecutor, &fUpdateExecutor);
}
// InitCheck
status_t
UpdateQueue::InitCheck()
{
return fStatus;
}
// AddRect
void
UpdateQueue::AddRect(const BRect& rect)
{
Lock();
fUpdateRegion.Include(rect);
_Reschedule();
Unlock();
}
// _execute_updates_
int32
UpdateQueue::_execute_updates_(void* cookie)
{
UpdateQueue *gc = (UpdateQueue*)cookie;
return gc->_ExecuteUpdates();
}
// _ExecuteUpdates
int32
UpdateQueue::_ExecuteUpdates()
{
bool running = true;
while (running) {
status_t err = acquire_sem_etc(fThreadControl, 1, B_RELATIVE_TIMEOUT,
40000);
switch (err) {
case B_OK:
case B_TIMED_OUT:
// execute updates
if (Lock()) {
// if (fInterface->Lock()) {
int32 count = fUpdateRegion.CountRects();
for (int32 i = 0; i < count; i++) {
fInterface->CopyBackToFront(fUpdateRegion.RectAt(i));
}
// fInterface->Unlock();
fUpdateRegion.MakeEmpty();
// }
Unlock();
}
break;
case B_BAD_SEM_ID:
running = false;
break;
default:
break;
}
}
return 0;
}
// _Reschedule
//
// PRE: The object must be locked.
void
UpdateQueue::_Reschedule()
{
if (fStatus == B_OK) {
if (fUpdateRegion.Frame().IsValid())
release_sem(fThreadControl);
}
}