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: */