src/video/haiku/SDL_bframebuffer.cc
changeset 12201 8bdc4d340419
parent 12082 09999a0e8f9a
child 12503 806492103856
equal deleted inserted replaced
12200:c0b17b32b95e 12201:8bdc4d340419
    38 #ifndef DRAWTHREAD
    38 #ifndef DRAWTHREAD
    39 static int32 HAIKU_UpdateOnce(SDL_Window *window);
    39 static int32 HAIKU_UpdateOnce(SDL_Window *window);
    40 #endif
    40 #endif
    41 
    41 
    42 static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
    42 static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
    43 	return ((SDL_BWin*)(window->driverdata));
    43     return ((SDL_BWin*)(window->driverdata));
    44 }
    44 }
    45 
    45 
    46 static SDL_INLINE SDL_BApp *_GetBeApp() {
    46 static SDL_INLINE SDL_BApp *_GetBeApp() {
    47 	return ((SDL_BApp*)be_app);
    47     return ((SDL_BApp*)be_app);
    48 }
    48 }
    49 
    49 
    50 int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window,
    50 int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window,
    51                                        Uint32 * format,
    51                                        Uint32 * format,
    52                                        void ** pixels, int *pitch) {
    52                                        void ** pixels, int *pitch) {
    53 	SDL_BWin *bwin = _ToBeWin(window);
    53     SDL_BWin *bwin = _ToBeWin(window);
    54 	BScreen bscreen;
    54     BScreen bscreen;
    55 	if(!bscreen.IsValid()) {
    55     if(!bscreen.IsValid()) {
    56 		return -1;
    56         return -1;
    57 	}
    57     }
    58 
    58 
    59 	while(!bwin->Connected()) { snooze(100); }
    59     while(!bwin->Connected()) { snooze(100); }
    60 	
    60     
    61 	/* Make sure we have exclusive access to frame buffer data */
    61     /* Make sure we have exclusive access to frame buffer data */
    62 	bwin->LockBuffer();
    62     bwin->LockBuffer();
    63 
    63 
    64 	/* format */
    64     /* format */
    65 	display_mode bmode;
    65     display_mode bmode;
    66 	bscreen.GetMode(&bmode);
    66     bscreen.GetMode(&bmode);
    67 	int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode.space);
    67     int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode.space);
    68 	*format = HAIKU_BPPToSDLPxFormat(bpp);
    68     *format = HAIKU_BPPToSDLPxFormat(bpp);
    69 
    69 
    70 	/* Create the new bitmap object */
    70     /* Create the new bitmap object */
    71 	BBitmap *bitmap = bwin->GetBitmap();
    71     BBitmap *bitmap = bwin->GetBitmap();
    72 
    72 
    73 	if(bitmap) {
    73     if(bitmap) {
    74 		delete bitmap;
    74         delete bitmap;
    75 	}
    75     }
    76 	bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
    76     bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space,
    77 			false,	/* Views not accepted */
    77             false,    /* Views not accepted */
    78 			true);	/* Contiguous memory required */
    78             true);    /* Contiguous memory required */
    79 			
    79             
    80 	if(bitmap->InitCheck() != B_OK) {
    80     if(bitmap->InitCheck() != B_OK) {
    81 		delete bitmap;
    81         delete bitmap;
    82 		return SDL_SetError("Could not initialize back buffer!");
    82         return SDL_SetError("Could not initialize back buffer!");
    83 	}
    83     }
    84 
    84 
    85 
    85 
    86 	bwin->SetBitmap(bitmap);
    86     bwin->SetBitmap(bitmap);
    87 	
    87     
    88 	/* Set the pixel pointer */
    88     /* Set the pixel pointer */
    89 	*pixels = bitmap->Bits();
    89     *pixels = bitmap->Bits();
    90 
    90 
    91 	/* pitch = width of window, in bytes */
    91     /* pitch = width of window, in bytes */
    92 	*pitch = bitmap->BytesPerRow();
    92     *pitch = bitmap->BytesPerRow();
    93 
    93 
    94 	bwin->SetBufferExists(true);
    94     bwin->SetBufferExists(true);
    95 	bwin->SetTrashBuffer(false);
    95     bwin->SetTrashBuffer(false);
    96 	bwin->UnlockBuffer();
    96     bwin->UnlockBuffer();
    97 	return 0;
    97     return 0;
    98 }
    98 }
    99 
    99 
   100 
   100 
   101 
   101 
   102 int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
   102 int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window,
   103                                       const SDL_Rect * rects, int numrects) {
   103                                       const SDL_Rect * rects, int numrects) {
   104 	if(!window)
   104     if(!window)
   105 		return 0;
   105         return 0;
   106 
   106 
   107 	SDL_BWin *bwin = _ToBeWin(window);
   107     SDL_BWin *bwin = _ToBeWin(window);
   108 
   108 
   109 #ifdef DRAWTHREAD	
   109 #ifdef DRAWTHREAD    
   110 	bwin->LockBuffer();
   110     bwin->LockBuffer();
   111 	bwin->SetBufferDirty(true);
   111     bwin->SetBufferDirty(true);
   112 	bwin->UnlockBuffer();
   112     bwin->UnlockBuffer();
   113 #else
   113 #else
   114 	bwin->SetBufferDirty(true);
   114     bwin->SetBufferDirty(true);
   115 	HAIKU_UpdateOnce(window);
   115     HAIKU_UpdateOnce(window);
   116 #endif
   116 #endif
   117 
   117 
   118 	return 0;
   118     return 0;
   119 }
   119 }
   120 
   120 
   121 int32 HAIKU_DrawThread(void *data) {
   121 int32 HAIKU_DrawThread(void *data) {
   122 	SDL_BWin *bwin = (SDL_BWin*)data;
   122     SDL_BWin *bwin = (SDL_BWin*)data;
   123 	
   123     
   124 	BScreen bscreen;
   124     BScreen bscreen;
   125 	if(!bscreen.IsValid()) {
   125     if(!bscreen.IsValid()) {
   126 		return -1;
   126         return -1;
   127 	}
   127     }
   128 
   128 
   129 	while(bwin->ConnectionEnabled()) {
   129     while(bwin->ConnectionEnabled()) {
   130 		if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
   130         if( bwin->Connected() && bwin->BufferExists() && bwin->BufferIsDirty() ) {
   131 			bwin->LockBuffer();
   131             bwin->LockBuffer();
   132 			BBitmap *bitmap = NULL;
   132             BBitmap *bitmap = NULL;
   133 			bitmap = bwin->GetBitmap();
   133             bitmap = bwin->GetBitmap();
   134 			int32 windowPitch = bitmap->BytesPerRow();
   134             int32 windowPitch = bitmap->BytesPerRow();
   135 			int32 bufferPitch = bwin->GetRowBytes();
   135             int32 bufferPitch = bwin->GetRowBytes();
   136 			uint8 *windowpx;
   136             uint8 *windowpx;
   137 			uint8 *bufferpx;
   137             uint8 *bufferpx;
   138 
   138 
   139 			int32 BPP = bwin->GetBytesPerPx();
   139             int32 BPP = bwin->GetBytesPerPx();
   140 			int32 windowSub = bwin->GetFbX() * BPP +
   140             int32 windowSub = bwin->GetFbX() * BPP +
   141 						  bwin->GetFbY() * windowPitch;
   141                           bwin->GetFbY() * windowPitch;
   142 			clipping_rect *clips = bwin->GetClips();
   142             clipping_rect *clips = bwin->GetClips();
   143 			int32 numClips = bwin->GetNumClips();
   143             int32 numClips = bwin->GetNumClips();
   144 			int i, y;
   144             int i, y;
   145 
   145 
   146 			/* Blit each clipping rectangle */
   146             /* Blit each clipping rectangle */
   147 			bscreen.WaitForRetrace();
   147             bscreen.WaitForRetrace();
   148 			for(i = 0; i < numClips; ++i) {
   148             for(i = 0; i < numClips; ++i) {
   149 				/* Get addresses of the start of each clipping rectangle */
   149                 /* Get addresses of the start of each clipping rectangle */
   150 				int32 width = clips[i].right - clips[i].left + 1;
   150                 int32 width = clips[i].right - clips[i].left + 1;
   151 				int32 height = clips[i].bottom - clips[i].top + 1;
   151                 int32 height = clips[i].bottom - clips[i].top + 1;
   152 				bufferpx = bwin->GetBufferPx() + 
   152                 bufferpx = bwin->GetBufferPx() + 
   153 					clips[i].top * bufferPitch + clips[i].left * BPP;
   153                     clips[i].top * bufferPitch + clips[i].left * BPP;
   154 				windowpx = (uint8*)bitmap->Bits() + 
   154                 windowpx = (uint8*)bitmap->Bits() + 
   155 					clips[i].top * windowPitch + clips[i].left * BPP -
   155                     clips[i].top * windowPitch + clips[i].left * BPP -
   156 					windowSub;
   156                     windowSub;
   157 
   157 
   158 				/* Copy each row of pixels from the window buffer into the frame
   158                 /* Copy each row of pixels from the window buffer into the frame
   159 				   buffer */
   159                    buffer */
   160 				for(y = 0; y < height; ++y)
   160                 for(y = 0; y < height; ++y)
   161 				{
   161                 {
   162 
   162 
   163 					if(bwin->CanTrashWindowBuffer()) {
   163                     if(bwin->CanTrashWindowBuffer()) {
   164 						goto escape;	/* Break out before the buffer is killed */
   164                         goto escape;    /* Break out before the buffer is killed */
   165 					}
   165                     }
   166 
   166 
   167 					memcpy(bufferpx, windowpx, width * BPP);
   167                     memcpy(bufferpx, windowpx, width * BPP);
   168 					bufferpx += bufferPitch;
   168                     bufferpx += bufferPitch;
   169 					windowpx += windowPitch;
   169                     windowpx += windowPitch;
   170 				}
   170                 }
   171 			}
   171             }
   172 
   172 
   173 			bwin->SetBufferDirty(false);
   173             bwin->SetBufferDirty(false);
   174 escape:
   174 escape:
   175 			bwin->UnlockBuffer();
   175             bwin->UnlockBuffer();
   176 		} else {
   176         } else {
   177 			snooze(16000);
   177             snooze(16000);
   178 		}
   178         }
   179 	}
   179     }
   180 	
   180     
   181 	return B_OK;
   181     return B_OK;
   182 }
   182 }
   183 
   183 
   184 void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
   184 void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window) {
   185 	SDL_BWin *bwin = _ToBeWin(window);
   185     SDL_BWin *bwin = _ToBeWin(window);
   186 	
   186     
   187 	bwin->LockBuffer();
   187     bwin->LockBuffer();
   188 	
   188     
   189 	/* Free and clear the window buffer */
   189     /* Free and clear the window buffer */
   190 	BBitmap *bitmap = bwin->GetBitmap();
   190     BBitmap *bitmap = bwin->GetBitmap();
   191 	delete bitmap;
   191     delete bitmap;
   192 	bwin->SetBitmap(NULL);
   192     bwin->SetBitmap(NULL);
   193 	bwin->SetBufferExists(false);
   193     bwin->SetBufferExists(false);
   194 	bwin->UnlockBuffer();
   194     bwin->UnlockBuffer();
   195 }
   195 }
   196 
   196 
   197 
   197 
   198 /*
   198 /*
   199  * TODO:
   199  * TODO:
   201  * The specific issues have since become rare enough that they may have been
   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.
   202  * solved, but I doubt it- they were pretty sporadic before now.
   203  */
   203  */
   204 #ifndef DRAWTHREAD
   204 #ifndef DRAWTHREAD
   205 static int32 HAIKU_UpdateOnce(SDL_Window *window) {
   205 static int32 HAIKU_UpdateOnce(SDL_Window *window) {
   206 	SDL_BWin *bwin = _ToBeWin(window);
   206     SDL_BWin *bwin = _ToBeWin(window);
   207 	BScreen bscreen;
   207     BScreen bscreen;
   208 	if(!bscreen.IsValid()) {
   208     if(!bscreen.IsValid()) {
   209 		return -1;
   209         return -1;
   210 	}
   210     }
   211 
   211 
   212 	if(bwin->ConnectionEnabled() && bwin->Connected()) {
   212     if(bwin->ConnectionEnabled() && bwin->Connected()) {
   213 		bwin->LockBuffer();
   213         bwin->LockBuffer();
   214 		int32 windowPitch = window->surface->pitch;
   214         int32 windowPitch = window->surface->pitch;
   215 		int32 bufferPitch = bwin->GetRowBytes();
   215         int32 bufferPitch = bwin->GetRowBytes();
   216 		uint8 *windowpx;
   216         uint8 *windowpx;
   217 		uint8 *bufferpx;
   217         uint8 *bufferpx;
   218 
   218 
   219 		int32 BPP = bwin->GetBytesPerPx();
   219         int32 BPP = bwin->GetBytesPerPx();
   220 		uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
   220         uint8 *windowBaseAddress = (uint8*)window->surface->pixels;
   221 		int32 windowSub = bwin->GetFbX() * BPP +
   221         int32 windowSub = bwin->GetFbX() * BPP +
   222 						  bwin->GetFbY() * windowPitch;
   222                           bwin->GetFbY() * windowPitch;
   223 		clipping_rect *clips = bwin->GetClips();
   223         clipping_rect *clips = bwin->GetClips();
   224 		int32 numClips = bwin->GetNumClips();
   224         int32 numClips = bwin->GetNumClips();
   225 		int i, y;
   225         int i, y;
   226 
   226 
   227 		/* Blit each clipping rectangle */
   227         /* Blit each clipping rectangle */
   228 		bscreen.WaitForRetrace();
   228         bscreen.WaitForRetrace();
   229 		for(i = 0; i < numClips; ++i) {
   229         for(i = 0; i < numClips; ++i) {
   230 			/* Get addresses of the start of each clipping rectangle */
   230             /* Get addresses of the start of each clipping rectangle */
   231 			int32 width = clips[i].right - clips[i].left + 1;
   231             int32 width = clips[i].right - clips[i].left + 1;
   232 			int32 height = clips[i].bottom - clips[i].top + 1;
   232             int32 height = clips[i].bottom - clips[i].top + 1;
   233 			bufferpx = bwin->GetBufferPx() + 
   233             bufferpx = bwin->GetBufferPx() + 
   234 				clips[i].top * bufferPitch + clips[i].left * BPP;
   234                 clips[i].top * bufferPitch + clips[i].left * BPP;
   235 			windowpx = windowBaseAddress + 
   235             windowpx = windowBaseAddress + 
   236 				clips[i].top * windowPitch + clips[i].left * BPP - windowSub;
   236                 clips[i].top * windowPitch + clips[i].left * BPP - windowSub;
   237 
   237 
   238 			/* Copy each row of pixels from the window buffer into the frame
   238             /* Copy each row of pixels from the window buffer into the frame
   239 			   buffer */
   239                buffer */
   240 			for(y = 0; y < height; ++y)
   240             for(y = 0; y < height; ++y)
   241 			{
   241             {
   242 				memcpy(bufferpx, windowpx, width * BPP);
   242                 memcpy(bufferpx, windowpx, width * BPP);
   243 				bufferpx += bufferPitch;
   243                 bufferpx += bufferPitch;
   244 				windowpx += windowPitch;
   244                 windowpx += windowPitch;
   245 			}
   245             }
   246 		}
   246         }
   247 		bwin->UnlockBuffer();
   247         bwin->UnlockBuffer();
   248 	}
   248     }
   249 	return 0;
   249     return 0;
   250 }
   250 }
   251 #endif
   251 #endif
   252 
   252 
   253 #ifdef __cplusplus
   253 #ifdef __cplusplus
   254 }
   254 }