Drawing code works, but it flashes
authorNathan Heisey <nathanheisey@gmail.com>
Fri, 22 Jul 2011 12:39:53 +0000
changeset 5922 efd1498efdff
parent 5921 4cec9ba57dfb
child 5923 460ce3fb104c
Drawing code works, but it flashes
src/main/beos/SDL_BApp.h
src/main/beos/SDL_BeApp.cc
src/main/beos/SDL_BeApp.h
src/video/bwindow/SDL_BWin.h
src/video/bwindow/SDL_bmodes.cc
src/video/bwindow/SDL_bmodes.h
src/video/bwindow/SDL_bwindow.cc
src/video/bwindow/SDL_bwindow.h
--- a/src/main/beos/SDL_BApp.h	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/main/beos/SDL_BApp.h	Fri Jul 22 12:39:53 2011 +0000
@@ -21,11 +21,14 @@
 #ifndef SDL_BAPP_H
 #define SDL_BAPP_H
 
+#include <InterfaceKit.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include "SDL_config.h"
+
 #include "SDL_video.h"
 
 /* Local includes */
@@ -173,6 +176,11 @@
     	}
     }
     
+    /* Modes methods */
+    void SetPrevMode(display_mode *prevMode) { saved_mode = prevMode; }
+    
+    display_mode* GetPrevMode() { return saved_mode; }
+    
     /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here.  Is
        there another way to do this? */
     void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */
@@ -387,6 +395,8 @@
 	int32 _length;
 	SDL_Window *window_map;
 #endif
+
+	display_mode *saved_mode;
 };
 
 #endif
--- a/src/main/beos/SDL_BeApp.cc	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/main/beos/SDL_BeApp.cc	Fri Jul 22 12:39:53 2011 +0000
@@ -35,6 +35,9 @@
 
 #include "../../video/bwindow/SDL_BWin.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 /* Flag to tell whether or not the Be application is active or not */
 int SDL_BeAppActive = 0;
 static SDL_Thread *SDL_AppThread = NULL;
@@ -113,6 +116,12 @@
     }
 }
 
+
+/* vi: set ts=4 sw=4 expandtab: */
+#ifdef __cplusplus
+}
+#endif
+
 /* SDL_BApp functions */
 void SDL_BApp::ClearID(SDL_BWin *bwin) {
 	_SetSDLWindow(NULL, bwin->GetID());
@@ -122,6 +131,3 @@
 		--i;
 	}
 }
-
-/* vi: set ts=4 sw=4 expandtab: */
-
--- a/src/main/beos/SDL_BeApp.h	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/main/beos/SDL_BeApp.h	Fri Jul 22 12:39:53 2011 +0000
@@ -20,6 +20,10 @@
 */
 #include "SDL_config.h"
 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 /* Handle the BeApp specific portions of the application */
 
 /* Initialize the Be Application, if it's not already started */
@@ -31,3 +35,7 @@
 /* Flag to tell whether the app is active or not */
 extern int SDL_BeAppActive;
 /* vi: set ts=4 sw=4 expandtab: */
+
+#ifdef __cplusplus
+}
+#endif
--- a/src/video/bwindow/SDL_BWin.h	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/video/bwindow/SDL_BWin.h	Fri Jul 22 12:39:53 2011 +0000
@@ -76,11 +76,18 @@
         inhibit_resize = false;
         mouse_focused = false;
         prev_frame = NULL; printf("SDL_BWin.h: 79\n");
