Corrected memory leak with rendering.
This commit is contained in:
parent
8932a116a0
commit
ee8ee9d166
3 changed files with 62 additions and 223 deletions
|
@ -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: */
|
|
@ -42,7 +42,6 @@ extern "C" {
|
|||
#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 @@ class SDL_BWin:public BDirectWindow
|
|||
{
|
||||
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 @@ printf("SDL_BWin.h: 69\n");
|
|||
|
||||
/* 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 @@ printf("SDL_BWin.h: 69\n");
|
|||
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 @@ printf("SDL_BWin.h: 69\n");
|
|||
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 @@ printf("SDL_BWin.h: 69\n");
|
|||
|
||||
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 @@ printf("SDL_BWin.h: 175 Direct start.\n");
|
|||
_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 @@ printf("SDL_BWin.h: 175 Direct start.\n");
|
|||
_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 @@ printf("SDL_BWin.h: 175 Direct start.\n");
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* * * * * Event sending * * * * */
|
||||
/* Hook functions */
|
||||
virtual void FrameMoved(BPoint origin) {
|
||||
|
@ -412,54 +400,16 @@ printf("SDL_BWin.h: 175 Direct start.\n");
|
|||
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 @@ private:
|
|||
#if SDL_VIDEO_OPENGL
|
||||
BGLView * SDL_GLView;
|
||||
#endif
|
||||
SDL_BView *SDL_View;
|
||||
BView *the_view;
|
||||
|
||||
int32 last_buttons;
|
||||
|
@ -650,6 +599,9 @@ private:
|
|||
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
|
||||
|
|
|
@ -43,8 +43,8 @@ static inline SDL_BApp *_GetBeApp() {
|
|||
|
||||
/* 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 @@ static inline int ColorSpaceToBitsPerPixel(uint32 colorspace)
|
|||
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 @@ static inline void BE_BDisplayModeToSdlDisplayMode(display_mode *bmode,
|
|||
|
||||
/* 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_InitModes(_THIS) {
|
|||
|
||||
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 @@ int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
|
|||
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 @@ int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
|
|||
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 @@ int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
|
|||
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 @@ int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
|
|||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue