src/video/bwindow/SDL_bframebuffer.cc
author Nathan Heisey <nathanheisey@gmail.com>
Wed, 03 Aug 2011 06:22:33 +0000
changeset 5933 5f8a7ebc88e5
parent 5932 cd08863bcb49
child 5934 01531d8d1e01
permissions -rw-r--r--
Replaced window backbuffer with BBitmap
nathanheisey@5931
     1
/*
nathanheisey@5931
     2
  Simple DirectMedia Layer
nathanheisey@5931
     3
  Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
nathanheisey@5931
     4
nathanheisey@5931
     5
  This software is provided 'as-is', without any express or implied
nathanheisey@5931
     6
  warranty.  In no event will the authors be held liable for any damages
nathanheisey@5931
     7
  arising from the use of this software.
nathanheisey@5931
     8
nathanheisey@5931
     9
  Permission is granted to anyone to use this software for any purpose,
nathanheisey@5931
    10
  including commercial applications, and to alter it and redistribute it
nathanheisey@5931
    11
  freely, subject to the following restrictions:
nathanheisey@5931
    12
nathanheisey@5931
    13
  1. The origin of this software must not be misrepresented; you must not
nathanheisey@5931
    14
     claim that you wrote the original software. If you use this software
nathanheisey@5931
    15
     in a product, an acknowledgment in the product documentation would be
nathanheisey@5931
    16
     appreciated but is not required.
nathanheisey@5931
    17
  2. Altered source versions must be plainly marked as such, and must not be
nathanheisey@5931
    18
     misrepresented as being the original software.
nathanheisey@5931
    19
  3. This notice may not be removed or altered from any source distribution.
nathanheisey@5931
    20
*/
nathanheisey@5931
    21
nathanheisey@5931
    22
#include "SDL_bframebuffer.h"
nathanheisey@5931
    23
nathanheisey@5931
    24
#include <AppKit.h>
nathanheisey@5931
    25
#include <InterfaceKit.h>
nathanheisey@5931
    26
#include "SDL_bmodes.h"
nathanheisey@5931
    27
#include "SDL_BWin.h"
nathanheisey@5931
    28
nathanheisey@5931
    29
#include "../../main/beos/SDL_BApp.h"
nathanheisey@5931
    30
nathanheisey@5931
    31
#ifdef __cplusplus
nathanheisey@5931
    32
extern "C" {
nathanheisey@5931
    33
#endif
nathanheisey@5931
    34
nathanheisey@5931
    35
static inline SDL_BWin *_ToBeWin(SDL_Window *window) {
nathanheisey@5931
    36
	return ((SDL_BWin*)(window->driverdata));
nathanheisey@5931
    37
}
nathanheisey@5931
    38
nathanheisey@5931
    39
static inline SDL_BApp *_GetBeApp() {
nathanheisey@5931
    40
	return ((SDL_BApp*)be_app);
nathanheisey@5931
    41
}
nathanheisey@5931
    42
nathanheisey@5931
    43
int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window,
nathanheisey@5931
    44
                                       Uint32 * format,
nathanheisey@5931
    45
                                       void ** pixels, int *pitch) {
nathanheisey@5931
    46
	SDL_BWin *bwin = _ToBeWin(window);
nathanheisey@5931
    47
	BScreen bscreen;
nathanheisey@5931
    48
	if(!bscreen.IsValid()) {
nathanheisey@5931
    49
		return -1;
nathanheisey@5931
    50
	}
nathanheisey@5931
    51
nathanheisey@5931
    52
	while(!bwin->Connected()) { snooze(100); }
nathanheisey@5931
    53
	
nathanheisey@5931
    54
	/* Make sure we have exclusive access to frame buffer data */
nathanheisey@5931
    55
	bwin->LockBuffer();
nathanheisey@5932
    56
nathanheisey@5931
    57
	/* format */
nathanheisey@5931
    58
	display_mode bmode;
nathanheisey@5931
    59
	bscreen.GetMode(&bmode);
nathanheisey@5931
    60
	int32 bpp = ColorSpaceToBitsPerPixel(bmode.space);
nathanheisey@5931
    61
	*format = BPPToSDLPxFormat(bpp);
nathanheisey@5931
    62
nathanheisey@5933
    63
	/* Create the new bitmap object */
nathanheisey@5933
    64
	BBitmap *bitmap = bwin->GetBitmap();
nathanheisey@5933
    65
	if(bitmap) {
nathanheisey@5933
    66
		delete bitmap;
nathanheisey@5933
    67
	}
nathanheisey@5933
    68
	bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
nathanheisey@5933
    69
			false,	/* Views not accepted */
nathanheisey@5933
    70
			true);	/* Contiguous memory required */
nathanheisey@5933
    71
	bwin->SetBitmap(bitmap);
nathanheisey@5933
    72
	
nathanheisey@5933
    73
	/* Set the pixel pointer */
nathanheisey@5933
    74
	*pixels = bitmap->Bits();
nathanheisey@5931
    75
nathanheisey@5933
    76
	/* pitch = width of window, in bytes */
nathanheisey@5933
    77
	*pitch = bitmap->BytesPerRow();
nathanheisey@5931
    78
nathanheisey@5931
    79
	bwin->SetBufferExists(true);
nathanheisey@5931
    80
	bwin->SetTrashBuffer(false);
nathanheisey@5931
    81
	bwin->UnlockBuffer();
nathanheisey@5931
    82
	return 0;
nathanheisey@5931
    83
}
nathanheisey@5931
    84
nathanheisey@5931
    85
nathanheisey@5931
    86
nathanheisey@5931
    87
