Denis Oliver Kropp wrote:

Quoting Claudio KLaN Ciccani:


  f = (srect->h << 16) / drect->h;
+     h = drect->h;

  Aop_xy( gfxs, gfxs->dst_org, drect->x, drect->y, gfxs->dst_pitch );
  Bop_xy( gfxs, gfxs->src_org, srect->x, srect->y, gfxs->src_pitch );

-     while (drect->h--) {
+     while (h--) {
       RUN_PIPELINE();

Aop_next( gfxs, gfxs->dst_pitch );
@@ -4648,6 +4652,39 @@
Bop_next( gfxs, gfxs->src_pitch );
}
}
+
+ /* scale other planes */
+ if (gfxs->src_format == DSPF_YV12 || gfxs->src_format == DSPF_I420) {
+ void *splane1 = gfxs->src_org + (gfxs->src_pitch * gfxs->src_height)
+ + ((gfxs->src_pitch * srect->y) / 4) + (srect->x / 2);
+ void *splane2 = splane1 + ((gfxs->src_pitch * gfxs->src_height) / 4);
+ void *dplane1 = gfxs->dst_org + (gfxs->dst_pitch * gfxs->dst_height)
+ + ((gfxs->dst_pitch * drect->y) / 4) + (drect->x / 2);
+ void *dplane2 = dplane1 + ((gfxs->dst_pitch * gfxs->dst_height) / 4);
+ int spitch = gfxs->src_pitch / 2;
+ int dpitch = gfxs->dst_pitch / 2;
+
+ gfxs->length = drect->w / 2;
+ h = drect->h / 2;
+ i = 0;
+
+ while (h--) {
+ gfxs->Bop = splane1 + (i >> 16) * spitch;
+ gfxs->Aop = dplane1;




You should use ?op_xy() and ?op_next() to do this stuff.




I can use ?op_xy but not ?op_next because I'm processing two
planes at once to save time.



+
+ RUN_PIPELINE();
+
+ gfxs->Bop = splane2 + (i >> 16) * spitch;
+ gfxs->Aop = dplane2;
+
+ RUN_PIPELINE();
+
+ dplane1 += dpitch;
+ dplane2 += dpitch;




I think blitting the planes one at a time would be better.




It would be only slower, according to me.



I think it would be faster, if planes are stored sequentially in memory one after the other.




I have changed the patch, now it scales planes one at time.


------------------------------------------------------------------------
--- DirectFB/src/gfx/generic/generic.c 2004-06-10 12:53:05.000000000 +0200
+++ /home/klan/src/DirectFB/src/gfx/generic/generic.c 2004-06-10 18:43:22.000000000 +0200
@@ -867,11 +867,11 @@
Bop_32_Sto_Aop,
Bop_32_Sto_Aop,
Bop_8_Sto_Aop,
- NULL,
+ Bop_32_Sto_Aop,
+ Bop_8_Sto_Aop,
+ Bop_32_Sto_Aop,
+ Bop_8_Sto_Aop,
Bop_8_Sto_Aop,
- NULL,
- NULL,
- NULL,
Bop_8_Sto_Aop,
Bop_8_Sto_Aop,
Bop_32_Sto_Aop
@@ -3834,10 +3834,10 @@
case DSPF_UYVY:
case DSPF_I420:
case DSPF_YV12:
- if (accel != DFXL_BLIT ||
+ if (accel & ~(DFXL_BLIT | DFXL_STRETCHBLIT) ||
gfxs->src_format != gfxs->dst_format ||
state->blittingflags != DSBLIT_NOFX) {
- D_ONCE("only copying blits supported for YUV in software");
+ D_ONCE("only copying/scaling blits supported for YUV in software");
return false;
}
break;
@@ -4623,20 +4623,24 @@


     int f;
     int i = 0;
+     int h;

     D_ASSERT( gfxs != NULL );

     CHECK_PIPELINE();

-     gfxs->length = drect->w;
     gfxs->SperD  = (srect->w << 16) / drect->w;
+     gfxs->length = drect->w;
+     if (gfxs->src_format == DSPF_YUY2 || gfxs->src_format == DSPF_UYVY)
+      gfxs->length /= 2;

     f = (srect->h << 16) / drect->h;
+     h = drect->h;

     Aop_xy( gfxs, gfxs->dst_org, drect->x, drect->y, gfxs->dst_pitch );
     Bop_xy( gfxs, gfxs->src_org, srect->x, srect->y, gfxs->src_pitch );

-     while (drect->h--) {
+     while (h--) {
          RUN_PIPELINE();

Aop_next( gfxs, gfxs->dst_pitch );
@@ -4648,6 +4652,53 @@
Bop_next( gfxs, gfxs->src_pitch );
}
}
+
+ /* scale other planes */
+ if (gfxs->src_format == DSPF_YV12 || gfxs->src_format == DSPF_I420) {
+ void *sorg = gfxs->src_org + (gfxs->src_pitch * gfxs->src_height);
+ void *dorg = gfxs->dst_org + (gfxs->dst_pitch * gfxs->dst_height);
+ int spitch = gfxs->src_pitch / 2;
+ int dpitch = gfxs->dst_pitch / 2;
+
+ gfxs->length = drect->w / 2;
+
+ Aop_xy( gfxs, dorg, drect->x / 2, drect->y / 2, dpitch );
+ Bop_xy( gfxs, sorg, srect->x / 2, srect->y / 2, spitch );
+
+ /* scale first plane */
+ for (h = 0, i = 0; h < (drect->h / 2); h++) {
+ RUN_PIPELINE();
+
+ Aop_next( gfxs, dpitch );
+
+ i += f;
+
+ while (i > 0xFFFF) {
+ i -= 0x10000;
+ Bop_next( gfxs, spitch );
+ }
+ }
+
+ sorg += (spitch * gfxs->src_height) / 2;
+ dorg += (dpitch * gfxs->dst_height) / 2;
+
+ Aop_xy( gfxs, dorg, drect->x / 2, drect->y / 2, dpitch );
+ Bop_xy( gfxs, sorg, srect->x / 2, srect->y / 2, spitch );
+
+ /* scale second plane */
+ for (h = 0, i = 0; h < (drect->h / 2); h++) {
+ RUN_PIPELINE();
+
+ Aop_next( gfxs, dpitch );
+
+ i += f;
+
+ while (i > 0xFFFF) {
+ i -= 0x10000;
+ Bop_next( gfxs, spitch );
+ }
+ } + }
}








Reply via email to