}
}
- doublebuf = (flags & SDL_DOUBLEBUF) ? 1 : 0;
+ /* always use doublebuf, when SDL_DOUBLEBUF is not set,
+ * we'll have to blit manually on UpdateRects() */
+ doublebuf = 1;
+
fbmem = osdl_video_set_mode(pdata,
pdata->border_l, pdata->border_r, pdata->border_t, pdata->border_b,
width, height, bpp, &doublebuf, this->wm_title);
pdata->border_l, pdata->border_r, pdata->border_t, pdata->border_b);
return NULL;
}
- if ((flags & SDL_DOUBLEBUF) && !doublebuf) {
- log("doublebuffering could not be set\n");
- flags &= ~SDL_DOUBLEBUF;
+ pdata->front_buffer = osdl_video_get_active_buffer(pdata);
+ if (pdata->front_buffer == NULL) {
+ err("osdl_video_get_active_buffer failed\n");
+ return NULL;
+ }
+
+ if (!doublebuf) {
+ if (flags & SDL_DOUBLEBUF) {
+ log("doublebuffering could not be set\n");
+ flags &= ~SDL_DOUBLEBUF;
+ }
+ /* XXX: could just malloc a back buffer here instead */
+ pdata->cfg_force_directbuf = 1;
}
+ if (!(flags & SDL_DOUBLEBUF) && pdata->cfg_force_directbuf)
+ fbmem = pdata->front_buffer;
+
flags |= SDL_FULLSCREEN | SDL_HWSURFACE;
unhandled_flags = flags & ~(SDL_FULLSCREEN | SDL_HWSURFACE | SDL_DOUBLEBUF);
if (unhandled_flags != 0) {
static int omap_FlipHWSurface(SDL_VideoDevice *this, SDL_Surface *surface)
{
struct SDL_PrivateVideoData *pdata = this->hidden;
+ static int warned;
trace("%p", surface);
- surface->pixels = osdl_video_flip(pdata);
+ if (surface != this->screen) {
+ if (!warned) {
+ err("flip surface %p which is not screen %p?\n",
+ surface, this->screen);
+ warned = 1;
+ }
+ return;
+ }
+
+ if (surface->flags & SDL_DOUBLEBUF)
+ surface->pixels = osdl_video_flip(pdata);
+ else {
+ if (surface->pixels != pdata->front_buffer)
+ memcpy(surface->pixels, pdata->front_buffer,
+ surface->pitch * surface->h);
+ }
+
pdata->app_uses_flip = 1;
return 0;
static void omap_UpdateRects(SDL_VideoDevice *this, int nrects, SDL_Rect *rects)
{
struct SDL_PrivateVideoData *pdata = this->hidden;
+ SDL_Surface *screen = this->screen;
+ int fullscreen_blit = 0;
+ int i, Bpp, x, y, w, h;
+ char *src, *dst;
trace("%d, %p", nrects, rects);
- /* for doublebuf forcing on apps */
- if (nrects == 1 && rects->x == 0 && rects->y == 0
- && !pdata->app_uses_flip && (this->screen->flags & SDL_DOUBLEBUF)
- && rects->w == this->screen->w && rects->h == this->screen->h)
- {
- this->screen->pixels = osdl_video_flip(pdata);
+ fullscreen_blit =
+ nrects == 1 && rects->x == 0 && rects->y == 0
+ && (rects->w == screen->w || rects->w == 0)
+ && (rects->h == screen->h || rects->h == 0);
+
+ if (screen->flags & SDL_DOUBLEBUF) {
+ if (fullscreen_blit && !pdata->app_uses_flip)
+ screen->pixels = osdl_video_flip(pdata);
+ return;
+ }
+
+ src = screen->pixels;
+ dst = pdata->front_buffer;
+ if (src == dst)
+ return;
+
+ if (fullscreen_blit) {
+ memcpy(dst, src, screen->pitch * screen->h);
+ return;
+ }
+
+ for (i = 0, Bpp = screen->format->BytesPerPixel; i < nrects; i++) {
+ /* this supposedly has no clipping, but we'll do it anyway */
+ x = rects[i].x, y = rects[i].y, w = rects[i].w, h = rects[i].h;
+ if (x < 0)
+ w += x, x = 0;
+ else if (x + w > screen->w)
+ w = screen->w - x;
+ if (w <= 0)
+ continue;
+
+ if (y < 0)
+ h += y, y = 0;
+ else if (y + h > screen->h)
+ h = screen->h - y;
+
+ for (; h > 0; y++, h--)
+ memcpy(dst + y * screen->pitch + x * Bpp,
+ src + y * screen->pitch + x * Bpp,
+ w * Bpp);
}
}