SDL  2.0
SDL_bframebuffer.cc
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_HAIKU
24 
25 #include "SDL_bframebuffer.h"
26 
27 #include <AppKit.h>
28 #include <InterfaceKit.h>
29 #include "SDL_bmodes.h"
30 #include "SDL_BWin.h"
31 
32 #include "../../main/haiku/SDL_BApp.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 int32 BE_UpdateOnce(SDL_Window *window);
39 
40 static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
41  return ((SDL_BWin*)(window->driverdata));
42 }
43 
44 static SDL_INLINE SDL_BApp *_GetBeApp() {
45  return ((SDL_BApp*)be_app);
46 }
47 
49  Uint32 * format,
50  void ** pixels, int *pitch) {
51  SDL_BWin *bwin = _ToBeWin(window);
52  BScreen bscreen;
53  if(!bscreen.IsValid()) {
54  return -1;
55  }
56 
57  while(!bwin->Connected()) { snooze(100); }
58 
59  /* Make sure we have exclusive access to frame buffer data */
60  bwin->LockBuffer();
61 
62  /* format */
63  display_mode bmode;
64  bscreen.GetMode(&bmode);
65  int32 bpp = BE_ColorSpaceToBitsPerPixel(bmode.space);
66  *format = BE_BPPToSDLPxFormat(bpp);
67 
68  /* Create the new bitmap object */
69  BBitmap *bitmap = bwin->GetBitmap();
70 
71  if(bitmap) {
72  delete bitmap;
73  }
74  bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
75  false, /* Views not accepted */
76  true); /* Contiguous memory required */
77 
78  if(bitmap->InitCheck() != B_OK) {
79  return SDL_SetError("Could not initialize back buffer!\n");
80  }
81 
82 
83  bwin->SetBitmap(bitmap);
84 
85  /* Set the pixel pointer */
86  *pixels = bitmap->Bits();
87 
88  /* pitch = width of window, in bytes */
89  *pitch = bitmap->BytesPerRow();
90 
91  bwin->SetBufferExists(true);
92  bwin->SetTrashBuffer(false);
93  bwin->UnlockBuffer();
94  return 0;
95 }
96 
97 
98 
100  const SDL_Rect * rects, int numrects) {
101  if(!window)
102  return 0;
103 
104  SDL_BWin *bwin = _ToBeWin(window);
105 
106 #ifdef DRAWTHREAD
107  bwin->LockBuffer();
108  bwin->SetBufferDirty(true);
109  bwin->UnlockBuffer();
110 #else
111  bwin->SetBufferDirty(true);
112  BE_UpdateOnce(window);
113 #endif
114 
115  return 0;
116 }
117 
118 int32 BE_DrawThread(void *data) {
119  SDL_BWin *bwin = (SDL_BWin*)data;
120 
121  BScreen bscreen;
122  if(!bscreen.IsValid()) {
123  return -1;
124  }
125 
126  while(bwin->ConnectionEnabled()) {
127  if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
128  bwin->LockBuffer();
129  BBitmap *bitmap = NULL;
130  bitmap = bwin->GetBitmap();
131  int32 windowPitch = bitmap->BytesPerRow();
132  int32 bufferPitch = bwin->GetRowBytes();
133  uint8 *windowpx;
134  uint8 *bufferpx;
135 
136  int32 BPP = bwin->GetBytesPerPx();
137  int32 windowSub = bwin->GetFbX() * BPP +
138  bwin->GetFbY() * windowPitch;
139  clipping_rect *clips = bwin->GetClips();
140  int32 numClips = bwin->GetNumClips();
141  int i, y;
142 
143  /* Blit each clipping rectangle */
144  bscreen.WaitForRetrace();
145  for(i = 0; i < numClips; ++i) {
146  clipping_rect rc = clips[i];
147  /* Get addresses of the start of each clipping rectangle */
148  int32 width = clips[i].right - clips[i].left + 1;
149  int32 height = clips[i].bottom - clips[i].top + 1;
150  bufferpx = bwin->GetBufferPx() +
151  clips[i].top * bufferPitch + clips[i].left * BPP;
152  windowpx = (uint8*)bitmap->Bits() +
153  clips[i].top * windowPitch + clips[i].left * BPP -
154  windowSub;
155 
156  /* Copy each row of pixels from the window buffer into the frame
157  buffer */
158  for(y = 0; y < height; ++y)
159  {
160 
161  if(bwin->CanTrashWindowBuffer()) {
162  goto escape; /* Break out before the buffer is killed */
163  }
164 
165  memcpy(bufferpx, windowpx, width * BPP);
166  bufferpx += bufferPitch;
167  windowpx += windowPitch;
168  }
169  }
170 
171  bwin->SetBufferDirty(false);
172 escape:
173  bwin->UnlockBuffer();
174  } else {
175  snooze(16000);
176  }
177  }
178 
179  return B_OK;
180 }
181 
183  SDL_BWin *bwin = _ToBeWin(window);
184 
185  bwin->LockBuffer();
186 
187  /* Free and clear the window buffer */
188  BBitmap *bitmap = bwin->GetBitmap();
189  delete bitmap;
190  bwin->SetBitmap(NULL);
191  bwin->SetBufferExists(false);
192  bwin->UnlockBuffer();
193 }
194 
195 
196 /*
197  * TODO:
198  * This was written to test if certain errors were caused by threading issues.
199  * The specific issues have since become rare enough that they may have been
200  * solved, but I doubt it- they were pretty sporadic before now.
201  */
202 int32 BE_UpdateOnce(SDL_Window *window) {
203  SDL_BWin *bwin = _ToBeWin(window);
204  BScreen bscreen;
205  if(!bscreen.IsValid()) {
206  return -1;
207  }
208 
209  if(bwin->ConnectionEnabled() && bwin->Connected()) {
210  bwin->LockBuffer();
211  int32 windowPitch = window->surface->pitch;
212  int32 bufferPitch = bwin->GetRowBytes();
213  uint8 *windowpx;
214  uint8 *bufferpx;
215 
216  int32 BPP = bwin->GetBytesPerPx();
217  uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
218  int32 windowSub = bwin->GetFbX() * BPP +
219  bwin->GetFbY() * windowPitch;
220  clipping_rect *clips = bwin->GetClips();
221  int32 numClips = bwin->GetNumClips();
222  int i, y;
223 
224  /* Blit each clipping rectangle */
225  bscreen.WaitForRetrace();
226  for(i = 0; i < numClips; ++i) {
227  clipping_rect rc = clips[i];
228  /* Get addresses of the start of each clipping rectangle */
229  int32 width = clips[i].right - clips[i].left + 1;
230  int32 height = clips[i].bottom - clips[i].top + 1;
231  bufferpx = bwin->GetBufferPx() +
232  clips[i].top * bufferPitch + clips[i].left * BPP;
233  windowpx = windowBaseAddress +
234  clips[i].top * windowPitch + clips[i].left * BPP - windowSub;
235 
236  /* Copy each row of pixels from the window buffer into the frame
237  buffer */
238  for(y = 0; y < height; ++y)
239  {
240  memcpy(bufferpx, windowpx, width * BPP);
241  bufferpx += bufferPitch;
242  windowpx += windowPitch;
243  }
244  }
245  bwin->UnlockBuffer();
246  }
247  return 0;
248 }
249 
250 #ifdef __cplusplus
251 }
252 #endif
253 
254 #endif /* SDL_VIDEO_DRIVER_HAIKU */
int32 GetFbY()
Definition: SDL_BWin.h:414
bool BufferExists()
Definition: SDL_BWin.h:422
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
void UnlockBuffer()
Definition: SDL_BWin.h:433
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
uint32 GetRowBytes()
Definition: SDL_BWin.h:412
int32 BE_ColorSpaceToBitsPerPixel(uint32 colorspace)
SDL_Window * window
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1565
bool BufferIsDirty()
Definition: SDL_BWin.h:423
clipping_rect * GetClips()
Definition: SDL_BWin.h:417
void SetBitmap(BBitmap *bitmap)
Definition: SDL_BWin.h:436
void SetBufferExists(bool bufferExists)
Definition: SDL_BWin.h:431
#define BPP
Definition: testgesture.c:27
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
int32 GetNumClips()
Definition: SDL_BWin.h:418
void * pixels
Definition: SDL_surface.h:75
#define _THIS
void LockBuffer()
Definition: SDL_BWin.h:432
int32 BE_BPPToSDLPxFormat(int32 bpp)
BBitmap * GetBitmap()
Definition: SDL_BWin.h:424
void SetBufferDirty(bool bufferDirty)
Definition: SDL_BWin.h:434
bool Connected()
Definition: SDL_BWin.h:416
int BE_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
#define NULL
Definition: begin_code.h:143
int32 GetFbX()
Definition: SDL_BWin.h:413
int BE_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
#define SDL_SetError
void BE_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
#define memcpy
Definition: SDL_malloc.c:640
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_Rect rects[MAX_RECTS]
bool CanTrashWindowBuffer()
Definition: SDL_BWin.h:421
#define SDL_INLINE
Definition: begin_code.h:120
uint8 * GetBufferPx()
Definition: SDL_BWin.h:419
void SetTrashBuffer(bool trash)
Definition: SDL_BWin.h:435
void * driverdata
Definition: SDL_sysvideo.h:106
bool ConnectionEnabled()
Definition: SDL_BWin.h:415
SDL_Surface * surface
Definition: SDL_sysvideo.h:93
int32 BE_DrawThread(void *data)
int32 GetBytesPerPx()
Definition: SDL_BWin.h:420
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64