static int DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = data->target; DFBRegion clip_region; int i; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); destsurf->GetClip(destsurf, &clip_region); for (i=0; i<count; i++) { SDL_Rect dst = {rects[i]->x, rects[i]->y, rects[i]->w, rects[i]->h}; dst.x += clip_region.x1; dst.y += clip_region.y1; SDL_DFB_CHECKERR(destsurf->DrawRectangle(destsurf, dst.x, dst.y, dst.w, dst.h)); } return 0; error: return -1; }
static void DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; DirectFB_ActivateRenderer(renderer); if (!data) { return; } SDL_DFB_RELEASE(data->palette); SDL_DFB_RELEASE(data->surface); if (data->display) { DFB_DisplayData *dispdata = (DFB_DisplayData *) data->display->driverdata; dispdata->vidIDinuse = 0; /* FIXME: Shouldn't we reset the cooperative level */ SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer, DLSCL_ADMINISTRATIVE)); SDL_DFB_RELEASE(dispdata->vidlayer); } SDL_DFB_FREE(data->pixels); SDL_free(data); texture->driverdata = NULL; }
static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = data->target; DFBRegion clip_region; int i; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); /* Use antialiasing when available */ #if (DFB_VERSION_ATLEAST(1,2,0)) SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS)); #endif destsurf->GetClip(destsurf, &clip_region); for (i=0; i < count - 1; i++) { int x1 = points[i].x + clip_region.x1; int y1 = points[i].y + clip_region.y1; int x2 = points[i + 1].x + clip_region.x1; int y2 = points[i + 1].y + clip_region.y1; SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x1, y1, x2, y2)); } return 0; error: return -1; }
static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { Uint32 sdl_format; unsigned char* laypixels; int laypitch; DFBSurfacePixelFormat dfb_format; DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *winsurf = data->target; DirectFB_ActivateRenderer(renderer); winsurf->GetPixelFormat(winsurf, &dfb_format); sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format); winsurf->Lock(winsurf, DSLF_READ, (void **) &laypixels, &laypitch); laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) ); SDL_ConvertPixels(rect->w, rect->h, sdl_format, laypixels, laypitch, format, pixels, pitch); winsurf->Unlock(winsurf); return 0; }
static void DirectFB_RenderPresent(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; SDL_DFB_WINDOWDATA(window); SDL_ShapeData *shape_data = (window->shaper ? window->shaper->driverdata : NULL); DirectFB_ActivateRenderer(renderer); if (shape_data && shape_data->surface) { /* saturate the window surface alpha channel */ SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE)); SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE)); SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND)); SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff)); SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h)); /* blit the mask */ SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR)); SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO)); SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL)); #if (DFB_VERSION_ATLEAST(1,2,0)) SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE)); #endif SDL_DFB_CHECK(windata->surface->Blit(windata->surface, shape_data->surface, NULL, 0, 0)); } /* Send the data to the display */ SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL, data->flipflags)); }
static int DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; Uint8 *dpixels; int dpitch; Uint8 *src, *dst; int row; size_t length; int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)); /* FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes */ DirectFB_ActivateRenderer(renderer); if ((texture->format == SDL_PIXELFORMAT_YV12) || (texture->format == SDL_PIXELFORMAT_IYUV)) { bpp = 1; } SDL_DFB_CHECKERR(data->surface->Lock(data->surface, DSLF_WRITE | DSLF_READ, ((void **) &dpixels), &dpitch)); src = (Uint8 *) pixels; dst = (Uint8 *) dpixels + rect->y * dpitch + rect->x * bpp; length = rect->w * bpp; for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; dst += dpitch; } /* copy other planes for 3 plane formats */ if ((texture->format == SDL_PIXELFORMAT_YV12) || (texture->format == SDL_PIXELFORMAT_IYUV)) { src = (Uint8 *) pixels + texture->h * pitch; dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2; for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) { SDL_memcpy(dst, src, length / 2); src += pitch / 2; dst += dpitch / 2; } src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4; dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2; for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) { SDL_memcpy(dst, src, length / 2); src += pitch / 2; dst += dpitch / 2; } } SDL_DFB_CHECKERR(data->surface->Unlock(data->surface)); data->isDirty = 0; return 0; error: return 1; }
static void DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; DirectFB_ActivateRenderer(renderer); if (texturedata->display) { SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface)); texturedata->pixels = NULL; } }
static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; DirectFB_TextureData *tex_data = NULL; DirectFB_ActivateRenderer(renderer); if (texture) { tex_data = (DirectFB_TextureData *) texture->driverdata; data->target = tex_data->surface; } else { data->target = get_dfb_surface(data->window); } data->lastBlendMode = 0; return 0; }
int DirectFB_RenderClear(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = data->target; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); destsurf->Clear(destsurf, renderer->r, renderer->g, renderer->b, renderer->a); return 0; }
static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = get_dfb_surface(data->window); int i; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); for (i=0; i < count; i++) SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i].x, points[i].y)); return 0; error: return -1; }
static int DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = get_dfb_surface(data->window); int i; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); for (i=0; i<count; i++) SDL_DFB_CHECKERR(destsurf->DrawRectangle(destsurf, rects[i]->x, rects[i]->y, rects[i]->w, rects[i]->h)); return 0; error: return -1; }
static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = data->target; DFBRegion clip_region; int i; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); destsurf->GetClip(destsurf, &clip_region); for (i=0; i < count; i++) { int x = points[i].x + clip_region.x1; int y = points[i].y + clip_region.y1; SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x, y, x, y)); } return 0; error: return -1; }
static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = get_dfb_surface(data->window); int i; DirectFB_ActivateRenderer(renderer); PrepareDraw(renderer); /* Use antialiasing when available */ #if (DFB_VERSION_ATLEAST(1,2,0)) SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS)); #endif for (i=0; i < count - 1; i++) SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i+1].x, points[i+1].y)); return 0; error: return -1; }
static int DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; DirectFB_ActivateRenderer(renderer); #if 0 if (markDirty) { SDL_AddDirtyRect(&texturedata->dirty, rect); } #endif if (texturedata->display) { void *fdata; int fpitch; SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface, DSLF_WRITE | DSLF_READ, &fdata, &fpitch)); *pitch = fpitch; *pixels = fdata; } else { *pixels = (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format))); *pitch = texturedata->pitch; texturedata->isDirty = 1; } return 0; error: return -1; }
static int DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { SDL_Window *window = renderer->window; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DFB_DEVICEDATA(display->device); DirectFB_TextureData *data; DFBSurfaceDescription dsc; DFBSurfacePixelFormat pixelformat; DirectFB_ActivateRenderer(renderer); SDL_DFB_ALLOC_CLEAR(data, sizeof(*data)); texture->driverdata = data; /* find the right pixelformat */ pixelformat = DirectFB_SDLToDFBPixelFormat(texture->format); if (pixelformat == DSPF_UNKNOWN) { SDL_SetError("Unknown pixel format %d\n", data->format); goto error; } data->format = texture->format; data->pitch = texture->w * DFB_BYTES_PER_PIXEL(pixelformat); if (DirectFB_AcquireVidLayer(renderer, texture) != 0) { /* fill surface description */ dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; dsc.width = texture->w; dsc.height = texture->h; if(texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { /* dfb has problems with odd sizes -make them even internally */ dsc.width += (dsc.width % 2); dsc.height += (dsc.height % 2); } /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance * No DSCAPS_SYSTEMONLY either - let dfb decide * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8 * Depends on other settings as well. Let dfb decide. */ dsc.caps = DSCAPS_PREMULTIPLIED; #if 0 if (texture->access == SDL_TEXTUREACCESS_STREAMING) dsc.caps |= DSCAPS_SYSTEMONLY; else dsc.caps |= DSCAPS_VIDEOONLY; #endif dsc.pixelformat = pixelformat; data->pixels = NULL; /* Create the surface */ SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, &data->surface)); if (SDL_ISPIXELFORMAT_INDEXED(data->format) && !SDL_ISPIXELFORMAT_FOURCC(data->format)) { #if 1 SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &data->palette)); #else /* DFB has issues with blitting LUT8 surfaces. * Creating a new palette does not help. */ DFBPaletteDescription pal_desc; pal_desc.flags = DPDESC_SIZE; /* | DPDESC_ENTRIES */ pal_desc.size = 256; SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette)); SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette)); #endif } } #if (DFB_VERSION_ATLEAST(1,2,0)) data->render_options = DSRO_NONE; #endif if (texture->access == SDL_TEXTUREACCESS_STREAMING) { /* 3 plane YUVs return 1 bpp, but we need more space for other planes */ if(texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->h * data->pitch + ((texture->h + texture->h % 2) * (data->pitch + data->pitch % 2) * 2) / 4)); } else { SDL_DFB_ALLOC_CLEAR(data->pixels, texture->h * data->pitch); } } return 0; error: SDL_DFB_RELEASE(data->palette); SDL_DFB_RELEASE(data->surface); SDL_DFB_FREE(texture->driverdata); return -1; }
static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = data->target; DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; Uint8 alpha, r, g, b; DFBRegion clip_region; DFBRectangle sr, dr; DirectFB_ActivateRenderer(renderer); SDLtoDFBRect(srcrect, &sr); SDLtoDFBRect_Float(dstrect, &dr); destsurf->GetClip(destsurf, &clip_region); dr.x += clip_region.x1; dr.y += clip_region.y1; if (texturedata->display) { int px, py; SDL_Window *window = renderer->window; IDirectFBWindow *dfbwin = get_dfb_window(window); SDL_DFB_WINDOWDATA(window); SDL_VideoDisplay *display = texturedata->display; DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; SDL_DFB_CHECKERR(dispdata-> vidlayer->SetSourceRectangle(dispdata->vidlayer, sr.x, sr.y, sr.w, sr.h)); dfbwin->GetPosition(dfbwin, &px, &py); px += windata->client.x; py += windata->client.y; SDL_DFB_CHECKERR(dispdata-> vidlayer->SetScreenRectangle(dispdata->vidlayer, px + dr.x, py + dr.y, dr.w, dr.h)); } else { DFBSurfaceBlittingFlags flags = 0; #if 0 if (texturedata->dirty.list) { SDL_DirtyRect *dirty; void *pixels; int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)); int pitch = texturedata->pitch; for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { SDL_Rect *rect = &dirty->rect; pixels = (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch + rect->x * bpp); DirectFB_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch); } SDL_ClearDirtyRects(&texturedata->dirty); } #endif if (texturedata->isDirty) { SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = texture->w; rect.h = texture->h; DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch); } alpha = r = g = b = 0xff; if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){ alpha = texture->a; flags |= DSBLIT_BLEND_COLORALPHA; } if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { r = texture->r; g = texture->g; b = texture->b; flags |= DSBLIT_COLORIZE; } SDL_DFB_CHECKERR(destsurf-> SetColor(destsurf, r, g, b, alpha)); /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */ SetBlendMode(data, texture->blendMode, texturedata); SDL_DFB_CHECKERR(destsurf->SetBlittingFlags(destsurf, data->blitFlags | flags)); #if (DFB_VERSION_ATLEAST(1,2,0)) SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf, texturedata-> render_options)); #endif if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { SDL_DFB_CHECKERR(destsurf->Blit(destsurf, texturedata->surface, &sr, dr.x, dr.y)); } else { SDL_DFB_CHECKERR(destsurf->StretchBlit(destsurf, texturedata->surface, &sr, &dr)); } } return 0; error: return -1; }