int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
nathanheisey@5931
    88
                                      SDL_Rect * rects, int numrects) {
nathanheisey@5931
    89
	if(!window)
nathanheisey@5931
    90
		return 0;
nathanheisey@5931
    91
nathanheisey@5931
    92
	SDL_BWin *bwin = _ToBeWin(window);
nathanheisey@5931
    93
	
nathanheisey@5931
    94
	bwin->LockBuffer();
nathanheisey@5931
    95
	bwin->SetBufferDirty(true);
nathanheisey@5931
    96
	bwin->UnlockBuffer();
nathanheisey@5931
    97
nathanheisey@5931
    98
	return 0;
nathanheisey@5931
    99
}
nathanheisey@5931
   100
nathanheisey@5931
   101
int32 BE_DrawThread(void *data) {
nathanheisey@5931
   102
	SDL_BWin *bwin = (SDL_BWin*)data;
nathanheisey@5931
   103
	SDL_Window *window = _GetBeApp()->GetSDLWindow(bwin->GetID());
nathanheisey@5931
   104
	
nathanheisey@5931
   105
	BScreen bscreen;
nathanheisey@5931
   106
	if(!bscreen.IsValid()) {
nathanheisey@5931
   107
		return -1;
nathanheisey@5931
   108
	}
nathanheisey@5931
   109
nathanheisey@5931
   110
	while(bwin->ConnectionEnabled()) {
nathanheisey@5931
   111
		if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
nathanheisey@5931
   112
			bwin->LockBuffer();
nathanheisey@5933
   113
			BBitmap *bitmap = bwin->GetBitmap();
nathanheisey@5933
   114
			int32 windowPitch = bitmap->BytesPerRow();
nathanheisey@5931
   115
			int32 bufferPitch = bwin->GetRowBytes();
nathanheisey@5931
   116
			uint8 *windowpx;
nathanheisey@5931
   117
			uint8 *bufferpx;
nathanheisey@5931
   118
nathanheisey@5931
   119
			int32 BPP = bwin->GetBytesPerPx();
nathanheisey@5931
   120
			int32 windowSub = bwin->GetFbX() * BPP +
nathanheisey@5931
   121
						  bwin->GetFbY() * windowPitch;
nathanheisey@5931
   122
			clipping_rect *clips = bwin->GetClips();
nathanheisey@5931
   123
			int32 numClips = bwin->GetNumClips();
nathanheisey@5931
   124
			int i, y;
nathanheisey@5931
   125
nathanheisey@5931
   126
			/* Blit each clipping rectangle */
nathanheisey@5931
   127
			bscreen.WaitForRetrace();
nathanheisey@5931
   128
			for(i = 0; i < numClips; ++i) {
nathanheisey@5931
   129
				clipping_rect rc = clips[i];
nathanheisey@5931
   130
				/* Get addresses of the start of each clipping rectangle */
nathanheisey@5931
   131
				int32 width = clips[i].right - clips[i].left + 1;
nathanheisey@5931
   132
				int32 height = clips[i].bottom - clips[i].top + 1;
nathanheisey@5931
   133
				bufferpx = bwin->GetBufferPx() + 
nathanheisey@5931
   134
					clips[i].top * bufferPitch + clips[i].left * BPP;
nathanheisey@5933
   135
				windowpx = (uint8*)bitmap->Bits(); + 
nathanheisey@5933
   136
					clips[i].top * windowPitch + clips[i].left * BPP -
nathanheisey@5933
   137
					windowSub;
nathanheisey@5931
   138
nathanheisey@5931
   139
				/* Copy each row of pixels from the window buffer into the frame
nathanheisey@5931
   140
				   buffer */
nathanheisey@5931
   141
				for(y = 0; y < height; ++y)
nathanheisey@5931
   142
				{
nathanheisey@5931
   143
					if(bwin->CanTrashWindowBuffer()) {
nathanheisey@5931
   144
						goto escape;	/* Break out before the buffer is killed */
nathanheisey@5931
   145
					}
nathanheisey@5931
   146
					memcpy(bufferpx, windowpx, width * BPP);
nathanheisey@5931
   147
					bufferpx += bufferPitch;
nathanheisey@5931
   148
					windowpx += windowPitch;
nathanheisey@5931
   149
				}
nathanheisey@5931
   150
			}
nathanheisey@5931
   151
			bwin->SetBufferDirty(false);
nathanheisey@5931
   152
escape:
nathanheisey@5931
   153
			bwin->UnlockBuffer();
nathanheisey@5931
   154
		} else {
nathanheisey@5931
   155
			snooze(16000);
nathanheisey@5931
   156
		}
nathanheisey@5931
   157
	}
nathanheisey@5931
   158
	
nathanheisey@5931
   159
	return B_OK;
nathanheisey@5931
   160
}
nathanheisey@5931
   161
nathanheisey@5931
   162
void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
nathanheisey@5931
   163
	SDL_BWin *bwin = _ToBeWin(window);
nathanheisey@5931
   164
	
nathanheisey@5931
   165
	bwin->LockBuffer();
nathanheisey@5931
   166
	
nathanheisey@5931
   167
	/* Free and clear the window buffer */
nathanheisey@5933
   168
	BBitmap *bitmap = bwin->GetBitmap();
nathanheisey@5933
   169
	delete bitmap;
nathanheisey@5933
   170
	bwin->SetBitmap(NULL);
nathanheisey@5931
   171
	bwin->SetBufferExists(false);
nathanheisey@5931
   172
	bwin->UnlockBuffer();
nathanheisey@5931
   173
}
nathanheisey@5931
   174
nathanheisey@5931
   175
#ifdef __cplusplus
nathanheisey@5931
   176
}
nathanheisey@5931
   177
#endif