Corrected memory leak with rendering.
authorNathan Heisey <nathanheisey@gmail.com>
Fri, 22 Jul 2011 16:54:23 +0000
changeset 5923 460ce3fb104c
parent 5922 efd1498efdff
child 5924 5fb68068019d
Corrected memory leak with rendering.
src/video/bwindow/SDL_BView.h
src/video/bwindow/SDL_BWin.h
src/video/bwindow/SDL_bmodes.cc
--- a/src/video/bwindow/SDL_BView.h	Fri Jul 22 12:39:53 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-#include "SDL_config.h"
-
-#ifndef _SDL_BView_h
-#define _SDL_BView_h
-
-/* This is the event handling and graphics update portion of SDL_BWin */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "../../events/SDL_events_c.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-class SDL_BView:public BView
-{
-  public:
-    SDL_BView(BRect frame):BView(frame, "SDL View", B_FOLLOW_ALL_SIDES,
-                                 (B_WILL_DRAW | B_FRAME_EVENTS))
-    {
-        image = NULL;
-        xoff = yoff = 0;
-        SetViewColor(0, 0, 0, 0);
-        SetHighColor(0, 0, 0, 0);
-    }
-    virtual ~ SDL_BView()
-    {
-        SetBitmap(NULL);
-    }
-    /* Set drawing offsets for fullscreen mode */
-    virtual void SetXYOffset(int x, int y)
-    {
-        xoff = x;
-        yoff = y;
-    }
-    virtual void GetXYOffset(int &x, int &y)
-    {
-        x = xoff;
-        y = yoff;
-    }
-    /* The view changed size. If it means we're in fullscreen, we
-     * draw a nice black box in the entire view to get black borders.
-     */
-    virtual void FrameResized(float width, float height)
-    {
-        BRect bounds;
-        bounds.top = bounds.left = 0;
-        bounds.right = width;
-        bounds.bottom = height;
-        /* Fill the entire view with black */
-        FillRect(bounds, B_SOLID_HIGH);
-        /* And if there's an image, redraw it. */
-        if (image) {
-            bounds = image->Bounds();
-            Draw(bounds);
-        }
-    }
-
-    /* Drawing portion of this complete breakfast. :) */
-    virtual void SetBitmap(BBitmap * bitmap)
-    {
-        if (image) {
-            delete image;
-        }
-        image = bitmap;
-    }
-    virtual void Draw(BRect updateRect)
-    {
-        if (image) {
-            if (xoff || yoff) {
-                BRect dest;
-                dest.top = updateRect.top + yoff;
-                dest.left = updateRect.left + xoff;
-                dest.bottom = updateRect.bottom + yoff;
-                dest.right = updateRect.right + xoff;
-                DrawBitmap(image, updateRect, dest);
-            } else {
-                DrawBitmap(image, updateRect, updateRect);
-            }
-        }
-    }
-    virtual void DrawAsync(BRect updateRect)
-    {
-        if (xoff || yoff) {
-            BRect dest;
-            dest.top = updateRect.top + yoff;
-            dest.left = updateRect.left + xoff;
-            dest.bottom = updateRect.bottom + yoff;
-            dest.right = updateRect.right + xoff;;
-            DrawBitmapAsync(image, updateRect, dest);
-        } else {
-            DrawBitmapAsync(image, updateRect, updateRect);
-        }
-    }
-
-  private:
-    BBitmap * image;
-    int xoff, yoff;
-};
-
-#endif /* _SDL_BView_h */
-/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/bwindow/SDL_BWin.h	Fri Jul 22 12:39:53 2011 +0000
+++ b/src/video/bwindow/SDL_BWin.h	Fri Jul 22 16:54:23 2011 +0000
@@ -42,7 +42,6 @@
 #include <be/opengl/GLView.h>
 #endif
 #include "SDL_events.h"
