Mercurial > sdl-ios-xcode
comparison src/SDL_compat.c @ 1684:c4aa1a2f48f1 SDL-1.3
Software YUV texture support in progress...
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 18 Jun 2006 06:35:41 +0000 |
parents | 396a35389351 |
children | 66267c6a0b12 |
comparison
equal
deleted
inserted
replaced
1683:396a35389351 | 1684:c4aa1a2f48f1 |
---|---|
1174 SDL_cursor->area.x = 0; | 1174 SDL_cursor->area.x = 0; |
1175 SDL_cursor->area.y = 0; | 1175 SDL_cursor->area.y = 0; |
1176 SDL_memset(SDL_cursor->save[0], 0, savelen); | 1176 SDL_memset(SDL_cursor->save[0], 0, savelen); |
1177 } | 1177 } |
1178 } | 1178 } |
1179 #endif | |
1180 | |
1181 struct private_yuvhwdata | |
1182 { | |
1183 Uint16 pitches[3]; | |
1184 Uint8 *planes[3]; | |
1185 | |
1186 SDL_TextureID textureID; | |
1187 }; | |
1179 | 1188 |
1180 SDL_Overlay * | 1189 SDL_Overlay * |
1181 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display) | 1190 SDL_CreateYUVOverlay(int w, int h, Uint32 format, SDL_Surface * display) |
1182 { | 1191 { |
1183 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
1184 SDL_Window *window; | |
1185 const char *yuv_hwaccel; | |
1186 SDL_Overlay *overlay; | 1192 SDL_Overlay *overlay; |
1187 | 1193 Uint32 texture_format; |
1188 window = SDL_GetWindowFromSurface(display); | 1194 |
1189 if (window && (window->flags & SDL_WINDOW_OPENGL)) { | 1195 if ((display->flags & SDL_OPENGL) == SDL_OPENGL) { |
1190 SDL_SetError("YUV overlays are not supported in OpenGL mode"); | 1196 SDL_SetError("YUV overlays are not supported in OpenGL mode"); |
1191 return NULL; | 1197 return NULL; |
1192 } | 1198 } |
1193 | 1199 |
1194 /* Display directly on video surface, if possible */ | 1200 if (display != SDL_PublicSurface) { |
1195 if (SDL_getenv("SDL_VIDEO_YUV_DIRECT")) { | 1201 SDL_SetError("YUV display is only supported on the screen surface"); |
1196 if (window && | 1202 return NULL; |
1197 ((window->surface->format->BytesPerPixel == 2) || | 1203 } |
1198 (window->surface->format->BytesPerPixel == 4))) { | 1204 |
1199 display = window->surface; | 1205 switch (format) { |
1200 } | 1206 case SDL_YV12_OVERLAY: |
1201 } | 1207 texture_format = SDL_PixelFormat_YV12; |
1202 overlay = NULL; | 1208 break; |
1203 yuv_hwaccel = SDL_getenv("SDL_VIDEO_YUV_HWACCEL"); | 1209 case SDL_IYUV_OVERLAY: |
1204 if (((display->flags & SDL_SCREEN_SURFACE) && _this->CreateYUVOverlay) && | 1210 texture_format = SDL_PixelFormat_IYUV; |
1205 (!yuv_hwaccel || (SDL_atoi(yuv_hwaccel) > 0))) { | 1211 break; |
1206 overlay = _this->CreateYUVOverlay(_this, w, h, format, display); | 1212 case SDL_YUY2_OVERLAY: |
1207 } | 1213 texture_format = SDL_PixelFormat_YUY2; |
1208 /* If hardware YUV overlay failed ... */ | 1214 break; |
1209 if (overlay == NULL) { | 1215 case SDL_UYVY_OVERLAY: |
1210 overlay = SDL_CreateYUV_SW(_this, w, h, format, display); | 1216 texture_format = SDL_PixelFormat_UYVY; |
1211 } | 1217 break; |
1218 case SDL_YVYU_OVERLAY: | |
1219 texture_format = SDL_PixelFormat_YVYU; | |
1220 break; | |
1221 default: | |
1222 SDL_SetError("Unknown YUV format"); | |
1223 return NULL; | |
1224 } | |
1225 | |
1226 overlay = (SDL_Overlay *) SDL_malloc(sizeof(*overlay)); | |
1227 if (!overlay) { | |
1228 SDL_OutOfMemory(); | |
1229 return NULL; | |
1230 } | |
1231 SDL_zerop(overlay); | |
1232 | |
1233 overlay->hwdata = | |
1234 (struct private_yuvhwdata *) SDL_malloc(sizeof(*overlay->hwdata)); | |
1235 if (!overlay->hwdata) { | |
1236 SDL_free(overlay); | |
1237 SDL_OutOfMemory(); | |
1238 return NULL; | |
1239 } | |
1240 | |
1241 overlay->format = format; | |
1242 overlay->w = w; | |
1243 overlay->h = h; | |
1244 if (format == SDL_YV12_OVERLAY || format == SDL_IYUV_OVERLAY) { | |
1245 overlay->planes = 3; | |
1246 } else { | |
1247 overlay->planes = 1; | |
1248 } | |
1249 overlay->pitches = overlay->hwdata->pitches; | |
1250 overlay->pixels = overlay->hwdata->planes; | |
1251 | |
1252 switch (format) { | |
1253 case SDL_YV12_OVERLAY: | |
1254 case SDL_IYUV_OVERLAY: | |
1255 overlay->pitches[0] = overlay->w; | |
1256 overlay->pitches[1] = overlay->w / 2; | |
1257 overlay->pitches[2] = overlay->w / 2; | |
1258 break; | |
1259 case SDL_YUY2_OVERLAY: | |
1260 case SDL_UYVY_OVERLAY: | |
1261 case SDL_YVYU_OVERLAY: | |
1262 overlay->pitches[0] = overlay->h * 2; | |
1263 break; | |
1264 } | |
1265 | |
1266 overlay->hwdata->textureID = | |
1267 SDL_CreateTexture(texture_format, SDL_TextureAccess_Local, w, h); | |
1268 if (!overlay->hwdata->textureID) { | |
1269 SDL_FreeYUVOverlay(overlay); | |
1270 return NULL; | |
1271 } | |
1272 | |
1212 return overlay; | 1273 return overlay; |
1213 } | 1274 } |
1214 | 1275 |
1215 int | 1276 int |
1216 SDL_LockYUVOverlay(SDL_Overlay * overlay) | 1277 SDL_LockYUVOverlay(SDL_Overlay * overlay) |
1217 { | 1278 { |
1218 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 1279 void *pixels; |
1219 return overlay->hwfuncs->Lock(_this, overlay); | 1280 int pitch; |
1281 if (SDL_LockTexture(overlay->hwdata->textureID, NULL, 1, &pixels, &pitch) | |
1282 < 0) { | |
1283 return -1; | |
1284 } | |
1285 switch (overlay->format) { | |
1286 case SDL_YV12_OVERLAY: | |
1287 case SDL_IYUV_OVERLAY: | |
1288 overlay->pixels[0] = (Uint8 *) pixels; | |
1289 overlay->pixels[1] = | |
1290 overlay->pixels[0] + overlay->pitches[0] * overlay->h; | |
1291 overlay->pixels[2] = | |
1292 overlay->pixels[1] + overlay->pitches[1] * overlay->h; | |
1293 break; | |
1294 case SDL_YUY2_OVERLAY: | |
1295 case SDL_UYVY_OVERLAY: | |
1296 case SDL_YVYU_OVERLAY: | |
1297 overlay->pixels[0] = (Uint8 *) pixels; | |
1298 break; | |
1299 } | |
1300 return 0; | |
1220 } | 1301 } |
1221 | 1302 |
1222 void | 1303 void |
1223 SDL_UnlockYUVOverlay(SDL_Overlay * overlay) | 1304 SDL_UnlockYUVOverlay(SDL_Overlay * overlay) |
1224 { | 1305 { |
1225 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 1306 SDL_UnlockTexture(overlay->hwdata->textureID); |
1226 overlay->hwfuncs->Unlock(_this, overlay); | |
1227 } | 1307 } |
1228 | 1308 |
1229 int | 1309 int |
1230 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect) | 1310 SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect) |
1231 { | 1311 { |
1232 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | 1312 if (SDL_RenderCopy(overlay->hwdata->textureID, NULL, dstrect, |
1233 SDL_Rect src, dst; | 1313 SDL_TextureBlendMode_None, |
1234 int srcx, srcy, srcw, srch; | 1314 SDL_TextureScaleMode_Fast) < 0) { |
1235 int dstx, dsty, dstw, dsth; | 1315 return -1; |
1236 | 1316 } |
1237 /* Clip the rectangle to the screen area */ | 1317 SDL_RenderPresent(); |
1238 srcx = 0; | |
1239 srcy = 0; | |
1240 srcw = overlay->w; | |
1241 srch = overlay->h; | |
1242 dstx = dstrect->x; | |
1243 dsty = dstrect->y; | |
1244 dstw = dstrect->w; | |
1245 dsth = dstrect->h; | |
1246 if (dstx < 0) { | |
1247 srcw += (dstx * overlay->w) / dstrect->w; | |
1248 dstw += dstx; | |
1249 srcx -= (dstx * overlay->w) / dstrect->w; | |
1250 dstx = 0; | |
1251 } | |
1252 if ((dstx + dstw) > SDL_VideoSurface->w) { | |
1253 int extra = (dstx + dstw - SDL_VideoSurface->w); | |
1254 srcw -= (extra * overlay->w) / dstrect->w; | |
1255 dstw -= extra; | |
1256 } | |
1257 if (dsty < 0) { | |
1258 srch += (dsty * overlay->h) / dstrect->h; | |
1259 dsth += dsty; | |
1260 srcy -= (dsty * overlay->h) / dstrect->h; | |
1261 dsty = 0; | |
1262 } | |
1263 if ((dsty + dsth) > SDL_VideoSurface->h) { | |
1264 int extra = (dsty + dsth - SDL_VideoSurface->h); | |
1265 srch -= (extra * overlay->h) / dstrect->h; | |
1266 dsth -= extra; | |
1267 } | |
1268 if (srcw <= 0 || srch <= 0 || srch <= 0 || dsth <= 0) { | |
1269 return 0; | |
1270 } | |
1271 /* Ugh, I can't wait for SDL_Rect to be int values */ | |
1272 src.x = srcx; | |
1273 src.y = srcy; | |
1274 src.w = srcw; | |
1275 src.h = srch; | |
1276 dst.x = dstx; | |
1277 dst.y = dsty; | |
1278 dst.w = dstw; | |
1279 dst.h = dsth; | |
1280 return overlay->hwfuncs->Display(_this, overlay, &src, &dst); | |
1281 } | 1318 } |
1282 | 1319 |
1283 void | 1320 void |
1284 SDL_FreeYUVOverlay(SDL_Overlay * overlay) | 1321 SDL_FreeYUVOverlay(SDL_Overlay * overlay) |
1285 { | 1322 { |
1286 SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
1287 if (overlay) { | 1323 if (overlay) { |
1288 if (overlay->hwfuncs) { | 1324 if (overlay->hwdata) { |
1289 overlay->hwfuncs->FreeHW(_this, overlay); | 1325 if (overlay->hwdata->textureID) { |
1326 SDL_DestroyTexture(overlay->hwdata->textureID); | |
1327 } | |
1328 SDL_free(overlay->hwdata); | |
1290 } | 1329 } |
1291 SDL_free(overlay); | 1330 SDL_free(overlay); |
1292 } | 1331 } |
1293 } | 1332 } |
1294 #endif | |
1295 | 1333 |
1296 /* vi: set ts=4 sw=4 expandtab: */ | 1334 /* vi: set ts=4 sw=4 expandtab: */ |