From bccb06f609e86327cfbc96ec32214339d16c7347 Mon Sep 17 00:00:00 2001
From: Timothy Strelchun <Timothy.Strelchun@Intel.Com>
Date: Sun, 15 May 2011 01:14:00 -0700
Subject: [PATCH] Added buffer alloc destroy notify message.
 Added a surface notification message sent for each buffer allocation
 that is destroyed.  It is sent by the dfb_surface_pool_deallocate
 function using a new notify function called dfb_surface_pool_notify.

A graphics driver that allocates custom shared/local resources for a
buffer allocation from any surface pool (such as the pre-allocated
memory one) should register to receive this new buffer allocation
destruction message.  This will give the graphics driver (in each
registered process) an opportunity to destroy those associated custom
shared/local resources.
---
 src/core/surface.c      |   54 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/core/surface.h      |   26 ++++++++++++++++++++--
 src/core/surface_pool.c |    7 ++++++
 3 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/src/core/surface.c b/src/core/surface.c
index 4f8bb5f..e6b5ed9 100644
--- a/src/core/surface.c
+++ b/src/core/surface.c
@@ -1,5 +1,5 @@
 /*
-   (c) Copyright 2001-2010  The world wide DirectFB Open Source Community (directfb.org)
+   (c) Copyright 2001-2011  The world wide DirectFB Open Source Community (directfb.org)
    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
 
    All rights reserved.
@@ -409,6 +409,13 @@ dfb_surface_notify( CoreSurface                  *surface,
      FUSION_SKIRMISH_ASSERT( &surface->lock );
      D_FLAGS_ASSERT( flags, CSNF_ALL );
 
+     D_DEBUG_AT(
+          Core_Surface,
+          "Notifying of Surface message. SurfaceID:%d MsgSize:%d %s()-%s:%d\n",
+          surface->object.id,
+          sizeof( CoreSurfaceNotification ),
+          __FUNCTION__, __FILE__, __LINE__ );
+
      direct_serial_increase( &surface->serial );
 
      if (!(surface->state & CSSF_DESTROYED)) {
@@ -442,6 +449,51 @@ dfb_surface_notify_display( CoreSurface       *surface,
 }
 
 DFBResult
+dfb_surface_pool_notify( CoreSurface                    *surface,
+                         CoreSurfaceBuffer              *buffer,
+                         CoreSurfaceAllocation          *allocation,
+                         CoreSurfaceNotificationFlags    flags )
+{
+     CoreSurfaceNotification notification;
+
+     D_MAGIC_ASSERT( surface, CoreSurface );
+     FUSION_SKIRMISH_ASSERT( &surface->lock );
+     D_FLAGS_ASSERT( flags, CSNF_ALL );
+
+     /* For the moment, the only supported message is surface buffer allocation destruction. */
+     D_ASSERT( flags == CSNF_BUFFER_ALLOCATION_DESTROY );
+     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+     D_ASSERT( buffer->surface == surface );
+     CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+     D_ASSERT( allocation->buffer == buffer );
+
+     D_DEBUG_AT(
+          Core_Surface,
+          "Notifying of Surface buffer allocation destruction. SurfaceID:%d MsgSize:%d %s()-%s:%d\n",
+          surface->object.id,
+          sizeof( CoreSurfaceNotification ),
+          __FUNCTION__, __FILE__, __LINE__ );
+
+     if (!(surface->state & CSSF_DESTROYED)) {
+          if (!(surface->notifications & flags))
+               return DFB_OK;
+     }
+
+     /*
+          Make a copy of all the data needed by the listeners.  This was found to be necessary
+          because no good way was found to wait for all the listeners to complete before the
+          buffer allocation is destroyed along with all of its underlying data structures.
+     */
+     notification.flags             = flags;
+     notification.surface           = surface;
+     notification.buffer_no_access  = buffer;
+     notification.surface_data      = surface->data;
+     notification.surface_object_id = surface->object.id;
+
+     return dfb_surface_dispatch( surface, &notification, dfb_surface_globals );
+}
+
+DFBResult
 dfb_surface_flip( CoreSurface *surface, bool swap )
 {
      unsigned int back, front;
diff --git a/src/core/surface.h b/src/core/surface.h
index acc3f3c..aa312fa 100644
--- a/src/core/surface.h
+++ b/src/core/surface.h
@@ -1,5 +1,5 @@
 /*
-   (c) Copyright 2001-2010  The world wide DirectFB Open Source Community (directfb.org)
+   (c) Copyright 2001-2011  The world wide DirectFB Open Source Community (directfb.org)
    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
 
    All rights reserved.
@@ -55,15 +55,23 @@ typedef enum {
      CSNF_PALETTE_UPDATE = 0x00000080,  /* current palette has been altered */
      CSNF_ALPHA_RAMP     = 0x00000100,  /* alpha ramp was modified */
      CSNF_DISPLAY        = 0x00000200,  /* surface buffer displayed */
-
-     CSNF_ALL            = 0x000003FF
+     CSNF_BUFFER_ALLOCATION_DESTROY
+                         = 0x00000400,  /* Buffer allocation about to be destroyed */
+     CSNF_ALL            = 0x000007FF
 } CoreSurfaceNotificationFlags;
 
 typedef struct {
      CoreSurfaceNotificationFlags  flags;
      CoreSurface                  *surface;
 
+     /* The following field is used only by the CSNF_DISPLAY message. */
      int                           index;
+
+     /* The following fields are used only by the CSNF_BUFFER_ALLOCATION_DESTROY message. */
+     CoreSurfaceBuffer *buffer_no_access;  /* Pointer to associated CoreSurfaceBuffer being
+                                              destroyed. Do not dereference. */
+     void              *surface_data;      /* CoreSurface's shared driver specific data. */
+     int                surface_object_id; /* CoreSurface's Fusion ID. */
 } CoreSurfaceNotification;
 
 
@@ -264,6 +272,18 @@ DFBResult dfb_surface_notify        ( CoreSurface                  *surface,
 DFBResult dfb_surface_notify_display( CoreSurface                  *surface,
                                       CoreSurfaceBuffer            *buffer);
 
+/*
+     Prepares and sends a notification message that a change is about to happen to the specified
+     surface buffer pool allocation.  The notification message will be received by all pocesses
+     that have listeners attached to the associated CoreSurface's reactor.
+
+     At present, only THE CSNF_BUFFER_ALLOCATION_DESTROY message is handled.
+*/
+DFBResult dfb_surface_pool_notify   ( CoreSurface                  *surface,
+                                      CoreSurfaceBuffer            *buffer,
+                                      CoreSurfaceAllocation        *allocation,
+                                      CoreSurfaceNotificationFlags  flags );
+
 DFBResult dfb_surface_flip          ( CoreSurface                  *surface,
                                       bool                          swap );
 
diff --git a/src/core/surface_pool.c b/src/core/surface_pool.c
index a85d88d..388613b 100644
--- a/src/core/surface_pool.c
+++ b/src/core/surface_pool.c
@@ -685,6 +685,13 @@ dfb_surface_pool_deallocate( CoreSurfacePool       *pool,
 
      D_ASSERT( funcs->DeallocateBuffer != NULL );
 
+     /* Indicate that this surface buffer pool allocation is about to be destroyed. */
+     dfb_surface_pool_notify(
+          surface,
+          buffer,
+          allocation,
+          CSNF_BUFFER_ALLOCATION_DESTROY );
+
      if (fusion_skirmish_prevail( &pool->lock ))
           return DFB_FUSION;
 
-- 
1.6.0.6

