diff --git a/src/servers/app/DirectWindowSupport.cpp b/src/servers/app/DirectWindowSupport.cpp index bdba5c2aa3..a174b54784 100644 --- a/src/servers/app/DirectWindowSupport.cpp +++ b/src/servers/app/DirectWindowSupport.cpp @@ -9,7 +9,14 @@ #include "DirectWindowSupport.h" +#include + +#include "RenderingBuffer.h" +#include "clipping.h" + #include +#include + DirectWindowData::DirectWindowData() : @@ -89,55 +96,76 @@ DirectWindowData::SyncronizeWithClient() bool DirectWindowData::SetState(const direct_buffer_state& bufferState, - const direct_driver_state& driverState) -{ - BufferState inputState(bufferState); - BufferState currentState(buffer_info->buffer_state); + const direct_driver_state& driverState, RenderingBuffer *buffer, + const BRect& windowFrame, const BRegion& clipRegion) +{ + bool wasStopped = fTransition <= 0; - bool handle = false; + if ((bufferState & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) + fTransition--; + else if ((bufferState & B_DIRECT_MODE_MASK) == B_DIRECT_START) + fTransition++; + + bool isStopped = fTransition <= 0; - if (inputState.Action() == B_DIRECT_STOP) - handle = _HandleStop(bufferState); - else if (inputState.Action() == B_DIRECT_START) - handle = _HandleStart(bufferState); - else if (inputState.Action() == B_DIRECT_MODIFY) - handle = _HandleModify(bufferState); + if (wasStopped && isStopped) + return false; + + buffer_info->buffer_state = bufferState; if (driverState != -1) 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(); + switch (buffer->ColorSpace()) { + case B_RGB32: + case B_RGBA32: + case B_RGB32_BIG: + case B_RGBA32_BIG: + buffer_info->bits_per_pixel = 32; + break; + case B_RGB24: + case B_RGB24_BIG: + buffer_info->bits_per_pixel = 24; + break; + case B_RGB16: + case B_RGB16_BIG: + case B_RGB15: + case B_RGB15_BIG: + buffer_info->bits_per_pixel = 16; + break; + case B_CMAP8: + case B_GRAY8: + buffer_info->bits_per_pixel = 8; + break; + default: + syslog(LOG_ERR, + "unknown colorspace in DirectWindowData::SetState()!\n"); + buffer_info->bits_per_pixel = 0; + break; + } -bool -DirectWindowData::_HandleStop(const direct_buffer_state& state) -{ - buffer_info->buffer_state = B_DIRECT_STOP; - if (fTransition-- >= 1) - 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); -bool -DirectWindowData::_HandleStart(const direct_buffer_state& state) -{ - buffer_info->buffer_state = (direct_buffer_state) - (BufferState(buffer_info->buffer_state).Reason() | state); - if (fTransition++ >= 0) - return true; + 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 false; -} - - -bool -DirectWindowData::_HandleModify(const direct_buffer_state& state) -{ - buffer_info->buffer_state = state; - if (fTransition > 0) - return true; - - return false; + return true; } diff --git a/src/servers/app/DirectWindowSupport.h b/src/servers/app/DirectWindowSupport.h index 4060b9f55e..1581112d2e 100644 --- a/src/servers/app/DirectWindowSupport.h +++ b/src/servers/app/DirectWindowSupport.h @@ -4,10 +4,13 @@ * */ +#include #include #include +class RenderingBuffer; + struct BufferState { BufferState(const direct_buffer_state& state) : @@ -41,8 +44,11 @@ public: status_t SyncronizeWithClient(); 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; direct_buffer_info* buffer_info; bool full_screen; @@ -50,11 +56,11 @@ public: private: bool _HandleStop(const direct_buffer_state& state); bool _HandleStart(const direct_buffer_state& state); - bool _HandleModify(const direct_buffer_state& state); sem_id fSem; sem_id fAcknowledgeSem; area_id fBufferArea; + direct_buffer_state fPreviousState; int32 fTransition; }; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 9b2873e4ea..1e25db34a0 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -3483,78 +3483,25 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState) if (fDirectWindowData == NULL) return; - if (!fDirectWindowData->SetState((direct_buffer_state)bufferState, - (direct_driver_state)driverState)) - return; - - if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) { - // TODO: Locking ? - RenderingBuffer *buffer = fDesktop->HWInterface()->FrontBuffer(); - 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; + if (fDesktop->LockSingleWindow()) { + if (!fDirectWindowData->SetState((direct_buffer_state)bufferState, + (direct_driver_state)driverState, + fDesktop->HWInterface()->FrontBuffer(), fWindow->Frame(), + fWindow->VisibleContentRegion())) { + fDesktop->UnlockSingleWindow(); + return; } + + status_t status = fDirectWindowData->SyncronizeWithClient(); - fDirectWindowData->buffer_info->pixel_format = buffer->ColorSpace(); - 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 - const int32 kMaxClipRectsCount = (DIRECT_BUFFER_INFO_AREA_SIZE - - sizeof(direct_buffer_info)) / sizeof(clipping_rect); - - // We just want the region inside the window, border excluded. - BRegion clipRegion = fWindow->VisibleContentRegion(); - - 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); + 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; } - } - - 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; + fDesktop->UnlockSingleWindow(); } } diff --git a/src/servers/app/Window.cpp b/src/servers/app/Window.cpp index 5339b55ec9..c00376b383 100644 --- a/src/servers/app/Window.cpp +++ b/src/servers/app/Window.cpp @@ -214,7 +214,6 @@ Window::SetClipping(BRegion* stillAvailableOnScreen) fVisibleContentRegionValid = false; fEffectiveDrawingRegionValid = false; - // TODO: review this! fWindow->HandleDirectConnection(B_DIRECT_MODIFY | B_CLIPPING_MODIFIED); }