+        
+        /* Handle framebuffer stuff */
+        _connected = connection_disabled = false;
+        buffer_locker = new BLocker();
+//        LockBuffer();	/* Unlocked by buffer initialization */
     }
 
     virtual ~ SDL_BWin()
     {
         Lock();
+        connection_disabled = false;
+        
         if (the_view) {
 #if SDL_VIDEO_OPENGL
             if (the_view == SDL_GLView) {
@@ -99,6 +106,11 @@
         if (SDL_View) {
             delete SDL_View;
         }
+        
+        /* Clean up framebuffer stuff */
+        buffer_locker->Lock();
+        buffer_locker->Unlock();
+        delete buffer_locker;
     }
     
     
@@ -153,6 +165,41 @@
     
     /* * * * * Framebuffering* * * * */
     virtual void DirectConnected(direct_buffer_info *info) {
+    	if(!_connected && connection_disabled) {
+    		return;
+    	}
+    	LockBuffer();
+    	
+    	switch(info->buffer_state & B_DIRECT_MODE_MASK) {
+    	case B_DIRECT_START:
+printf("SDL_BWin.h: 175 Direct start.\n");
+    		_connected = true;
+
+    	case B_DIRECT_MODIFY:
+
+    		if(_clips) {
+    			free(_clips);
+    			_clips = NULL;
+    		}
+    		
+    		num_clips = info->clip_list_count;
+    		_clips = (clipping_rect *)malloc(num_clips*sizeof(clipping_rect));
+    		if(_clips) {
+    			memcpy(_clips, info->clip_list,
+    				num_clips*sizeof(clipping_rect));
+    			
+    			_bits = (uint8*) info->bits;
+    			row_bytes = info->bytes_per_row;
+    			_bounds = info->window_bounds;
+    		}
+    		
+    		break;
+
+    	case B_DIRECT_STOP:
+    		_connected = false;
+    		break;
+    	}
+    	UnlockBuffer();
     }
     
     
@@ -353,6 +400,18 @@
 	/* 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; }
+	int32 GetFbHeight() { return _bounds.bottom - _bounds.top + 1; }
+	int32 GetFbWidth() { return _bounds.right - _bounds.left + 1; }
+	bool ConnectionEnabled() { return !connection_disabled; }
+	bool Connected() { return _connected; }
+	clipping_rect *GetClips() { return _clips; }
+	int32 GetNumClips() { return num_clips; }
+	uint8* GetBufferPx() { return _bits; }
 	
 	/* Setter methods */
 	void SetID(int32 id) { _id = id; }
@@ -582,6 +641,15 @@
     bool inhibit_resize;
     
     BRect *prev_frame;	/* Previous position and size of the window */
+    
+    /* Framebuffer members */
+    bool			_connected, connection_disabled;
+    uint8			*_bits;
+    uint32			row_bytes;
+    clipping_rect	_bounds;
+    BLocker 		*buffer_locker;
+    clipping_rect	*_clips;
+    int32			num_clips;
 };
 
 #endif
--- a/src/video/bwindow/SDL_bmodes.cc	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/video/bwindow/SDL_bmodes.cc	Fri Jul 22 12:39:53 2011 +0000
@@ -24,6 +24,7 @@
 #include <AppKit.h>
 #include <InterfaceKit.h>
 #include "SDL_bmodes.h"
+#include "SDL_BWin.h"
 
 #include "../../main/beos/SDL_BApp.h"
 
@@ -31,6 +32,9 @@
 extern "C" {
 #endif
 
+static inline SDL_BWin *_ToBeWin(SDL_Window *window) {
+	return ((SDL_BWin*)(window->driverdata));
+}
 
 static inline SDL_BApp *_GetBeApp() {
 	return ((SDL_BApp*)be_app);
@@ -199,6 +203,95 @@
 	return -1;
 }
 
+
+
+int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
+                                       Uint32 * format,
+                                       void ** pixels, int *pitch) {
+	SDL_BWin *bwin = _ToBeWin(window);
+	BScreen bscreen;
+	if(!bscreen.IsValid()) {
+		return -1;
+	}
+	
+	while(!bwin->Connected()) { snooze(1600); }
+
+	/* Make sure we have exclusive access to frame buffer data */
+	bwin->LockBuffer();
+
+	/* format */
+	display_mode bmode;
+	bscreen.GetMode(&bmode);
+	int32 bpp = ColorSpaceToBitsPerPixel(bmode.space);
+	*format = BppToSDLPxFormat(bpp);
+
+	/* pitch = width of screen, in bytes */
+	*pitch = bpp * bwin->GetFbWidth() / 8;
+
+	/* Create a copy of the pixel buffer */
+	printf("SDL_bmodes.cc: 230; fbh: %i, pitch: %i; (x,y) = (%i, %i)\n", bwin->GetFbHeight(), (*pitch), bwin->GetFbX(), bwin->GetFbY());
+	*pixels = SDL_calloc((*pitch) * bwin->GetFbHeight() * bpp / 8, sizeof(uint8));
+
+	bwin->UnlockBuffer();
+	return 0;
+}
+
+
+
+int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
+                                      SDL_Rect * rects, int numrects) {
+	SDL_BWin *bwin = _ToBeWin(window);
+	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 = window->surface->format->BitsPerPixel;
+		uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
+		int32 windowSub = bwin->GetFbX() * bpp / 8 +
+						  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) {
+			/* 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 / 8;
+			windowpx = windowBaseAddress + 
+				clips[i].top * windowPitch + clips[i].left * bpp / 8
+				- 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 / 8);
+				bufferpx += bufferPitch;
+				windowpx += windowPitch;
+			}
+		}
+		bwin->UnlockBuffer();
+	}
+	return 0;
+}
+
+void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
+	/* FIXME: FINISH! */
+	printf("ERROR: Attempted to destroy the window frame buffer\n");
+}
+
 #ifdef __cplusplus
 }
 #endif
--- a/src/video/bwindow/SDL_bmodes.h	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/video/bwindow/SDL_bmodes.h	Fri Jul 22 12:39:53 2011 +0000
@@ -36,6 +36,14 @@
 extern int BE_SetDisplayMode(_THIS, SDL_VideoDisplay *display,
 	SDL_DisplayMode *mode);
 
+extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
+                                       Uint32 * format,
+                                       void ** pixels, int *pitch);
+extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
+                                       SDL_Rect * rects, int numrects);
+extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
+
+
 #ifdef __cplusplus
 }
 #endif
--- a/src/video/bwindow/SDL_bwindow.cc	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/video/bwindow/SDL_bwindow.cc	Fri Jul 22 12:39:53 2011 +0000
@@ -180,27 +180,6 @@
 
 
 
-int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
-                                       Uint32 * format,
-                                       void ** pixels, int *pitch) {
-	/* pitch = width of screen, in bytes */
-	BScreen bscreen;
-	*pitch = (bscreen->Frame().right - bscreen->Frame().left + 1) *	/*screen w*/
-			 SDL_BYTESPERPIXEL(*format);
-
-	/* FIXME: FINISH! */
-	return -1;
-}
-
-int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
-                                       SDL_Rect * rects, int numrects) {
-	
-	return -1;
-}
-
-void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
-	/* FIXME: FINISH! */
-}
 
  
 #ifdef __cplusplus
--- a/src/video/bwindow/SDL_bwindow.h	Wed Jul 20 19:25:38 2011 +0000
+++ b/src/video/bwindow/SDL_bwindow.h	Fri Jul 22 12:39:53 2011 +0000
@@ -45,12 +45,7 @@
 extern SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window,
                                     struct SDL_SysWMinfo *info);
 
-extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
-                                       Uint32 * format,
-                                       void ** pixels, int *pitch);
-extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
-                                       SDL_Rect * rects, int numrects);
-extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
+
 
 #endif