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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user