SDL  2.0
SDL_bframebuffer.cc
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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 #ifndef DRAWTHREAD
39 static int32 BE_UpdateOnce(SDL_Window *window);
40 #endif
41 
42 static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
43  return ((SDL_BWin*)(window->driverdata));
44 }
45 
46 static SDL_INLINE SDL_BApp *_GetBeApp() {
47  return ((SDL_BApp*)be_app);
48 }
49 
51  Uint32 * format,
52  void ** pixels, int *pitch) {
53  SDL_BWin *bwin = _ToBeWin(window);
54  BScreen bscreen;
55  if(!bscreen.IsValid()) {
56  return -1;
57  }
58 
59  while(!bwin->Connected()) { snooze(100); }
60 
61  /* Make sure we have exclusive access to frame buffer data */
62  bwin->LockBuffer();
63 
64  /* format */
65  display_mode bmode;
66  bscreen.GetMode(&bmode);
67  int32 bpp = BE_ColorSpaceToBitsPerPixel(bmode.space);
68  *format = BE_BPPToSDLPxFormat(bpp);
69 
70  /* Create the new bitmap object */
71  BBitmap *bitmap = bwin->GetBitmap();
72 
73  if(bitmap) {
74  delete bitmap;
75  }
76  bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
77  false, /* Views not accepted */
78  true); /* Contiguous memory required */
79 
80  if(bitmap->InitCheck() != B_OK) {
81  delete bitmap;
82  return SDL_SetError("Could not initialize back buffer!");
83  }
84 
85 
86  bwin->SetBitmap(bitmap);
87 
88  /* Set the pixel pointer */
89  *pixels = bitmap->Bits();
90 
91  /* pitch = width of window, in bytes */
92  *pitch = bitmap->BytesPerRow();
93 
94  bwin->SetBufferExists(true);
95  bwin->SetTrashBuffer(false);
96  bwin->UnlockBuffer();
97  return 0;
98 }
99 
100 
101 
103  const SDL_Rect * rects, int numrects) {
104  if(!window)
105  return 0;
106 
107  SDL_BWin *bwin = _ToBeWin(window);
108 
109 #ifdef DRAWTHREAD
110  bwin->LockBuffer();
111  bwin->SetBufferDirty(true);
112  bwin->UnlockBuffer();
113 #else
114  bwin->SetBufferDirty(true);
115  BE_UpdateOnce(window);
116 #endif
117 
118  return 0;
119 }
120 
121 int32 BE_DrawThread(void *data) {
122  SDL_BWin *bwin = (SDL_BWin*)data;
123 
124  BScreen bscreen;
125  if(!bscreen.IsValid()) {
126  return -1;
127  }
128 
129  while(bwin->ConnectionEnabled()) {
130  if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
131  bwin->LockBuffer();
132  BBitmap *bitmap = NULL;
133  bitmap = bwin->GetBitmap();
134  int32 windowPitch = bitmap->BytesPerRow();
135  int32 bufferPitch = bwin->GetRowBytes();
136  uint8 *windowpx;
137  uint8 *bufferpx;
138 
139  int32 BPP = bwin->GetBytesPerPx();
140  int32 windowSub = bwin->GetFbX() * BPP +
141  bwin->GetFbY() * windowPitch;
142  clipping_rect *clips = bwin->GetClips();
143  int32 numClips = bwin->GetNumClips();
144  int i, y;
145 
146  /* Blit each clipping rectangle */
147  bscreen.WaitForRetrace();
148  for(i = 0; i < numClips; ++i) {
149  /* Get addresses of the start of each clipping rectangle */
150  int32 width = clips[i].right - clips[i].left + 1;
151  int32 height = clips[i].bottom - clips[i].top + 1;
152  bufferpx = bwin->GetBufferPx() +
153  clips[i].top * bufferPitch + clips[i].left * BPP;
154  windowpx = (uint8*)bitmap->Bits() +
155  clips[i].top * windowPitch + clips[i].left * BPP -
156  windowSub;
157 
158  /* Copy each row of pixels from the window buffer into the frame
159  buffer */
160  for(y = 0; y < height; ++y)
161  {
162 
163  if(bwin->CanTrashWindowBuffer()) {
164  goto escape; /* Break out before the buffer is killed */
165  }
166 
167  memcpy(bufferpx, windowpx, width * BPP);
168  bufferpx += bufferPitch;
169  windowpx += windowPitch;
170  }
171  }
172 
173  bwin->SetBufferDirty(false);
174 escape:
175  bwin->UnlockBuffer();
176  } else {
177  snooze(16000);
178  }
179  }
180 
181  return B_OK;
182 }
183 
185  SDL_BWin *bwin = _ToBeWin(window);
186 
187  bwin->LockBuffer();
188 
189  /* Free and clear the window buffer */
190  BBitmap *bitmap = bwin->GetBitmap();
191  delete bitmap;
192  bwin->SetBitmap(NULL);
193  bwin->SetBufferExists(false);
194  bwin->UnlockBuffer();
195 }
196 
197 
198 /*
199  * TODO:
200  * This was written to test if certain errors were caused by threading issues.
201  * The specific issues have since become rare enough that they may have been
202  * solved, but I doubt it- they were pretty sporadic before now.
203  */
204 #ifndef DRAWTHREAD
205 static int32 BE_UpdateOnce(SDL_Window *window) {
206  SDL_BWin *bwin = _ToBeWin(window);
207  BScreen bscreen;
208  if(!bscreen.IsValid()) {
209  return -1;
210  }
211 
212  if(bwin->ConnectionEnabled() && bwin->Connected()) {
213  bwin->LockBuffer();
214  int32 windowPitch = window->surface->pitch;
215  int32 bufferPitch = bwin->GetRowBytes();
216  uint8 *windowpx;
217  uint8 *bufferpx;
218 
219  int32 BPP = bwin->GetBytesPerPx();
220  uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
221  int32 windowSub = bwin->GetFbX() * BPP +
222  bwin->GetFbY() * windowPitch;
223  clipping_rect *clips = bwin->GetClips();
224  int32 numClips = bwin->GetNumClips();
225  int i, y;
226 
227  /* Blit each clipping rectangle */
228  bscreen.WaitForRetrace();
229  for(i = 0; i < numClips; ++i) {
230  /* Get addresses of the start of each clipping rectangle */
231  int32 width = clips[i].right - clips[i].left + 1;
232  int32 height = clips[i].bottom - clips[i].top + 1;
233  bufferpx = bwin->GetBufferPx() +
234  clips[i].top * bufferPitch + clips[i].left * BPP;
235  windowpx = windowBaseAddress +
236  clips[i].top * windowPitch + clips[i].left * BPP - windowSub;
237 
238  /* Copy each row of pixels from the window buffer into the frame
239  buffer */
240  for(y = 0; y < height; ++y)
241  {
242  memcpy(bufferpx, windowpx, width * BPP);
243  bufferpx += bufferPitch;
244  windowpx += windowPitch;
245  }
246  }
247  bwin->UnlockBuffer();
248  }
249  return 0;
250 }
251 #endif
252 
253 #ifdef __cplusplus
254 }
255 #endif
256 
257 #endif /* SDL_VIDEO_DRIVER_HAIKU */
258 
259 /* vi: set ts=4 sw=4 expandtab: */
int32 GetFbY()
Definition: SDL_BWin.h:437
bool BufferExists()
Definition: SDL_BWin.h:445
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
void UnlockBuffer()
Definition: SDL_BWin.h:457
uint32 GetRowBytes()
Definition: SDL_BWin.h:435
int32 BE_ColorSpaceToBitsPerPixel(uint32 colorspace)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
bool BufferIsDirty()
Definition: SDL_BWin.h:446
clipping_rect * GetClips()
Definition: SDL_BWin.h:440
uint32_t Uint32
Definition: SDL_stdinc.h:181
void SetBitmap(BBitmap *bitmap)
Definition: SDL_BWin.h:460
void SetBufferExists(bool bufferExists)
Definition: SDL_BWin.h:455
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
#define BPP
Definition: testgesture.c:27
int32 GetNumClips()
Definition: SDL_BWin.h:441
void * pixels
Definition: SDL_surface.h:75
#define _THIS
void LockBuffer()
Definition: SDL_BWin.h:456
int32 BE_BPPToSDLPxFormat(int32 bpp)
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
BBitmap * GetBitmap()
Definition: SDL_BWin.h:447
void SetBufferDirty(bool bufferDirty)
Definition: SDL_BWin.h:458
bool Connected()
Definition: SDL_BWin.h:439
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:50
#define NULL
Definition: begin_code.h:164
int32 GetFbX()
Definition: SDL_BWin.h:436
int BE_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
#define SDL_SetError
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
void BE_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
#define memcpy
Definition: SDL_malloc.c:622
The type used to identify a window.
Definition: SDL_sysvideo.h:73
bool CanTrashWindowBuffer()
Definition: SDL_BWin.h:444
#define SDL_INLINE
Definition: begin_code.h:131
uint8 * GetBufferPx()
Definition: SDL_BWin.h:442
void SetTrashBuffer(bool trash)
Definition: SDL_BWin.h:459
void * driverdata
Definition: SDL_sysvideo.h:111
EGLSurface EGLint * rects
Definition: eglext.h:282
bool ConnectionEnabled()
Definition: SDL_BWin.h:438
SDL_Surface * surface
Definition: SDL_sysvideo.h:97
int32 BE_DrawThread(void *data)
int32 GetBytesPerPx()
Definition: SDL_BWin.h:443
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64