comparison src/video/SDL_video.c @ 5175:51b4cfdf7ebb

Don't free the surface since the application might be still using it. Also experimented with texture rectangle updates, but I think at this point the full rect update gives the most consistent results.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 04 Feb 2011 12:24:28 -0800
parents ededa1ccf91c
children 82a48f4d65f6
comparison
equal deleted inserted replaced
5174:34e2d5115786 5175:51b4cfdf7ebb
102 typedef struct { 102 typedef struct {
103 SDL_Renderer *renderer; 103 SDL_Renderer *renderer;
104 SDL_Texture *texture; 104 SDL_Texture *texture;
105 void *pixels; 105 void *pixels;
106 int pitch; 106 int pitch;
107 int bytes_per_pixel;
107 } SDL_WindowTextureData; 108 } SDL_WindowTextureData;
108 109
109 static int 110 static int
110 SDL_CreateWindowTexture(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) 111 SDL_CreateWindowTexture(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
111 { 112 {
174 if (!data->texture) { 175 if (!data->texture) {
175 return -1; 176 return -1;
176 } 177 }
177 178
178 /* Create framebuffer data */ 179 /* Create framebuffer data */
179 data->pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); 180 data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format);
181 data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
180 data->pixels = SDL_malloc(window->h * data->pitch); 182 data->pixels = SDL_malloc(window->h * data->pitch);
181 if (!data->pixels) { 183 if (!data->pixels) {
182 SDL_OutOfMemory(); 184 SDL_OutOfMemory();
183 return -1; 185 return -1;
184 } 186 }
190 192
191 static int 193 static int
192 SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects) 194 SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
193 { 195 {
194 SDL_WindowTextureData *data; 196 SDL_WindowTextureData *data;
197 #ifdef UPDATE_TEXTURE_SUBRECTS
198 void *src, *dst;
199 int src_pitch;
200 int dst_pitch;
201 int i, row, length;
202 #endif
195 203
196 data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); 204 data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
197 if (!data || !data->texture) { 205 if (!data || !data->texture) {
198 SDL_SetError("No window texture data"); 206 SDL_SetError("No window texture data");
199 return -1; 207 return -1;
200 } 208 }
201 209
210 #ifdef UPDATE_TEXTURE_SUBRECTS
211 src_pitch = data->pitch;
212 for (i = 0; i < numrects; ++i) {
213 src = (void *)((Uint8 *)data->pixels +
214 rects[i].y * src_pitch +
215 rects[i].x * data->bytes_per_pixel);
216 if (SDL_LockTexture(data->texture, &rects[i], &dst, &dst_pitch) < 0) {
217 return -1;
218 }
219 length = rects[i].w * data->bytes_per_pixel;
220 for (row = rects[i].h; row--; ) {
221 SDL_memcpy(dst, src, length);
222 src = (Uint8*)src + src_pitch;
223 dst = (Uint8*)dst + dst_pitch;
224 }
225 SDL_UnlockTexture(data->texture);
226 }
227 #else
202 if (SDL_UpdateTexture(data->texture, NULL, data->pixels, data->pitch) < 0) { 228 if (SDL_UpdateTexture(data->texture, NULL, data->pixels, data->pitch) < 0) {
203 return -1; 229 return -1;
204 } 230 }
231 #endif
232
205 if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) { 233 if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
206 return -1; 234 return -1;
207 } 235 }
236
208 SDL_RenderPresent(data->renderer); 237 SDL_RenderPresent(data->renderer);
209 return 0; 238 return 0;
210 } 239 }
211 240
212 static void 241 static void
1387 SDL_Surface * 1416 SDL_Surface *
1388 SDL_GetWindowSurface(SDL_Window * window) 1417 SDL_GetWindowSurface(SDL_Window * window)
1389 { 1418 {
1390 CHECK_WINDOW_MAGIC(window, NULL); 1419 CHECK_WINDOW_MAGIC(window, NULL);
1391 1420
1392 if (!window->surface) { 1421 if (!window->surface_valid) {
1422 if (window->surface) {
1423 window->surface->refcount = 0;
1424 SDL_FreeSurface(window->surface);
1425 }
1393 window->surface = SDL_CreateWindowFramebuffer(window); 1426 window->surface = SDL_CreateWindowFramebuffer(window);
1394 if (window->surface) { 1427 if (window->surface) {
1428 window->surface_valid = SDL_TRUE;
1395 window->surface->refcount = 0x7FFFFFF; 1429 window->surface->refcount = 0x7FFFFFF;
1396 } 1430 }
1397 } 1431 }
1398 return window->surface; 1432 return window->surface;
1399 } 1433 }
1416 SDL_UpdateWindowSurfaceRects(SDL_Window * window, 1450 SDL_UpdateWindowSurfaceRects(SDL_Window * window,
1417 int numrects, SDL_Rect * rects) 1451 int numrects, SDL_Rect * rects)
1418 { 1452 {
1419 CHECK_WINDOW_MAGIC(window, -1); 1453 CHECK_WINDOW_MAGIC(window, -1);
1420 1454
1421 if (!window->surface) { 1455 if (!window->surface_valid) {
1422 SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface"); 1456 SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface");
1423 return -1; 1457 return -1;
1424 } 1458 }
1425 1459
1426 return _this->UpdateWindowFramebuffer(_this, window, numrects, rects); 1460 return _this->UpdateWindowFramebuffer(_this, window, numrects, rects);
1472 } 1506 }
1473 1507
1474 void 1508 void
1475 SDL_OnWindowResized(SDL_Window * window) 1509 SDL_OnWindowResized(SDL_Window * window)
1476 { 1510 {
1477 if (window->surface) { 1511 window->surface_valid = SDL_FALSE;
1478 window->surface->refcount = 0;
1479 SDL_FreeSurface(window->surface);
1480 window->surface = NULL;
1481 }
1482 } 1512 }
1483 1513
1484 void 1514 void
1485 SDL_OnWindowMinimized(SDL_Window * window) 1515 SDL_OnWindowMinimized(SDL_Window * window)
1486 { 1516 {