Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Moved draw code to a separate thread
Browse files Browse the repository at this point in the history
  • Loading branch information
antifinidictor committed Jul 27, 2011
1 parent 320518f commit 722973e
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 58 deletions.
37 changes: 24 additions & 13 deletions src/main/beos/SDL_BApp.h
Expand Up @@ -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
}
Expand Down Expand Up @@ -167,7 +168,7 @@ class SDL_BApp : public BApplication {
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;
}
Expand All @@ -189,6 +190,11 @@ class SDL_BApp : public BApplication {
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) {
Expand All @@ -199,7 +205,7 @@ class SDL_BApp : public BApplication {
) {
return;
}
win = _GetSDLWindow(winID);
win = GetSDLWindow(winID);
SDL_SendWindowEvent(win, sdlEventType, 0, 0);
}

Expand All @@ -214,8 +220,11 @@ class SDL_BApp : public BApplication {
) {
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) {
Expand All @@ -229,7 +238,7 @@ class SDL_BApp : public BApplication {
) {
return;
}
win = _GetSDLWindow(winID);
win = GetSDLWindow(winID);
SDL_SendMouseButton(win, state, button);
}

Expand All @@ -244,7 +253,7 @@ class SDL_BApp : public BApplication {
) {
return;
}
win = _GetSDLWindow(winID);
win = GetSDLWindow(winID);
SDL_SendMouseWheel(win, xTicks, yTicks);
}

Expand Down Expand Up @@ -275,7 +284,7 @@ class SDL_BApp : public BApplication {
) {
return;
}
win = _GetSDLWindow(winID);
win = GetSDLWindow(winID);
if(bSetFocus) {
SDL_SetMouseFocus(win);
} else if(SDL_GetMouseFocus() == win) {
Expand All @@ -294,7 +303,7 @@ class SDL_BApp : public BApplication {
) {
return;
}
win = _GetSDLWindow(winID);
win = GetSDLWindow(winID);
if(bSetFocus) {
SDL_SetKeyboardFocus(win);
} else if(SDL_GetKeyboardFocus() == win) {
Expand All @@ -315,8 +324,11 @@ class SDL_BApp : public BApplication {
) {
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) {
Expand All @@ -331,8 +343,11 @@ class SDL_BApp : public BApplication {
) {
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) {
Expand All @@ -342,10 +357,6 @@ class SDL_BApp : public BApplication {


/* Vector imitators */
SDL_Window *_GetSDLWindow(int32 winID) {
return window_map[winID];
}

void _SetSDLWindow(SDL_Window *win, int32 winID) {
window_map[winID] = win;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/beos/SDL_BeApp.cc
Expand Up @@ -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;
}
Expand Down
27 changes: 19 additions & 8 deletions src/video/bwindow/SDL_BWin.h
Expand Up @@ -76,16 +76,22 @@ 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 */
}

virtual ~ SDL_BWin()
{
Lock();
_connection_disabled = true;
int32 result;

#if SDL_VIDEO_OPENGL
if (_SDL_GLView) {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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; }
Expand All @@ -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; }



Expand All @@ -416,10 +427,6 @@ class SDL_BWin:public BDirectWindow
{
return (_the_view);
}







Expand Down Expand Up @@ -584,7 +591,10 @@ class SDL_BWin:public BDirectWindow
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;
Expand All @@ -594,6 +604,7 @@ class SDL_BWin:public BDirectWindow
int32 _bytes_per_px;
uint8 *_window_buffer; /* A copy of the window buffer */
bool _trash__window_buffer;
thread_id _draw_thread_id;
};

#endif
95 changes: 59 additions & 36 deletions src/video/bwindow/SDL_bmodes.cc
Expand Up @@ -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();
Expand All @@ -243,6 +243,7 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
bwin->SetWindowFramebuffer((uint8*)(*pixels));
}

bwin->SetBufferExists(true);
bwin->UnlockBuffer();
return 0;
}
Expand All @@ -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;

int32 BPP = bwin->GetBytesPerPx();
uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
int32 windowSub = bwin->GetFbX() * BPP +
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 +
bwin->GetFbY() * windowPitch;
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;

/* 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;
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;

/* 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) {
Expand All @@ -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();
}

Expand Down
1 change: 1 addition & 0 deletions src/video/bwindow/SDL_bmodes.h
Expand Up @@ -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
Expand Down

0 comments on commit 722973e

Please sign in to comment.