bool davinciStretchBlit32( void *drv, void *dev, DFBRectangle *srect, DFBRectangle *drect ) { DavinciDriverData *ddrv = drv; DavinciDeviceData *ddev = dev; DFBRegion clip = DFB_REGION_INIT_FROM_RECTANGLE( drect ); D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(drect), DFB_RECTANGLE_VALS(srect) ); if (!dfb_region_region_intersect( &clip, &ddev->clip )) return true; dfb_region_translate( &clip, -drect->x, -drect->y ); davinci_c64x_stretch_32__L( &ddrv->tasks, ddev->dst_phys + ddev->dst_pitch * drect->y + ddev->dst_bpp * drect->x, ddev->dst_pitch, ddev->src_phys + ddev->src_pitch * srect->y + ddev->src_bpp * srect->x, ddev->src_pitch, drect->w, drect->h, srect->w, srect->h, &clip ); return true; }
static bool stretch_hvx( CardState *state, DFBRectangle *srect, DFBRectangle *drect ) { GenefxState *gfxs; const StretchFunctionTable *table; StretchHVx stretch; bool down = false; void *dst; void *src; StretchCtx ctx; int idx = STRETCH_NONE; u32 colors[256]; D_ASSERT( state != NULL ); DFB_RECTANGLE_ASSERT( srect ); DFB_RECTANGLE_ASSERT( drect ); gfxs = state->gfxs; if (srect->w > drect->w && srect->h > drect->h) down = true; if (down) { if (!(state->render_options & DSRO_SMOOTH_DOWNSCALE)) return false; } else { if (!(state->render_options & DSRO_SMOOTH_UPSCALE)) return false; } switch (gfxs->dst_format) { case DSPF_NV12: case DSPF_NV21: return stretch_hvx_planar( state, srect, drect, down ); default: break; } if (state->blittingflags & ~(DSBLIT_COLORKEY_PROTECT | DSBLIT_SRC_COLORKEY | DSBLIT_SRC_PREMULTIPLY)) return false; if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY && !DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) return false; if (DFB_PIXELFORMAT_INDEX(gfxs->dst_format) >= D_ARRAY_SIZE(stretch_tables)) return false; if (DFB_PIXELFORMAT_INDEX(gfxs->src_format) >= D_ARRAY_SIZE((stretch_tables[0])->f)) return false; table = stretch_tables[DFB_PIXELFORMAT_INDEX(gfxs->dst_format)]; if (!table) return false; if (state->blittingflags & DSBLIT_SRC_COLORKEY) idx |= STRETCH_SRCKEY; if (state->blittingflags & DSBLIT_COLORKEY_PROTECT) idx |= STRETCH_PROTECT; if (down) stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].down[idx]; else stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].up[idx]; if (!stretch) return false; ctx.clip = state->clip; if (!dfb_region_rectangle_intersect( &ctx.clip, drect )) return false; dfb_region_translate( &ctx.clip, - drect->x, - drect->y ); if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) { int i; const DFBColor *entries; u16 *colors16 = (void*) colors; D_ASSERT( gfxs->Blut != NULL ); entries = gfxs->Blut->entries; switch (gfxs->dst_format) { case DSPF_ARGB: if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { for (i=0; i<gfxs->Blut->num_entries; i++) { int alpha = entries[i].a + 1; switch (alpha) { case 0: colors[i] = 0; break; case 255: colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); break; default: colors[i] = PIXEL_ARGB( entries[i].a, (alpha * entries[i].r) >> 8, (alpha * entries[i].g) >> 8, (alpha * entries[i].b) >> 8 ); } } } else { for (i=0; i<gfxs->Blut->num_entries; i++) colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); } break; case DSPF_RGB32: for (i=0; i<gfxs->Blut->num_entries; i++) colors[i] = PIXEL_RGB32( entries[i].r, entries[i].g, entries[i].b ); break; case DSPF_RGB16: for (i=0; i<gfxs->Blut->num_entries; i++) colors16[i] = PIXEL_RGB16( entries[i].r, entries[i].g, entries[i].b ); break; case DSPF_ARGB4444: if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { for (i=0; i<gfxs->Blut->num_entries; i++) { int alpha = entries[i].a + 1; switch (alpha) { case 0: colors16[i] = 0; break; case 255: colors16[i] = PIXEL_ARGB4444( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); break; default: colors16[i] = PIXEL_ARGB4444( entries[i].a, (alpha * entries[i].r) >> 8, (alpha * entries[i].g) >> 8, (alpha * entries[i].b) >> 8 ); } } } else { for (i=0; i<gfxs->Blut->num_entries; i++)
static bool stretch_hvx_planar( CardState *state, DFBRectangle *srect, DFBRectangle *drect, bool down ) { GenefxState *gfxs; void *dst; void *src; DFBRegion clip; D_ASSERT( state != NULL ); DFB_RECTANGLE_ASSERT( srect ); DFB_RECTANGLE_ASSERT( drect ); gfxs = state->gfxs; if (state->blittingflags) return false; if (gfxs->dst_format != gfxs->src_format) return false; clip = state->clip; if (!dfb_region_rectangle_intersect( &clip, drect )) return false; dfb_region_translate( &clip, - drect->x, - drect->y ); dst = gfxs->dst_org[0] + drect->y * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x ); src = gfxs->src_org[0] + srect->y * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x ); switch (gfxs->dst_format) { case DSPF_NV12: case DSPF_NV21: if (down) stretch_hvx_8_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch, srect->w, srect->h, drect->w, drect->h, &clip ); else stretch_hvx_8_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch, srect->w, srect->h, drect->w, drect->h, &clip ); clip.x1 /= 2; clip.x2 /= 2; clip.y1 /= 2; clip.y2 /= 2; dst = gfxs->dst_org[1] + drect->y/2 * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x ); src = gfxs->src_org[1] + srect->y/2 * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x ); if (down) stretch_hvx_88_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch, srect->w/2, srect->h, drect->w/2, drect->h, &clip ); else stretch_hvx_88_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch, srect->w/2, srect->h, drect->w/2, drect->h, &clip ); break; default: break; } return true; }