Hi,
Blitting of YV12 and I420 formats should not be too difficult. It's
just an 8bpp to 8bpp blit with rect->h = rect->h + rect->h/2, right?
I think the difficult part is how to add clipping support when you have
3 different planes.
So, can we just clip/blit each plane separately? The following patch
adds planar blitting to dfb_gfxcard_blit. It actually subdivides the
region into 5 subregions (1 for Y-plane, 2 for the U and V planes each),
and each subregion separately undergoes a clip and a blit. It looks
pretty ugly right now but I have tested that at least the blitting
works. I haven't tested the clipping part.
Is it worthwhile to pursue this path? Anything that I might have
missed? Any comments?
Thanks
Tony
PS: The patch is against DirectFB-0.9.11.
diff -Naur DirectFB-0.9.11-orig/src/core/gfxcard.c DirectFB-0.9.11/src/core/gfxcard.c
--- DirectFB-0.9.11-orig/src/core/gfxcard.c Mon Jun 3 18:00:53 2002
+++ DirectFB-0.9.11/src/core/gfxcard.c Sat Jun 15 06:10:28 2002
@@ -818,6 +818,10 @@
void dfb_gfxcard_blit( DFBRectangle *rect, int dx, int dy, CardState *state )
{
+ DFBRectangle urect1, urect2, vrect1, vrect2;
+ DFBRegion uclip1, uclip2, vclip1, vclip2;
+ int udx1, udy1, udx2, udy2, vdx1, vdy1, vdx2, vdy2, planar_blit = 0;
+
dfb_state_lock( state );
if (!dfb_clip_blit_precheck( &state->clip, rect->w, rect->h, dx, dy )) {
@@ -826,6 +830,58 @@
return;
}
+ /*
+ * Planar blitting: To accomodate clipping, the 3 planes have to be subdivided into
+ * 5 planes, 1 Y-plane, 2 U-planes, and 2 V-planes.
+ *
+ * ----------------------
+ * | |
+ * | |
+ * | Y |
+ * | |
+ * ----------------------
+ * | U1 | U2 |
+ * ----------------------
+ * | V1 | V2 |
+ * ----------------------
+ *
+ * each of the U and V sub-planes will have:
+ * width = 1/2 of Y-plane width
+ * height = 1/4 of Y-plane height
+ *
+ * If we disregard clipping, planar blitting can be done simply enough just by
+ * adding the following statement:
+ * rect->h += rect->h >> 1;
+ *
+ * Question: Maybe we can do this at the lower levels, gBlit for instance?
+ */
+ if ((state->source->format == DSPF_YV12 && state->destination->format == DSPF_YV12) ||
+ (state->source->format == DSPF_I420 && state->destination->format == DSPF_I420)) {
+
+ urect1.x = vrect1.x = rect->x;
+ urect1.y = urect2.y = rect->y + rect->h;
+ urect2.x = vrect2.x = rect->x + (rect->w >> 1);
+ vrect1.y = vrect2.y = urect1.y + (rect->h >> 2);
+ urect1.w = urect2.w = vrect1.w = vrect2.w = rect->w >> 1;
+ urect1.h = urect2.h = vrect1.h = vrect2.h = rect->h >> 2;
+
+ udx1 = vdx1 = dx;
+ udy1 = udy2 = dy + rect->h;
+ udx2 = vdx2 = dx + urect1.w;
+ vdy1 = vdy2 = udy1 + urect1.h;
+
+ uclip1.x1 = vclip1.x1 = state->clip.x1 >> 1;
+ uclip1.x2 = vclip1.x2 = state->clip.x2 >> 1;
+ uclip1.y1 = uclip2.y1 = (state->clip.y1 >> 2) + rect->h;
+ uclip1.y2 = uclip2.y2 = (state->clip.y2 >> 2) + rect->h;
+ uclip2.x1 = vclip2.x1 = uclip1.x1 + urect1.w;
+ uclip2.x2 = vclip2.x2 = uclip1.x2 + urect1.w;
+ vclip1.y1 = vclip2.y1 = uclip1.y1 + urect1.h;
+ vclip1.y2 = vclip2.y2 = uclip1.y2 + urect1.h;
+
+ planar_blit = 1;
+ }
+
if (dfb_gfxcard_state_check( state, DFXL_BLIT ) &&
dfb_gfxcard_state_acquire( state, DFXL_BLIT )) {
if (!(Scard->device_info.caps.flags & CCF_CLIPPING))
@@ -839,6 +895,17 @@
if (gAquire( state, DFXL_BLIT )) {
dfb_clip_blit( &state->clip, rect, &dx, &dy );
gBlit( rect, dx, dy );
+ if (planar_blit) {
+ dfb_clip_blit( &uclip1, &urect1, &udx1, &udy1 );
+ dfb_clip_blit( &uclip2, &urect2, &udx2, &udy2 );
+ dfb_clip_blit( &vclip1, &vrect1, &vdx1, &vdy1 );
+ dfb_clip_blit( &vclip2, &vrect2, &vdx2, &vdy2 );
+
+ gBlit( &urect1, udx1, udy1 );
+ gBlit( &urect2, udx2, udy2 );
+ gBlit( &vrect1, vdx1, vdy1 );
+ gBlit( &vrect2, vdx2, vdy2 );
+ }
gRelease( state );
}
}
diff -Naur DirectFB-0.9.11-orig/src/gfx/generic/generic.c DirectFB-0.9.11/src/gfx/generic/generic.c
--- DirectFB-0.9.11-orig/src/gfx/generic/generic.c Mon Jun 3 19:54:33 2002
+++ DirectFB-0.9.11/src/gfx/generic/generic.c Sat Jun 15 06:10:27 2002
@@ -291,8 +291,8 @@
NULL,
#endif
Bop_16_to_Aop,
- NULL,
- NULL
+ Bop_8_to_Aop,
+ Bop_8_to_Aop
};
/********************************* Bop_PFI_Kto_Aop_PFI ************************/