Commit bf4cf189 authored by Nathan Heisey's avatar Nathan Heisey

Moved draw code to a separate thread

parent 350e15ee
...@@ -37,6 +37,7 @@ extern "C" { ...@@ -37,6 +37,7 @@ extern "C" {
/* Local includes */ /* Local includes */
#include "../../events/SDL_events_c.h" #include "../../events/SDL_events_c.h"
#include "../../video/bwindow/SDL_bkeyboard.h" #include "../../video/bwindow/SDL_bkeyboard.h"
#include "../../video/bwindow/SDL_bmodes.h"
#ifdef __cplusplus #ifdef __cplusplus
} }
...@@ -167,7 +168,7 @@ public: ...@@ -167,7 +168,7 @@ public:
int32 GetID(SDL_Window *win) { int32 GetID(SDL_Window *win) {
int32 i; int32 i;
for(i = 0; i < _GetNumWindowSlots(); ++i) { for(i = 0; i < _GetNumWindowSlots(); ++i) {
if( _GetSDLWindow(i) == NULL ) { if( GetSDLWindow(i) == NULL ) {
_SetSDLWindow(win, i); _SetSDLWindow(win, i);
return i; return i;
} }
...@@ -189,6 +190,11 @@ public: ...@@ -189,6 +190,11 @@ public:
there another way to do this? */ there another way to do this? */
void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */ void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */
SDL_Window *GetSDLWindow(int32 winID) {
return window_map[winID];
}
private: private:
/* Event management */ /* Event management */
void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) { void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) {
...@@ -199,7 +205,7 @@ private: ...@@ -199,7 +205,7 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
SDL_SendWindowEvent(win, sdlEventType, 0, 0); SDL_SendWindowEvent(win, sdlEventType, 0, 0);
} }
...@@ -214,8 +220,11 @@ private: ...@@ -214,8 +220,11 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
SDL_SendMouseMotion(win, 0, x, y); SDL_SendMouseMotion(win, 0, x, y);
/* FIXME: Attempt at fixing rendering problems */
BE_UpdateWindowFramebuffer(NULL,win,NULL,-1);
} }
void _HandleMouseButton(BMessage *msg) { void _HandleMouseButton(BMessage *msg) {
...@@ -229,7 +238,7 @@ private: ...@@ -229,7 +238,7 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
SDL_SendMouseButton(win, state, button); SDL_SendMouseButton(win, state, button);
} }
...@@ -244,7 +253,7 @@ private: ...@@ -244,7 +253,7 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
SDL_SendMouseWheel(win, xTicks, yTicks); SDL_SendMouseWheel(win, xTicks, yTicks);
} }
...@@ -275,7 +284,7 @@ private: ...@@ -275,7 +284,7 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
if(bSetFocus) { if(bSetFocus) {
SDL_SetMouseFocus(win); SDL_SetMouseFocus(win);
} else if(SDL_GetMouseFocus() == win) { } else if(SDL_GetMouseFocus() == win) {
...@@ -294,7 +303,7 @@ private: ...@@ -294,7 +303,7 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
if(bSetFocus) { if(bSetFocus) {
SDL_SetKeyboardFocus(win); SDL_SetKeyboardFocus(win);
} else if(SDL_GetKeyboardFocus() == win) { } else if(SDL_GetKeyboardFocus() == win) {
...@@ -315,8 +324,11 @@ private: ...@@ -315,8 +324,11 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos); SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos);
/* FIXME: Attempt at fixing rendering problems */
BE_UpdateWindowFramebuffer(NULL,win,NULL,-1);
} }
void _HandleWindowResized(BMessage *msg) { void _HandleWindowResized(BMessage *msg) {
...@@ -331,8 +343,11 @@ private: ...@@ -331,8 +343,11 @@ private:
) { ) {
return; return;
} }
win = _GetSDLWindow(winID); win = GetSDLWindow(winID);
SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h); SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h);
/* FIXME: Attempt at fixing rendering problems */
BE_UpdateWindowFramebuffer(NULL,win,NULL,-1);
} }
bool _GetWinID(BMessage *msg, int32 *winID) { bool _GetWinID(BMessage *msg, int32 *winID) {
...@@ -342,10 +357,6 @@ private: ...@@ -342,10 +357,6 @@ private:
/* Vector imitators */ /* Vector imitators */
SDL_Window *_GetSDLWindow(int32 winID) {
return window_map[winID];
}
void _SetSDLWindow(SDL_Window *win, int32 winID) { void _SetSDLWindow(SDL_Window *win, int32 winID) {
window_map[winID] = win; window_map[winID] = win;
} }
......
...@@ -126,7 +126,7 @@ SDL_QuitBeApp(void) ...@@ -126,7 +126,7 @@ SDL_QuitBeApp(void)
void SDL_BApp::ClearID(SDL_BWin *bwin) { void SDL_BApp::ClearID(SDL_BWin *bwin) {
_SetSDLWindow(NULL, bwin->GetID()); _SetSDLWindow(NULL, bwin->GetID());
int32 i = _GetNumWindowSlots() - 1; int32 i = _GetNumWindowSlots() - 1;
while(i >= 0 && _GetSDLWindow(i) == NULL) { while(i >= 0 && GetSDLWindow(i) == NULL) {
_PopBackWindow(); _PopBackWindow();
--i; --i;
} }
......
...@@ -76,9 +76,14 @@ class SDL_BWin:public BDirectWindow ...@@ -76,9 +76,14 @@ class SDL_BWin:public BDirectWindow
/* Handle framebuffer stuff */ /* Handle framebuffer stuff */
_connected = _connection_disabled = false; _connected = _connection_disabled = false;
_buffer_created = _buffer_dirty = false;
_trash__window_buffer = false; _trash__window_buffer = false;
_buffer_locker = new BLocker(); _buffer_locker = new BLocker();
_window_buffer = NULL; _window_buffer = NULL;
_draw_thread_id = spawn_thread(BE_DrawThread, "drawing_thread",
B_NORMAL_PRIORITY, (void*) this);
resume_thread(_draw_thread_id);
// LockBuffer(); /* Unlocked by buffer initialization */ // LockBuffer(); /* Unlocked by buffer initialization */
} }
...@@ -86,6 +91,7 @@ class SDL_BWin:public BDirectWindow ...@@ -86,6 +91,7 @@ class SDL_BWin:public BDirectWindow
{ {
Lock(); Lock();
_connection_disabled = true; _connection_disabled = true;
int32 result;
#if SDL_VIDEO_OPENGL #if SDL_VIDEO_OPENGL
if (_SDL_GLView) { if (_SDL_GLView) {
...@@ -102,6 +108,7 @@ class SDL_BWin:public BDirectWindow ...@@ -102,6 +108,7 @@ class SDL_BWin:public BDirectWindow
/* Clean up framebuffer stuff */ /* Clean up framebuffer stuff */
_buffer_locker->Lock(); _buffer_locker->Lock();
wait_for_thread(_draw_thread_id, &result);
free(_clips); free(_clips);
delete _buffer_locker; delete _buffer_locker;
} }
...@@ -382,8 +389,6 @@ class SDL_BWin:public BDirectWindow ...@@ -382,8 +389,6 @@ class SDL_BWin:public BDirectWindow
/* Accessor methods */ /* Accessor methods */
bool IsShown() { return _shown; } bool IsShown() { return _shown; }
int32 GetID() { return _id; } int32 GetID() { return _id; }
void LockBuffer() { _buffer_locker->Lock(); }
void UnlockBuffer() { _buffer_locker->Unlock(); }
uint32 GetRowBytes() { return _row_bytes; } uint32 GetRowBytes() { return _row_bytes; }
int32 GetFbX() { return _bounds.left; } int32 GetFbX() { return _bounds.left; }
int32 GetFbY() { return _bounds.top; } int32 GetFbY() { return _bounds.top; }
...@@ -395,12 +400,18 @@ class SDL_BWin:public BDirectWindow ...@@ -395,12 +400,18 @@ class SDL_BWin:public BDirectWindow
int32 GetNumClips() { return _num_clips; } int32 GetNumClips() { return _num_clips; }
uint8* GetBufferPx() { return _bits; } uint8* GetBufferPx() { return _bits; }
int32 GetBytesPerPx() { return _bytes_per_px; } int32 GetBytesPerPx() { return _bytes_per_px; }
void SetWindowFramebuffer(uint8* fb) { _window_buffer = fb; }
uint8* GetWindowFramebuffer() { return _window_buffer; } uint8* GetWindowFramebuffer() { return _window_buffer; }
bool CanTrashWindowBuffer() { return _trash__window_buffer; } bool CanTrashWindowBuffer() { return _trash__window_buffer; }
bool BufferExists() { return _buffer_created; }
bool BufferIsDirty() { return _buffer_dirty; }
/* Setter methods */ /* Setter methods */
void SetID(int32 id) { _id = id; } void SetID(int32 id) { _id = id; }
bool SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; }
void SetWindowFramebuffer(uint8* fb) { _window_buffer = fb; }
void LockBuffer() { _buffer_locker->Lock(); }
void UnlockBuffer() { _buffer_locker->Unlock(); }
void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; }
...@@ -416,10 +427,6 @@ class SDL_BWin:public BDirectWindow ...@@ -416,10 +427,6 @@ class SDL_BWin:public BDirectWindow
{ {
return (_the_view); return (_the_view);
} }
...@@ -584,7 +591,10 @@ private: ...@@ -584,7 +591,10 @@ private:
BRect *_prev_frame; /* Previous position and size of the window */ BRect *_prev_frame; /* Previous position and size of the window */
/* Framebuffer members */ /* Framebuffer members */
bool _connected, _connection_disabled; bool _connected,
_connection_disabled,
_buffer_created,
_buffer_dirty;
uint8 *_bits; uint8 *_bits;
uint32 _row_bytes; uint32 _row_bytes;
clipping_rect _bounds; clipping_rect _bounds;
...@@ -594,6 +604,7 @@ private: ...@@ -594,6 +604,7 @@ private:
int32 _bytes_per_px; int32 _bytes_per_px;
uint8 *_window_buffer; /* A copy of the window buffer */ uint8 *_window_buffer; /* A copy of the window buffer */
bool _trash__window_buffer; bool _trash__window_buffer;
thread_id _draw_thread_id;
}; };
#endif #endif
...@@ -218,7 +218,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, ...@@ -218,7 +218,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
return -1; return -1;
} }
while(!bwin->Connected()) { snooze(10); } while(!bwin->Connected()) { snooze(100); }
/* Make sure we have exclusive access to frame buffer data */ /* Make sure we have exclusive access to frame buffer data */
bwin->LockBuffer(); bwin->LockBuffer();
...@@ -243,6 +243,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, ...@@ -243,6 +243,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
bwin->SetWindowFramebuffer((uint8*)(*pixels)); bwin->SetWindowFramebuffer((uint8*)(*pixels));
} }
bwin->SetBufferExists(true);
bwin->UnlockBuffer(); bwin->UnlockBuffer();
return 0; return 0;
} }
...@@ -251,51 +252,72 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, ...@@ -251,51 +252,72 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
SDL_Rect * rects, int numrects) { SDL_Rect * rects, int numrects) {
if(!window)
return 0;
SDL_BWin *bwin = _ToBeWin(window); SDL_BWin *bwin = _ToBeWin(window);
bwin->LockBuffer();
bwin->SetBufferDirty(true);
bwin->UnlockBuffer();
return 0;
}
int32 BE_DrawThread(void *data) {
SDL_BWin *bwin = (SDL_BWin*)data;
SDL_Window *window = _GetBeApp()->GetSDLWindow(bwin->GetID());
BScreen bscreen; BScreen bscreen;
if(!bscreen.IsValid()) { if(!bscreen.IsValid()) {
return -1; return -1;
} }
if(bwin->ConnectionEnabled() && bwin->Connected()) { while(bwin->ConnectionEnabled()) {
bwin->LockBuffer(); if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
int32 windowPitch = window->surface->pitch; bwin->LockBuffer();
int32 bufferPitch = bwin->GetRowBytes(); int32 windowPitch = window->surface->pitch;
uint8 *windowpx; int32 bufferPitch = bwin->GetRowBytes();
uint8 *bufferpx; uint8 *windowpx;
uint8 *bufferpx;
int32 BPP = bwin->GetBytesPerPx();
uint8 *windowBaseAddress = (uint8*)window->surface->pixels; int32 BPP = bwin->GetBytesPerPx();
int32 windowSub = bwin->GetFbX() * BPP + uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
int32 windowSub = bwin->GetFbX() * BPP +
bwin->GetFbY() * windowPitch; bwin->GetFbY() * windowPitch;
clipping_rect *clips = bwin->GetClips(); clipping_rect *clips = bwin->GetClips();
int32 numClips = bwin->GetNumClips(); int32 numClips = bwin->GetNumClips();
int i, y; int i, y;
/* Blit each clipping rectangle */ /* Blit each clipping rectangle */
bscreen.WaitForRetrace(); bscreen.WaitForRetrace();
for(i = 0; i < numClips; ++i) { for(i = 0; i < numClips; ++i) {
clipping_rect rc = clips[i]; clipping_rect rc = clips[i];
/* Get addresses of the start of each clipping rectangle */ /* Get addresses of the start of each clipping rectangle */
int32 width = clips[i].right - clips[i].left + 1; int32 width = clips[i].right - clips[i].left + 1;
int32 height = clips[i].bottom - clips[i].top + 1; int32 height = clips[i].bottom - clips[i].top + 1;
bufferpx = bwin->GetBufferPx() + bufferpx = bwin->GetBufferPx() +
clips[i].top * bufferPitch + clips[i].left * BPP; clips[i].top * bufferPitch + clips[i].left * BPP;
windowpx = windowBaseAddress + windowpx = windowBaseAddress +
clips[i].top * windowPitch + clips[i].left * BPP - windowSub; clips[i].top * windowPitch + clips[i].left * BPP - windowSub;
/* Copy each row of pixels from the window buffer into the frame /* Copy each row of pixels from the window buffer into the frame
buffer */ buffer */
for(y = 0; y < height; ++y) for(y = 0; y < height; ++y)
{ {
memcpy(bufferpx, windowpx, width * BPP); memcpy(bufferpx, windowpx, width * BPP);
bufferpx += bufferPitch; bufferpx += bufferPitch;
windowpx += windowPitch; windowpx += windowPitch;
}
} }
bwin->SetBufferDirty(false);
bwin->UnlockBuffer();
} else {
snooze(1000);
} }
bwin->UnlockBuffer();
} }
return 0;
return B_OK;
} }
void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
...@@ -307,6 +329,7 @@ void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { ...@@ -307,6 +329,7 @@ void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
uint8* winBuffer = bwin->GetWindowFramebuffer(); uint8* winBuffer = bwin->GetWindowFramebuffer();
SDL_free(winBuffer); SDL_free(winBuffer);
bwin->SetWindowFramebuffer(NULL); bwin->SetWindowFramebuffer(NULL);
bwin->SetBufferExists(false);
bwin->UnlockBuffer(); bwin->UnlockBuffer();
} }
......
...@@ -42,6 +42,7 @@ extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, ...@@ -42,6 +42,7 @@ extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
SDL_Rect * rects, int numrects); SDL_Rect * rects, int numrects);
extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window); extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
extern int32 BE_DrawThread(void *data);
#ifdef __cplusplus #ifdef __cplusplus
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment