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