On Tue, May 19, 2009 at 05:32:06PM -0700, Strelchun, Timothy wrote:
> I just realized a behavior change in our new DFB 1.2 based systems driver as 
> compared to our previous 1.0 based driver...
> 
> Newly created visible and non-visible surfaces do not appear to be cleared 
> after they are allocated (previously done by default window stack I believe).
> 
> Is it an expectation of a CoreSurfaceBuffer Pool Manager to clear newly 
> allocated raw pixel buffers?

If it's not the first allocation for the buffer then clearing it would
just waste resources since the surface core will overwrite it with the
old data anyway. I just cooked up the attached patch that should clear
only the first allocation for each buffer. I just implemented it in the
surface core with CPU access to make it simple and generic.

-- 
Ville Syrjälä
syrj...@sci.fi
http://www.sci.fi/~syrjala/
>From ce5d76db0ad2e519c9c0b1978ab95847e8638176 Mon Sep 17 00:00:00 2001
From: Ville Syrjala <syrj...@sci.fi>
Date: Wed, 20 May 2009 22:37:44 +0300
Subject: [PATCH] surfaces: Clear fresh buffers

When accessing the first allocation for a buffer for the first time
clear it to black.
---
 src/core/surface_buffer.c |  137 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 137 insertions(+), 0 deletions(-)

diff --git a/src/core/surface_buffer.c b/src/core/surface_buffer.c
index 6d2a23d..5bc09ea 100644
--- a/src/core/surface_buffer.c
+++ b/src/core/surface_buffer.c
@@ -980,6 +980,135 @@ transfer_buffer( CoreSurfaceBuffer *buffer,
      }
 }
 
+static void
+clear_buffer( CoreSurfaceBuffer *buffer,
+              void              *dst,
+              int                pitch )
+{
+     u32          pixel;
+     int          i;
+     CoreSurface *surface;
+
+     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+     surface = buffer->surface;
+     D_MAGIC_ASSERT( surface, CoreSurface );
+
+     D_DEBUG_AT( Core_SurfBuffer, "%s( %p %p [%d] ) * %d\n",
+                 __FUNCTION__, buffer, dst, pitch, surface->config.size.h );
+
+     D_ASSERT( dst != NULL );
+     D_ASSERT( pitch > 0 );
+
+     D_ASSERT( pitch >= DFB_BYTES_PER_LINE( buffer->format, 
surface->config.size.w ) );
+
+     switch (buffer->format) {
+          case DSPF_YUY2:
+               pixel = 0x80108010;
+               break;
+          case DSPF_UYVY:
+               pixel = 0x10801080;
+               break;
+          case DSPF_AiRGB:
+               pixel = 0xff000000;
+               break;
+          case DSPF_YV12:
+          case DSPF_I420:
+          case DSPF_NV12:
+          case DSPF_NV21:
+          case DSPF_NV16:
+               pixel = 0x10;
+               break;
+          default:
+               pixel = 0x00;
+               break;
+     }
+
+     switch (buffer->format) {
+          case DSPF_YUY2:
+          case DSPF_UYVY:
+          case DSPF_AiRGB:
+               for (i=0; i<surface->config.size.h; i++) {
+                    int  j;
+                    u32 *d = dst;
+
+                    for (j = 0; j<surface->config.size.w; j++)
+                         *d++ = pixel;
+
+                    dst += pitch;
+               }
+               break;
+          default:
+               for (i=0; i<surface->config.size.h; i++) {
+                    memset( dst, pixel, DFB_BYTES_PER_LINE( buffer->format, 
surface->config.size.w ) );
+                    dst += pitch;
+               }
+     }
+
+     switch (buffer->format) {
+          case DSPF_YV12:
+          case DSPF_I420:
+               for (i=0; i<surface->config.size.h; i++) {
+                    memset( dst, 0x80, DFB_BYTES_PER_LINE( buffer->format, 
surface->config.size.w / 2 ) );
+                    dst += pitch / 2;
+               }
+               break;
+
+          case DSPF_NV12:
+          case DSPF_NV21:
+               for (i=0; i<surface->config.size.h/2; i++) {
+                    memset( dst, 0x80, DFB_BYTES_PER_LINE( buffer->format, 
surface->config.size.w ) );
+                    dst += pitch;
+               }
+               break;
+
+          case DSPF_NV16:
+               for (i=0; i<surface->config.size.h; i++) {
+                    memset( dst, 0x80, DFB_BYTES_PER_LINE( buffer->format, 
surface->config.size.w ) );
+                    dst += pitch;
+               }
+               break;
+
+          default:
+               break;
+     }
+}
+
+static DFBResult
+allocation_clear( CoreSurfaceAllocation *allocation )
+{
+     DFBResult              ret;
+     CoreSurfaceBufferLock  lock;
+     CoreSurfaceBuffer     *buffer;
+
+     D_DEBUG_AT( Core_SurfBuffer, "%s()\n", __FUNCTION__ );
+
+     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+
+     buffer = allocation->buffer;
+     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+     D_ASSERT( fusion_vector_size( &buffer->allocs ) == 1 );
+
+     /* Lock the allocation. */
+     dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_WRITE );
+
+     ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
+     if (ret) {
+          D_DERROR( ret, "Core/SurfBuffer: Could not lock destination for 
transfer!\n" );
+          dfb_surface_buffer_lock_deinit( &lock );
+          return ret;
+     }
+
+     clear_buffer( buffer, lock.addr, lock.pitch );
+
+     dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
+
+     dfb_surface_buffer_lock_deinit( &lock );
+
+     return DFB_OK;
+}
+
 static DFBResult
 allocation_update_copy( CoreSurfaceAllocation *allocation,
                         CoreSurfaceAllocation *source )
@@ -1163,6 +1292,14 @@ dfb_surface_allocation_update( CoreSurfaceAllocation  
*allocation,
                D_DERROR( ret, "Core/SurfaceBuffer: Updating allocation 
failed!\n" );
                return ret;
           }
+     } else if (!buffer->written && !buffer->read) {
+          /* This is the first allocation so clear it. */
+          ret = allocation_clear( allocation );
+
+          if (ret) {
+               D_DERROR( ret, "Core/SurfaceBuffer: Clearing allocation 
failed!\n" );
+               return ret;
+          }
      }
 
      if (access & CSAF_WRITE) {
-- 
1.6.0.6

_______________________________________________
directfb-dev mailing list
directfb-dev@directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to