BDirectWindow: Clone the framebuffer from app_server, if necessary.
This paves the way for accelerants to map the framebuffer in user memory, not kernel memory. It uses the ServerMemoryAllocator in order to avoid mapping the framebuffer multiple times in client applications. While at it, clean up some names. Tested with DirectWindowStars and GLTeapot, both work. Change-Id: I4e0c003fae99891044af0a5e6e1d6a4506da6430 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10571 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
ede14380e5
commit
f6be811473
@@ -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;
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
|
||||
#include <clipping.h>
|
||||
#include <AppServerLink.h>
|
||||
#include <ApplicationPrivate.h>
|
||||
#include <DirectWindowPrivate.h>
|
||||
#include <ServerProtocol.h>
|
||||
#include <ServerMemoryAllocator.h>
|
||||
|
||||
|
||||
//#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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <syslog.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <kernel.h>
|
||||
|
||||
#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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ] ;
|
||||
|
||||
Reference in New Issue
Block a user