diff --git a/headers/os/game/DirectWindow.h b/headers/os/game/DirectWindow.h index 01ab10a3ce..19241677df 100644 --- a/headers/os/game/DirectWindow.h +++ b/headers/os/game/DirectWindow.h @@ -35,15 +35,14 @@ typedef struct { direct_buffer_state buffer_state; direct_driver_state driver_state; void *bits; - void *pci_bits; + addr_t _reserved; // was pci_bits int32 bytes_per_row; uint32 bits_per_pixel; color_space pixel_format; buffer_layout layout; buffer_orientation orientation; - uint32 _reserved[9]; - uint32 _dd_type_; - uint32 _dd_token_; + area_id bits_area; + uint32 _reserved1[10]; uint32 clip_list_count; clipping_rect window_bounds; clipping_rect clip_bounds; @@ -141,7 +140,7 @@ private: bool fConnectionEnable; bool fIsFullScreen; bool _unused; - bool fInDirectConnect; + bool fInDirectConnected; int32 fDirectLock; sem_id fDirectSem; uint32 fDirectLockCount; @@ -151,12 +150,12 @@ private: sem_id fDisableSemAck; uint32 fInitStatus; - uint32 fInfoAreaSize; uint32 _reserved[2]; - area_id fClonedClippingArea; - area_id fSourceClippingArea; + area_id fSourceDirectArea; + area_id fClonedDirectArea; + area_id fSourceBitsArea; thread_id fDirectDaemonId; direct_buffer_info* fBufferDesc; diff --git a/src/kits/game/DirectWindow.cpp b/src/kits/game/DirectWindow.cpp index 262bfb4cd3..a9053d1952 100644 --- a/src/kits/game/DirectWindow.cpp +++ b/src/kits/game/DirectWindow.cpp @@ -17,8 +17,10 @@ #include #include +#include #include #include +#include //#define DEBUG 1 @@ -128,7 +130,6 @@ print_direct_buffer_info(const direct_buffer_info &info) # if DEBUG > 1 OUTPUT("bits: %p\n", info.bits); - OUTPUT("pci_bits: %p\n", info.pci_bits); OUTPUT("bytes_per_row: %ld\n", info.bytes_per_row); OUTPUT("bits_per_pixel: %lu\n", info.bits_per_pixel); OUTPUT("pixel_format: %d\n", info.pixel_format); @@ -366,7 +367,7 @@ BDirectWindow::GetClippingRegion(BRegion* region, BPoint* origin) const if (IsLocked() || !_LockDirect()) return B_ERROR; - if (!fInDirectConnect) { + if (!fInDirectConnected) { _UnlockDirect(); return B_ERROR; } @@ -486,9 +487,29 @@ BDirectWindow::_DirectDaemon() == B_DIRECT_START) fConnectionEnable = true; - fInDirectConnect = true; + if (fBufferDesc->bits == NULL) { + // (re-)clone the bits area + BPrivate::AppServerLink linkLocker; + // protects ServerAllocator + BPrivate::ServerMemoryAllocator* allocator + = BApplication::Private::ServerAllocator(); + allocator->RemoveArea(fSourceBitsArea); + area_id localArea; + uint8* bits; + status_t status = allocator->AddArea(fBufferDesc->bits_area, + localArea, bits, (size_t)-1); + if (status != B_OK) { + _UnlockDirect(); + return -1; + } + + fBufferDesc->bits = (void*)bits; + fSourceBitsArea = fBufferDesc->bits_area; + } + + fInDirectConnected = true; DirectConnected(fBufferDesc); - fInDirectConnect = false; + fInDirectConnected = false; if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP) @@ -559,7 +580,7 @@ BDirectWindow::_InitData() { fConnectionEnable = false; fIsFullScreen = false; - fInDirectConnect = false; + fInDirectConnected = false; fInitStatus = 0; @@ -583,14 +604,16 @@ BDirectWindow::_InitData() fInitStatus |= DW_STATUS_SEM_CREATED; #endif - fSourceClippingArea = syncData.area; + fSourceDirectArea = syncData.area; fDisableSem = syncData.disable_sem; fDisableSemAck = syncData.disable_sem_ack; - fClonedClippingArea = clone_area("cloned direct area", (void**)&fBufferDesc, - B_ANY_ADDRESS, B_READ_AREA, fSourceClippingArea); + fClonedDirectArea = clone_area("cloned direct area", (void**)&fBufferDesc, + B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, fSourceDirectArea); - if (fClonedClippingArea > 0) { + fSourceBitsArea = -1; + + if (fClonedDirectArea > 0) { fInitStatus |= DW_STATUS_AREA_CLONED; fDirectDaemonId = spawn_thread(_daemon_thread, "direct daemon", @@ -633,7 +656,7 @@ BDirectWindow::_DisposeData() #endif if (fInitStatus & DW_STATUS_AREA_CLONED) - delete_area(fClonedClippingArea); + delete_area(fClonedDirectArea); } diff --git a/src/servers/app/DirectWindowInfo.cpp b/src/servers/app/DirectWindowInfo.cpp index aadbe66696..88c2ada8b9 100644 --- a/src/servers/app/DirectWindowInfo.cpp +++ b/src/servers/app/DirectWindowInfo.cpp @@ -15,6 +15,7 @@ #include #include +#include #include "RenderingBuffer.h" #include "clipping.h" @@ -35,6 +36,7 @@ DirectWindowInfo::DirectWindowInfo() memset(fBufferInfo, 0, DIRECT_BUFFER_INFO_AREA_SIZE); fBufferInfo->buffer_state = B_DIRECT_STOP; + fBufferInfo->bits_area = -1; fSem = create_sem(0, "direct sem"); fAcknowledgeSem = create_sem(0, "direct sem ack"); @@ -92,9 +94,21 @@ DirectWindowInfo::SetState(direct_buffer_state bufferState, if ((int)driverState != -1) fBufferInfo->driver_state = driverState; - if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) { - fBufferInfo->bits = buffer->Bits(); - fBufferInfo->pci_bits = NULL; // TODO + if ((bufferState & B_BUFFER_RESET) != 0 || fBufferInfo->bits_area < 0) { + void* bits = buffer->Bits(); + if (IS_USER_ADDRESS(bits)) { + fBufferInfo->bits = NULL; + + area_id area = area_for(bits); + fBufferInfo->bits_area = area; + + // make sure the area is cloneable + set_area_protection(area, B_READ_AREA | B_WRITE_AREA | B_CLONEABLE_AREA); + } else { + // framebuffer is in kernel address space + // TODO: update all drivers and then drop this case! + fBufferInfo->bits = bits; + } fBufferInfo->bytes_per_row = buffer->BytesPerRow(); switch (buffer->ColorSpace()) { @@ -137,6 +151,9 @@ DirectWindowInfo::SetState(direct_buffer_state bufferState, fBufferInfo->layout = B_BUFFER_NONINTERLEAVED; fBufferInfo->orientation = B_BUFFER_TOP_TO_BOTTOM; // TODO + } + + if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) { fBufferInfo->window_bounds = to_clipping_rect(windowFrame); const int32 kMaxClipRectsCount = (DIRECT_BUFFER_INFO_AREA_SIZE @@ -150,7 +167,7 @@ DirectWindowInfo::SetState(direct_buffer_state bufferState, fBufferInfo->clip_list[i] = clipRegion.RectAtInt(i); } - return _SyncronizeWithClient(); + return _SynchronizeWithClient(); } @@ -171,7 +188,7 @@ DirectWindowInfo::DisableFullScreen() status_t -DirectWindowInfo::_SyncronizeWithClient() +DirectWindowInfo::_SynchronizeWithClient() { // Releasing this semaphore causes the client to call // BDirectWindow::DirectConnected() diff --git a/src/servers/app/DirectWindowInfo.h b/src/servers/app/DirectWindowInfo.h index 4a26ac98d0..5aa5a46d30 100644 --- a/src/servers/app/DirectWindowInfo.h +++ b/src/servers/app/DirectWindowInfo.h @@ -40,7 +40,7 @@ public: window_feel OriginalFeel() const { return fOriginalFeel; } private: - status_t _SyncronizeWithClient(); + status_t _SynchronizeWithClient(); direct_buffer_info* fBufferInfo; sem_id fSem; diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 408da96b27..9ecb85e7dc 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -3,6 +3,9 @@ SubDir HAIKU_TOP src servers app ; UseLibraryHeaders agg ; UsePrivateHeaders app graphics input interface shared storage support ; +UsePrivateKernelHeaders ; + # TODO: Remove! (only needed by DirectWindowInfo.cpp) + UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ; UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ; UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter drawing_modes ] ;