SDL  2.0
SDL_bframebuffer.cc
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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 HAIKU_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 = HAIKU_ColorSpaceToBitsPerPixel(bmode.space);
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  HAIKU_UpdateOnce(window);
116 #endif
117 
118  return 0;
119 }
120 
121 int32 HAIKU_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 HAIKU_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: */
SDL_bframebuffer.h
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
SDL_BWin::BufferExists
bool BufferExists()
Definition: SDL_BWin.h:446
SDL_BWin::GetBitmap
BBitmap * GetBitmap()
Definition: SDL_BWin.h:448
NULL
#define NULL
Definition: begin_code.h:167
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
SDL_BWin
Definition: SDL_BWin.h:65
SDL_BWin::CanTrashWindowBuffer
bool CanTrashWindowBuffer()
Definition: SDL_BWin.h:445
SDL_bmodes.h
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_BWin::BufferIsDirty
bool BufferIsDirty()
Definition: SDL_BWin.h:447
SDL_BWin::GetFbX
int32 GetFbX()
Definition: SDL_BWin.h:437
memcpy
#define memcpy
Definition: SDL_malloc.c:630
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:75
SDL_BWin::GetNumClips
int32 GetNumClips()
Definition: SDL_BWin.h:442
SDL_BWin::UnlockBuffer
void UnlockBuffer()
Definition: SDL_BWin.h:458
SDL_BWin::GetRowBytes
uint32 GetRowBytes()
Definition: SDL_BWin.h:436
SDL_BWin::ConnectionEnabled
bool ConnectionEnabled()
Definition: SDL_BWin.h:439
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_BWin::SetBitmap
void SetBitmap(BBitmap *bitmap)
Definition: SDL_BWin.h:461
SDL_INLINE
#define SDL_INLINE
Definition: begin_code.h:134
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
SDL_BWin::LockBuffer
void LockBuffer()
Definition: SDL_BWin.h:457
HAIKU_CreateWindowFramebuffer
int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
HAIKU_UpdateWindowFramebuffer
int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
HAIKU_DrawThread
int32 HAIKU_DrawThread(void *data)
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
SDL_BWin::SetBufferExists
void SetBufferExists(bool bufferExists)
Definition: SDL_BWin.h:456
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
bpp
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp
Definition: pixman-arm-neon-asm.h:146
bitmap
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
Definition: SDL_opengl_glext.h:4537
SDL_BWin::Connected
bool Connected()
Definition: SDL_BWin.h:440
HAIKU_ColorSpaceToBitsPerPixel
int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace)
SDL_BWin.h
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_Rect
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
SDL_BWin::SetBufferDirty
void SetBufferDirty(bool bufferDirty)
Definition: SDL_BWin.h:459
BPP
#define BPP
Definition: testgesture.c:31
SDL_BWin::GetFbY
int32 GetFbY()
Definition: SDL_BWin.h:438
HAIKU_BPPToSDLPxFormat
int32 HAIKU_BPPToSDLPxFormat(int32 bpp)
SDL_BApp
Definition: SDL_BApp.h:81
SDL_BWin::GetBytesPerPx
int32 GetBytesPerPx()
Definition: SDL_BWin.h:444
rects
EGLSurface EGLint * rects
Definition: eglext.h:282
SDL_BWin::SetTrashBuffer
void SetTrashBuffer(bool trash)
Definition: SDL_BWin.h:460
SDL_BWin::GetClips
clipping_rect * GetClips()
Definition: SDL_BWin.h:441
HAIKU_DestroyWindowFramebuffer
void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
i
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
SDL_BWin::GetBufferPx
uint8 * GetBufferPx()
Definition: SDL_BWin.h:443