Atlas - SDL_bframebuffer.cc

Home / ext / SDL2 / src / video / haiku Lines: 1 | Size: 6712 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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 35extern "C" { 36#endif 37 38#ifndef DRAWTHREAD 39static int32 HAIKU_UpdateOnce(SDL_Window *window); 40#endif 41 42static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { 43 return ((SDL_BWin*)(window->driverdata)); 44} 45 46static SDL_INLINE SDL_BApp *_GetBeApp() { 47 return ((SDL_BApp*)be_app); 48} 49 50int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window, 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); 68 *format = HAIKU_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 102int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window, 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 121int32 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); 174escape: 175 bwin->UnlockBuffer(); 176 } else { 177 snooze(16000); 178 } 179 } 180 181 return B_OK; 182} 183 184void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { 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 205static 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: */ 260
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.