DirectFB - Home of the pragmatist Roadmap


[directfb-dev] Adding support for planar blitting
Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[directfb-dev] Adding support for planar blitting




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

Home | Main Index | Thread Index


directfb.org / Development / Old Archives