-#include "SDL_BView.h"
 #include "../../main/beos/SDL_BApp.h"
 
 enum WinCommands {
@@ -67,11 +66,10 @@
     {
         last_buttons = 0;
 printf("SDL_BWin.h: 69\n");
-        the_view = NULL;
+
 #if SDL_VIDEO_OPENGL
         SDL_GLView = NULL;
 #endif
-        SDL_View = NULL;
         _shown = false;
         inhibit_resize = false;
         mouse_focused = false;
@@ -79,42 +77,39 @@
         
         /* Handle framebuffer stuff */
         _connected = connection_disabled = false;
+        trash_window_buffer = false;
         buffer_locker = new BLocker();
+        window_buffer = NULL;
 //        LockBuffer();	/* Unlocked by buffer initialization */
     }
 
     virtual ~ SDL_BWin()
     {
         Lock();
-        connection_disabled = false;
+        connection_disabled = true;
         
-        if (the_view) {
 #if SDL_VIDEO_OPENGL
-            if (the_view == SDL_GLView) {
-                SDL_GLView->UnlockGL();
-            }
-#endif
-            RemoveChild(the_view);
-            the_view = NULL;
+        if (SDL_GLView) {
+            SDL_GLView->UnlockGL();
         }
+        RemoveChild(SDL_GLView);
+#endif    
         Unlock();
 #if SDL_VIDEO_OPENGL
         if (SDL_GLView) {
             delete SDL_GLView;
         }
 #endif
-        if (SDL_View) {
-            delete SDL_View;
-        }
         
         /* Clean up framebuffer stuff */
         buffer_locker->Lock();
-        buffer_locker->Unlock();
+        free(_clips);
         delete buffer_locker;
     }
     
-    
+
     /* Other construction */
+#if SDL_VIDEO_OPENGL
     virtual int CreateView(Uint32 flags, Uint32 gl_flags)
     {
         int retval;
@@ -122,7 +117,6 @@
         retval = 0;
         Lock();
         if (flags & SDL_OPENGL/*SDL_INTERNALOPENGL*/) {
-#if SDL_VIDEO_OPENGL
             if (SDL_GLView == NULL) {
                 SDL_GLView = new BGLView(Bounds(), "SDL GLView",
                                          B_FOLLOW_ALL_SIDES,
@@ -137,31 +131,16 @@
                 SDL_GLView->LockGL();
                 the_view = SDL_GLView;
             }
-#else
-            SDL_SetError("OpenGL support not enabled");
-            retval = -1;
-#endif
         } else {
-            if (SDL_View == NULL) {
-                SDL_View = new SDL_BView(Bounds());
-            }
-            if (the_view != SDL_View) {
-                if (the_view) {
-#if SDL_VIDEO_OPENGL
-                    if (the_view == SDL_GLView) {
-                        SDL_GLView->UnlockGL();
-                    }
-#endif
-                    RemoveChild(the_view);
-                }
-                AddChild(SDL_View);
-                the_view = SDL_View;
+            if (the_view) {
+                    SDL_GLView->UnlockGL();
+                RemoveChild(the_view);
             }
         }
         Unlock();
         return (retval);
     }
-    
+#endif
     
     /* * * * * Framebuffering* * * * */
     virtual void DirectConnected(direct_buffer_info *info) {
@@ -172,7 +151,7 @@
     	
     	switch(info->buffer_state & B_DIRECT_MODE_MASK) {
     	case B_DIRECT_START:
-printf("SDL_BWin.h: 175 Direct start.\n");
+printf(__FILE__": %d; Direct start.\n", __LINE__);
     		_connected = true;
 
     	case B_DIRECT_MODIFY:
@@ -182,6 +161,12 @@
     			_clips = NULL;
     		}
     		
+    		/* Can we reuse the window's pixel buffer after this? */
+    		trash_window_buffer = ((info->buffer_state & B_BUFFER_RESIZED)
+    							|| (info->buffer_state & B_BUFFER_RESET)
+    							|| ((info->buffer_state & B_DIRECT_MODE_MASK)
+    								== B_DIRECT_START));
+    		
     		num_clips = info->clip_list_count;
     		_clips = (clipping_rect *)malloc(num_clips*sizeof(clipping_rect));
     		if(_clips) {
@@ -191,6 +176,7 @@
     			_bits = (uint8*) info->bits;
     			row_bytes = info->bytes_per_row;
     			_bounds = info->window_bounds;
+    			bytes_per_px = info->bits_per_pixel / 8;
     		}
     		
     		break;
@@ -203,6 +189,8 @@
     }
     
     
+    
+    
     /* * * * * Event sending * * * * */
     /* Hook functions */
     virtual void FrameMoved(BPoint origin) {
@@ -412,54 +400,16 @@
 	clipping_rect *GetClips() { return _clips; }
 	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; }
 	
 	/* Setter methods */
 	void SetID(int32 id) { _id = id; }
 
 
 
-
-
-
-
-
-
-	/* FIXME: Methods copied directly; do we need them? */
-#if 0	/* Disabled until its purpose is determined */
-    virtual void SetXYOffset(int x, int y)
-    {
-#if SDL_VIDEO_OPENGL
-        if (the_view == SDL_GLView) {
-            return;
-        }
-#endif
-        SDL_View->SetXYOffset(x, y);
-    }
-    virtual void GetXYOffset(int &x, int &y)
-    {
-#if SDL_VIDEO_OPENGL
-        if (the_view == SDL_GLView) {
-            x = 0;
-            y = 0;
-            return;
-        }
-#endif
-        SDL_View->GetXYOffset(x, y);
-    }
-#endif
-    virtual bool BeginDraw(void)
-    {
-        return (Lock());
-    }
-    virtual void DrawAsync(BRect updateRect)
-    {
-        SDL_View->DrawAsync(updateRect);
-    }
-    virtual void EndDraw(void)
-    {
-        SDL_View->Sync();
-        Unlock();
-    }
 #if SDL_VIDEO_OPENGL
     virtual void SwapBuffers(void)
     {
@@ -631,7 +581,6 @@
 #if SDL_VIDEO_OPENGL
     BGLView * SDL_GLView;
 #endif
-    SDL_BView *SDL_View;
     BView *the_view;
     
     int32 last_buttons;
@@ -650,6 +599,9 @@
     BLocker 		*buffer_locker;
     clipping_rect	*_clips;
     int32			num_clips;
+    int32			bytes_per_px;
+    uint8			*window_buffer;	/* A copy of the window buffer */
+    bool			trash_window_buffer;
 };
 
 #endif
--- a/src/video/bwindow/SDL_bmodes.cc	Fri Jul 22 12:39:53 2011 +0000
+++ b/src/video/bwindow/SDL_bmodes.cc	Fri Jul 22 16:54:23 2011 +0000
@@ -43,8 +43,8 @@
 
 /* Copied from haiku/trunk/src/preferences/screen/ScreenMode.cpp */
 static float get_refresh_rate(display_mode &mode) {
-	return rint(10 * float(mode.timing.pixel_clock * 1000)
-		/ float(mode.timing.h_total * mode.timing.v_total)) / 10.0;
+	return float(mode.timing.pixel_clock * 1000)
+		/ float(mode.timing.h_total * mode.timing.v_total);
 }
 
 static inline int ColorSpaceToBitsPerPixel(uint32 colorspace)
@@ -78,7 +78,7 @@
 	return(bitsperpixel);
 }
 
-static inline int32 BppToSDLPxFormat(int32 bpp) {
+static inline int32 BPPToSDLPxFormat(int32 bpp) {
 	/* Translation taken from SDL_windowsmodes.c */
 	switch (bpp) {
 	case 32:
@@ -112,7 +112,7 @@
 
 	/* Set the format */
 	int32 bpp = ColorSpaceToBitsPerPixel(bmode->space);
-	mode->format = BppToSDLPxFormat(bpp);
+	mode->format = BPPToSDLPxFormat(bpp);
 }
 
 /* Later, there may be more than one monitor available */
@@ -145,8 +145,6 @@
 
 int BE_QuitModes(_THIS) {
 	/* Restore the previous video mode */
-	printf("Quit Modes\n");
-	
 	BScreen screen;
 	display_mode *savedMode = _GetBeApp()->GetPrevMode();
 	screen.SetMode(savedMode);
@@ -223,14 +221,21 @@
 	display_mode bmode;
 	bscreen.GetMode(&bmode);
 	int32 bpp = ColorSpaceToBitsPerPixel(bmode.space);
-	*format = BppToSDLPxFormat(bpp);
+	*format = BPPToSDLPxFormat(bpp);
 
 	/* pitch = width of screen, in bytes */
-	*pitch = bpp * bwin->GetFbWidth() / 8;
+	*pitch = bwin->GetFbWidth() * bwin->GetBytesPerPx();
 
-	/* 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));
+	/* Create a copy of the pixel buffer if it doesn't recycle */
+	*pixels = bwin->GetWindowFramebuffer();
+	if( bwin->CanTrashWindowBuffer() ) {
+		if( (*pixels) != NULL ) {
+			SDL_free(*pixels);
+		}
+		*pixels = SDL_calloc((*pitch) * bwin->GetFbHeight() * 
+			bwin->GetBytesPerPx(), sizeof(uint8));
+		bwin->SetWindowFramebuffer((uint8*)(*pixels));
+	}
 
 	bwin->UnlockBuffer();
 	return 0;
@@ -253,9 +258,9 @@
 		uint8 *windowpx;
 		uint8 *bufferpx;
 
-		int32 bpp = window->surface->format->BitsPerPixel;
+		int32 BPP = bwin->GetBytesPerPx();
 		uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
-		int32 windowSub = bwin->GetFbX() * bpp / 8 +
+		int32 windowSub = bwin->GetFbX() * BPP +
 						  bwin->GetFbY() * windowPitch;
 		clipping_rect *clips = bwin->GetClips();
 		int32 numClips = bwin->GetNumClips();
@@ -268,16 +273,15 @@
 			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;
+				clips[i].top * bufferPitch + clips[i].left * BPP;
 			windowpx = windowBaseAddress + 
-				clips[i].top * windowPitch + clips[i].left * bpp / 8
-				- windowSub;
+				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 / 8);
+				memcpy(bufferpx, windowpx, width * BPP);
 				bufferpx += bufferPitch;
 				windowpx += windowPitch;
 			}
@@ -288,8 +292,15 @@
 }
 
 void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
-	/* FIXME: FINISH! */
-	printf("ERROR: Attempted to destroy the window frame buffer\n");
+	SDL_BWin *bwin = _ToBeWin(window);
+	
+	bwin->LockBuffer();
+	
+	/* Free and clear the window buffer */
+	uint8* winBuffer = bwin->GetWindowFramebuffer();
+	SDL_free(winBuffer);
+	bwin->SetWindowFramebuffer(NULL);
+	bwin->UnlockBuffer();
 }
 
 #ifdef __cplusplus