More encapsulation of directwindow stuff into DirectWindowData.

I changed lot of code (while trying to fix ticket #4311), reverted some old
changes and probably messed up a lot. It's very much a work in progress.
Anyway, DirectWindowStars still work correctly, but Chart (and GLTeapot) do
not. I suspect a race condition between the DirectWindow creation and
the activation of the direct mode on the server, maybe exposed more easily 
by the changes in the scheduler.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32625 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2009-08-23 07:08:39 +00:00
parent 97cccf16b0
commit f6ad8d5abb
4 changed files with 93 additions and 113 deletions
+72 -44
View File
@@ -9,7 +9,14 @@
#include "DirectWindowSupport.h" #include "DirectWindowSupport.h"
#include <Autolock.h>
#include "RenderingBuffer.h"
#include "clipping.h"
#include <string.h> #include <string.h>
#include <syslog.h>
DirectWindowData::DirectWindowData() DirectWindowData::DirectWindowData()
: :
@@ -89,55 +96,76 @@ DirectWindowData::SyncronizeWithClient()
bool bool
DirectWindowData::SetState(const direct_buffer_state& bufferState, DirectWindowData::SetState(const direct_buffer_state& bufferState,
const direct_driver_state& driverState) const direct_driver_state& driverState, RenderingBuffer *buffer,
const BRect& windowFrame, const BRegion& clipRegion)
{ {
BufferState inputState(bufferState); bool wasStopped = fTransition <= 0;
BufferState currentState(buffer_info->buffer_state);
bool handle = false; if ((bufferState & B_DIRECT_MODE_MASK) == B_DIRECT_STOP)
fTransition--;
else if ((bufferState & B_DIRECT_MODE_MASK) == B_DIRECT_START)
fTransition++;
if (inputState.Action() == B_DIRECT_STOP) bool isStopped = fTransition <= 0;
handle = _HandleStop(bufferState);
else if (inputState.Action() == B_DIRECT_START) if (wasStopped && isStopped)
handle = _HandleStart(bufferState); return false;
else if (inputState.Action() == B_DIRECT_MODIFY)
handle = _HandleModify(bufferState); buffer_info->buffer_state = bufferState;
if (driverState != -1) if (driverState != -1)
buffer_info->driver_state = driverState; buffer_info->driver_state = driverState;
return handle; if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) {
} buffer_info->bits = buffer->Bits();
buffer_info->pci_bits = NULL; // TODO
buffer_info->bytes_per_row = buffer->BytesPerRow();
bool
DirectWindowData::_HandleStop(const direct_buffer_state& state) switch (buffer->ColorSpace()) {
{ case B_RGB32:
buffer_info->buffer_state = B_DIRECT_STOP; case B_RGBA32:
if (fTransition-- >= 1) case B_RGB32_BIG:
return true; case B_RGBA32_BIG:
return false; buffer_info->bits_per_pixel = 32;
} break;
case B_RGB24:
case B_RGB24_BIG:
bool buffer_info->bits_per_pixel = 24;
DirectWindowData::_HandleStart(const direct_buffer_state& state) break;
{ case B_RGB16:
buffer_info->buffer_state = (direct_buffer_state) case B_RGB16_BIG:
(BufferState(buffer_info->buffer_state).Reason() | state); case B_RGB15:
if (fTransition++ >= 0) case B_RGB15_BIG:
return true; buffer_info->bits_per_pixel = 16;
break;
return false; case B_CMAP8:
} case B_GRAY8:
buffer_info->bits_per_pixel = 8;
break;
bool default:
DirectWindowData::_HandleModify(const direct_buffer_state& state) syslog(LOG_ERR,
{ "unknown colorspace in DirectWindowData::SetState()!\n");
buffer_info->buffer_state = state; buffer_info->bits_per_pixel = 0;
if (fTransition > 0) break;
return true; }
return false; buffer_info->pixel_format = buffer->ColorSpace();
buffer_info->layout = B_BUFFER_NONINTERLEAVED;
buffer_info->orientation = B_BUFFER_TOP_TO_BOTTOM;
// TODO
buffer_info->window_bounds = to_clipping_rect(windowFrame);
// TODO: Review this
const int32 kMaxClipRectsCount = (DIRECT_BUFFER_INFO_AREA_SIZE
- sizeof(direct_buffer_info)) / sizeof(clipping_rect);
buffer_info->clip_list_count = min_c(clipRegion.CountRects(),
kMaxClipRectsCount);
buffer_info->clip_bounds = clipRegion.FrameInt();
for (uint32 i = 0; i < buffer_info->clip_list_count; i++)
buffer_info->clip_list[i] = clipRegion.RectAtInt(i);
}
return true;
} }
+8 -2
View File
@@ -4,10 +4,13 @@
* *
*/ */
#include <Autolock.h>
#include <DirectWindow.h> #include <DirectWindow.h>
#include <DirectWindowPrivate.h> #include <DirectWindowPrivate.h>
class RenderingBuffer;
struct BufferState { struct BufferState {
BufferState(const direct_buffer_state& state) BufferState(const direct_buffer_state& state)
: :
@@ -41,7 +44,10 @@ public:
status_t SyncronizeWithClient(); status_t SyncronizeWithClient();
bool SetState(const direct_buffer_state& bufferState, bool SetState(const direct_buffer_state& bufferState,
const direct_driver_state& driverState); const direct_driver_state& driverState,
RenderingBuffer *renderingBuffer,
const BRect& windowFrame,
const BRegion& clipRegion);
BRect old_window_frame; BRect old_window_frame;
direct_buffer_info* buffer_info; direct_buffer_info* buffer_info;
@@ -50,11 +56,11 @@ public:
private: private:
bool _HandleStop(const direct_buffer_state& state); bool _HandleStop(const direct_buffer_state& state);
bool _HandleStart(const direct_buffer_state& state); bool _HandleStart(const direct_buffer_state& state);
bool _HandleModify(const direct_buffer_state& state);
sem_id fSem; sem_id fSem;
sem_id fAcknowledgeSem; sem_id fAcknowledgeSem;
area_id fBufferArea; area_id fBufferArea;
direct_buffer_state fPreviousState;
int32 fTransition; int32 fTransition;
}; };
+15 -68
View File
@@ -3483,78 +3483,25 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
if (fDirectWindowData == NULL) if (fDirectWindowData == NULL)
return; return;
if (!fDirectWindowData->SetState((direct_buffer_state)bufferState, if (fDesktop->LockSingleWindow()) {
(direct_driver_state)driverState)) if (!fDirectWindowData->SetState((direct_buffer_state)bufferState,
return; (direct_driver_state)driverState,
fDesktop->HWInterface()->FrontBuffer(), fWindow->Frame(),
if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) { fWindow->VisibleContentRegion())) {
// TODO: Locking ? fDesktop->UnlockSingleWindow();
RenderingBuffer *buffer = fDesktop->HWInterface()->FrontBuffer(); return;
fDirectWindowData->buffer_info->bits = buffer->Bits();
fDirectWindowData->buffer_info->pci_bits = NULL; // TODO
fDirectWindowData->buffer_info->bytes_per_row = buffer->BytesPerRow();
switch (buffer->ColorSpace()) {
case B_RGB32:
case B_RGBA32:
case B_RGB32_BIG:
case B_RGBA32_BIG:
fDirectWindowData->buffer_info->bits_per_pixel = 32;
break;
case B_RGB24:
case B_RGB24_BIG:
fDirectWindowData->buffer_info->bits_per_pixel = 24;
break;
case B_RGB16:
case B_RGB16_BIG:
case B_RGB15:
case B_RGB15_BIG:
fDirectWindowData->buffer_info->bits_per_pixel = 16;
break;
case B_CMAP8:
case B_GRAY8:
fDirectWindowData->buffer_info->bits_per_pixel = 8;
break;
default:
syslog(LOG_ERR,
"unknown colorspace in HandleDirectConnection()!\n");
fDirectWindowData->buffer_info->bits_per_pixel = 0;
break;
} }
fDirectWindowData->buffer_info->pixel_format = buffer->ColorSpace(); status_t status = fDirectWindowData->SyncronizeWithClient();
fDirectWindowData->buffer_info->layout = B_BUFFER_NONINTERLEAVED;
fDirectWindowData->buffer_info->orientation = B_BUFFER_TOP_TO_BOTTOM;
// TODO
fDirectWindowData->buffer_info->window_bounds
= to_clipping_rect(fWindow->Frame());
// TODO: Review this if (status != B_OK) {
const int32 kMaxClipRectsCount = (DIRECT_BUFFER_INFO_AREA_SIZE // The client application didn't release the semaphore
- sizeof(direct_buffer_info)) / sizeof(clipping_rect); // within the given timeout. Or something else went wrong.
// Deleting this member should make it crash.
// We just want the region inside the window, border excluded. delete fDirectWindowData;
BRegion clipRegion = fWindow->VisibleContentRegion(); fDirectWindowData = NULL;
fDirectWindowData->buffer_info->clip_list_count
= min_c(clipRegion.CountRects(), kMaxClipRectsCount);
fDirectWindowData->buffer_info->clip_bounds = clipRegion.FrameInt();
for (uint32 i = 0; i < fDirectWindowData->buffer_info->clip_list_count;
i++) {
fDirectWindowData->buffer_info->clip_list[i]
= clipRegion.RectAtInt(i);
} }
} fDesktop->UnlockSingleWindow();
status_t status = fDirectWindowData->SyncronizeWithClient();
if (status != B_OK) {
// The client application didn't release the semaphore
// within the given timeout. Or something else went wrong.
// Deleting this member should make it crash.
delete fDirectWindowData;
fDirectWindowData = NULL;
} }
} }
-1
View File
@@ -214,7 +214,6 @@ Window::SetClipping(BRegion* stillAvailableOnScreen)
fVisibleContentRegionValid = false; fVisibleContentRegionValid = false;
fEffectiveDrawingRegionValid = false; fEffectiveDrawingRegionValid = false;
// TODO: review this!
fWindow->HandleDirectConnection(B_DIRECT_MODIFY | B_CLIPPING_MODIFIED); fWindow->HandleDirectConnection(B_DIRECT_MODIFY | B_CLIPPING_MODIFIED);
} }