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