diff src/video/photon/SDL_photon_render.c @ 3375:dd105b317335

Continue working on 2D support for Photon/QNX.
author Mike Gorchak <lestat@i.com.ua>
date Sat, 10 Oct 2009 20:15:20 +0000
parents 7f684f249ec9
children 90935231e9b6
line wrap: on
line diff
--- a/src/video/photon/SDL_photon_render.c	Sat Oct 10 18:37:35 2009 +0000
+++ b/src/video/photon/SDL_photon_render.c	Sat Oct 10 20:15:20 2009 +0000
@@ -68,6 +68,8 @@
 static void photon_dirtytexture(SDL_Renderer * renderer,
                                 SDL_Texture * texture, int numrects,
                                 const SDL_Rect * rects);
+static int photon_setdrawcolor(SDL_Renderer * renderer);
+static int photon_setdrawblendmode(SDL_Renderer * renderer);
 static int photon_renderpoint(SDL_Renderer * renderer, int x, int y);
 static int photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2,
                              int y2);
@@ -80,6 +82,8 @@
                                   SDL_Texture * texture);
 static void photon_destroyrenderer(SDL_Renderer * renderer);
 
+static int _photon_recreate_surfaces(SDL_Renderer * renderer);
+
 SDL_RenderDriver photon_renderdriver = {
     photon_createrenderer,
     {
@@ -92,18 +96,15 @@
       SDL_TEXTUREMODULATE_ALPHA),
      (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK |
       SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
-     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_SLOW),
-     13,
-     {
-      SDL_PIXELFORMAT_INDEX8,
+     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_SLOW |
+      SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_BEST),
+     10,
+     {SDL_PIXELFORMAT_INDEX8,
       SDL_PIXELFORMAT_RGB555,
       SDL_PIXELFORMAT_RGB565,
+      SDL_PIXELFORMAT_RGB24,
       SDL_PIXELFORMAT_RGB888,
-      SDL_PIXELFORMAT_BGR888,
       SDL_PIXELFORMAT_ARGB8888,
-      SDL_PIXELFORMAT_RGBA8888,
-      SDL_PIXELFORMAT_ABGR8888,
-      SDL_PIXELFORMAT_BGRA8888,
       SDL_PIXELFORMAT_YV12,
       SDL_PIXELFORMAT_YUY2,
       SDL_PIXELFORMAT_UYVY,
@@ -150,6 +151,8 @@
     renderer->LockTexture = photon_locktexture;
     renderer->UnlockTexture = photon_unlocktexture;
     renderer->DirtyTexture = photon_dirtytexture;
+    renderer->SetDrawColor = photon_setdrawcolor;
+    renderer->SetDrawBlendMode = photon_setdrawblendmode;
     renderer->RenderPoint = photon_renderpoint;
     renderer->RenderLine = photon_renderline;
     renderer->RenderFill = photon_renderfill;
@@ -168,8 +171,6 @@
         renderer->info.flags &= ~(SDL_RENDERER_ACCELERATED);
     }
 
-    rdata->window = window;
-
     /* Check if upper level requested synchronization on vsync signal */
     if ((flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) {
         rdata->enable_vsync = SDL_TRUE;
@@ -214,6 +215,13 @@
         }
     }
 
+    /* Create new graphics context */
+    if (rdata->gc==NULL)
+    {
+       rdata->gc=PgCreateGC(0);
+       PgDefaultGC(rdata->gc);
+    }
+
     return renderer;
 }
 
@@ -228,28 +236,347 @@
 }
 
 /****************************************************************************/
-/* SDL render interface                                                     */
+/* Render helper functions                                                  */
 /****************************************************************************/
-static int
-photon_displaymodechanged(SDL_Renderer * renderer)
+
+static int _photon_recreate_surfaces(SDL_Renderer * renderer)
 {
     SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+    SDL_VideoDisplay *display = NULL;
+    SDL_DisplayData *didata = NULL;
+    SDL_Window *window = NULL;
+    SDL_WindowData *wdata = NULL;
+    SDL_VideoData *phdata = NULL;
+    uint32_t allocate_task=SDL_PHOTON_SURFTYPE_UNKNOWN;
+    int32_t status;
 
-    /* Remove all allocated surfaces, they are no more valid */
+    /* Obtain window and display structures */
+    window=SDL_GetWindowFromID(renderer->window);
+    wdata=(SDL_WindowData*)window->driverdata;
+    display=SDL_GetDisplayFromWindow(window);
+    didata=(SDL_DisplayData *) display->driverdata;
+    phdata=(SDL_VideoData *) display->device->driverdata;
+
+    /* Check if it is OpenGL ES window */
+    if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
+        /* If so, do not waste surfaces */
+        rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
+        return 0;
+    }
+
+    if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
+    {
+       /* Try to allocate offscreen surfaces */
+       allocate_task=SDL_PHOTON_SURFTYPE_OFFSCREEN;
+    }
+    else
+    {
+       uint32_t it;
+
+       if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_OFFSCREEN)
+       {
+          /* Create offscreen surfaces */
+          allocate_task=SDL_PHOTON_SURFTYPE_OFFSCREEN;
+
+          /* Destroy current surfaces */
+          for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
+          {
+             if (rdata->osurfaces[it] != NULL)
+             {
+                PhDCRelease(rdata->osurfaces[it]);
+                rdata->osurfaces[it] = NULL;
+             }
+          }
+       }
+       else
+       {
+          if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_PHIMAGE)
+          {
+             /* Create shared phimage surfaces */
+             allocate_task=SDL_PHOTON_SURFTYPE_PHIMAGE;
+
+             /* Destroy current surfaces */
+             for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
+             {
+                if (rdata->pcontexts[it]!=NULL)
+                {
+                   PmMemReleaseMC(rdata->pcontexts[it]);
+                   rdata->pcontexts[it]=NULL;
+                }
+                if (rdata->psurfaces[it]!=NULL)
+                {
+                   if (rdata->psurfaces[it]->palette!=NULL)
+                   {
+                      SDL_free(rdata->psurfaces[it]->palette);
+                      rdata->psurfaces[it]->palette=NULL;
+                   }
+                   /* Destroy shared memory for PhImage_t */
+                   PgShmemDestroy(rdata->psurfaces[it]->image);
+                   rdata->psurfaces[it]->image=NULL;
+                   SDL_free(rdata->psurfaces[it]);
+                   rdata->psurfaces[it]=NULL;
+                }
+             }
+          }
+       }
+    }
+
+    /* Check if current device is not the same as target */
+    if (phdata->current_device_id != didata->device_id) {
+        /* Set target device as default for Pd and Pg functions */
+        status = PdSetTargetDevice(NULL, phdata->rid[didata->device_id]);
+        if (status != 0) {
+            SDL_SetError("Photon: Can't set default target device\n");
+            return -1;
+        }
+        phdata->current_device_id = didata->device_id;
+    }
+
+    switch (allocate_task)
+    {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            {
+               int32_t it;
+               int32_t jt;
+
+               /* Try the hardware accelerated offscreen surfaces first */
+               for (it=0; it<rdata->surfaces_count; it++)
+               {
+                  rdata->osurfaces[it]=PdCreateOffscreenContext(0, window->w, window->h,
+                  Pg_OSC_MEM_LINEAR_ACCESSIBLE |
+                  /* in case if 2D acceleration is not available use CPU optimized surfaces */
+                  Pg_OSC_MEM_HINT_CPU_READ | Pg_OSC_MEM_HINT_CPU_WRITE |
+                  /* in case if 2D acceleration is available use it */
+                  Pg_OSC_MEM_2D_WRITABLE | Pg_OSC_MEM_2D_READABLE);
+
+                  /* If we can't create an offscreen surface, then fallback to software */
+                  if (rdata->osurfaces[it]==NULL)
+                  {
+                     /* Destroy previously allocated surface(s) */
+                     for (jt = it - 1; jt > 0; jt--)
+                     {
+                        PhDCRelease(rdata->osurfaces[jt]);
+                        rdata->osurfaces[jt] = NULL;
+                     }
+                     break;
+                  }
+               }
 
-    /* TODO: Add video mode change detection and new parameters detection */
+               /* Check if all required surfaces have been created */
+               if (rdata->osurfaces[0]!=NULL)
+               {
+                  rdata->surfaces_type=SDL_PHOTON_SURFTYPE_OFFSCREEN;
+                  /* exit from switch if surfaces have been created */
+                  break;
+               }
+               else
+               {
+                  /* else fall through to software phimage surface allocation */
+               }
+            }
+            /* fall through */
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            {
+               int32_t it;
+               int32_t jt;
+               uint32_t image_pfmt=photon_sdl_to_image_pixelformat(didata->current_mode.format);
+
+               /* Try to allocate the software surfaces in shared memory */
+               for (it=0; it<rdata->surfaces_count; it++)
+               {
+                  /* If this surface with palette, create a palette space */
+                  if (image_pfmt==Pg_IMAGE_PALETTE_BYTE)
+                  {
+                     rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
+                        image_pfmt, NULL, 256, 1);
+                  }
+                  else
+                  {
+                     rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
+                        image_pfmt, NULL, 0, 1);
+                  }
+
+                  if (rdata->psurfaces[it]!=NULL)
+                  {
+                     PhPoint_t translation={0, 0};
+                     PhDim_t   dimension={window->w, window->h};
+
+                     /* Create memory context for PhImage_t */
+                     rdata->pcontexts[it]=PmMemCreateMC(rdata->psurfaces[it], &dimension, &translation);
+                  }
+
+                  if ((rdata->psurfaces[it]==NULL) || (rdata->pcontexts[it]==NULL))
+                  {
+                     /* Destroy previously allocated surface(s) */
+                     for (jt = it - 1; jt > 0; jt--)
+                     {
+                        if (rdata->pcontexts[jt]!=NULL)
+                        {
+                           PmMemReleaseMC(rdata->pcontexts[it]);
+                           rdata->pcontexts[jt]=NULL;
+                        }
+                        if (rdata->psurfaces[jt]!=NULL)
+                        {
+                           if (rdata->psurfaces[jt]->palette!=NULL)
+                           {
+                              SDL_free(rdata->psurfaces[jt]->palette);
+                              rdata->psurfaces[jt]->palette=NULL;
+                           }
+                           /* Destroy shared memory for PhImage_t */
+                           PgShmemDestroy(rdata->psurfaces[jt]->image);
+                           rdata->psurfaces[jt]->image=NULL;
+                           SDL_free(rdata->psurfaces[jt]);
+                           rdata->psurfaces[jt] = NULL;
+                        }
+                     }
+                     break;
+                  }
+               }
+
+               /* Check if all required surfaces have been created */
+               if (rdata->psurfaces[0]!=NULL)
+               {
+                  rdata->surfaces_type=SDL_PHOTON_SURFTYPE_PHIMAGE;
+               }
+               else
+               {
+                  rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
+               }
+            }
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            {
+               /* do nothing with surface allocation */
+               rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
+            }
+            break;
+    }
+
+    /* Check if one of two allocation scheme was successful */
+    if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
+    {
+       SDL_SetError("Photon: primary surface(s) allocation failure");
+       return -1;
+    }
+
+    /* Store current surface dimensions */
+    rdata->window_width=window->w;
+    rdata->window_height=window->h;
+
+    /* If current copy/flip scheme is single buffer, then set initial parameters */
+    if ((renderer->info.flags & SDL_RENDERER_SINGLEBUFFER)==SDL_RENDERER_SINGLEBUFFER)
+    {
+       rdata->surface_visible_idx = 0;
+       rdata->surface_render_idx = 0;
+    }
+
+    /* If current copy/flip scheme is double buffer, then set initial parameters */
+    if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP2)==SDL_RENDERER_PRESENTFLIP2)
+    {
+       rdata->surface_visible_idx = 0;
+       rdata->surface_render_idx = 1;
+    }
+
+    /* If current copy/flip scheme is triple buffer, then set initial parameters */
+    if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP3)==SDL_RENDERER_PRESENTFLIP3)
+    {
+       rdata->surface_visible_idx = 0;
+       rdata->surface_render_idx = 1;
+    }
+
+    switch (rdata->surfaces_type)
+    {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            PgSetGCCx(rdata->osurfaces[rdata->surface_render_idx], rdata->gc);
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PgSetGCCx(rdata->pcontexts[rdata->surface_render_idx], rdata->gc);
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            break;
+    }
 
     return 0;
 }
 
+int _photon_update_rectangles(SDL_Renderer* renderer, PhRect_t* rect)
+{
+   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+   SDL_Window *window = window=SDL_GetWindowFromID(renderer->window);
+   SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
+   PhPoint_t src_point;
+
+   /* If currently single buffer is in use, we have to flush all data */
+   if (rdata->surface_render_idx==rdata->surface_visible_idx)
+   {
+      /* Flush all undrawn graphics data to surface */
+      switch (rdata->surfaces_type)
+      {
+          case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+               PgFlushCx(rdata->osurfaces[rdata->surface_visible_idx]);
+               PgWaitHWIdle();
+               break;
+          case SDL_PHOTON_SURFTYPE_PHIMAGE:
+               PmMemFlush(rdata->pcontexts[rdata->surface_visible_idx], rdata->psurfaces[rdata->surface_visible_idx]);
+               break;
+          case SDL_PHOTON_SURFTYPE_UNKNOWN:
+               return;
+      }
+   }
+
+   PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
+
+   src_point.x = rect->ul.x;
+   src_point.y = rect->ul.y;
+
+   switch (rdata->surfaces_type)
+   {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            PgContextBlit(rdata->osurfaces[rdata->surface_visible_idx], rect, NULL, rect);
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PgDrawPhImageRectv(&src_point, rdata->psurfaces[rdata->surface_visible_idx], rect, 0);
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            break;
+   }
+}
+
+/****************************************************************************/
+/* SDL render interface                                                     */
+/****************************************************************************/
+
 static int
 photon_activaterenderer(SDL_Renderer * renderer)
 {
-    SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
-    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(rdata->window);
-    SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
+   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+   SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+   SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
+
+   if ((rdata->window_width!=window->w) || (rdata->window_height!=window->h))
+   {
+      return _photon_recreate_surfaces(renderer);
+   }
 
-    return 0;
+   switch (rdata->surfaces_type)
+   {
+      case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+           PgSetGCCx(rdata->osurfaces[rdata->surface_render_idx], rdata->gc);
+           break;
+      case SDL_PHOTON_SURFTYPE_PHIMAGE:
+           PgSetGCCx(rdata->pcontexts[rdata->surface_render_idx], rdata->gc);
+           break;
+      case SDL_PHOTON_SURFTYPE_UNKNOWN:
+           break;
+   }
+
+   return 0;
+}
+
+static int
+photon_displaymodechanged(SDL_Renderer * renderer)
+{
+    return _photon_recreate_surfaces(renderer);
 }
 
 static int
@@ -269,7 +596,6 @@
 
     /* Set texture driver data */
     texture->driverdata = tdata;
-
 }
 
 static int
@@ -336,18 +662,79 @@
 }
 
 static int
+photon_setdrawcolor(SDL_Renderer * renderer)
+{
+   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+
+   switch (rdata->surfaces_type)
+   {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PgSetFillColorCx(rdata->gc, PgRGB(renderer->r, renderer->g, renderer->b));
+            PgSetStrokeColorCx(rdata->gc, PgRGB(renderer->r, renderer->g, renderer->b));
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            break;
+   }
+}
+
+static int
+photon_setdrawblendmode(SDL_Renderer * renderer)
+{
+}
+
+static int
 photon_renderpoint(SDL_Renderer * renderer, int x, int y)
 {
+   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+
+   switch (rdata->surfaces_type)
+   {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            PgDrawIPixelCx(rdata->osurfaces[rdata->surface_render_idx], x, y);
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PgDrawIPixelCx(rdata->pcontexts[rdata->surface_render_idx], x, y);
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            break;
+   }
 }
 
 static int
 photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
 {
+   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+
+   switch (rdata->surfaces_type)
+   {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            PgDrawILineCx(rdata->osurfaces[rdata->surface_render_idx], x1, y1, x2, y2);
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PgDrawILineCx(rdata->pcontexts[rdata->surface_render_idx], x1, y1, x2, y2);
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            break;
+   }
 }
 
 static int
 photon_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect)
 {
+   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+
+   switch (rdata->surfaces_type)
+   {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            PgDrawIRectCx(rdata->osurfaces[rdata->surface_render_idx], rect->x, rect->y, rect->w+rect->x-1, rect->h+rect->y-1, Pg_DRAW_FILL);
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PgDrawIRectCx(rdata->pcontexts[rdata->surface_render_idx], rect->x, rect->y, rect->w+rect->x-1, rect->h+rect->y-1, Pg_DRAW_FILL);
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            break;
+   }
 }
 
 static int
@@ -359,6 +746,53 @@
 static void
 photon_renderpresent(SDL_Renderer * renderer)
 {
+   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+   SDL_Window *window = window=SDL_GetWindowFromID(renderer->window);
+   SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
+   PhRect_t src_rect;
+   PhPoint_t src_point;
+
+   /* Flush all undrawn graphics data to surface */
+   switch (rdata->surfaces_type)
+   {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            PgFlushCx(rdata->osurfaces[rdata->surface_render_idx]);
+            PgWaitHWIdle();
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PmMemFlush(rdata->pcontexts[rdata->surface_render_idx], rdata->psurfaces[rdata->surface_render_idx]);
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            return;
+   }
+
+   PgFFlush(Ph_START_DRAW);
+   PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
+
+   /* Set blit area */
+   src_rect.ul.x = 0;
+   src_rect.ul.y = 0;
+   src_rect.lr.x = rdata->window_width - 1;
+   src_rect.lr.y = rdata->window_height - 1;
+
+   src_point.x = 0;
+   src_point.y = 0;
+
+   switch (rdata->surfaces_type)
+   {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            PgContextBlit(rdata->osurfaces[rdata->surface_render_idx], &src_rect, NULL, &src_rect);
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            PgDrawPhImagev(&src_point, rdata->psurfaces[rdata->surface_render_idx], 0);
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            break;
+   }
+
+   /* finish blit */
+   PgFFlush(Ph_DONE_DRAW);
+   PgWaitHWIdle();
 }
 
 static void
@@ -370,8 +804,64 @@
 photon_destroyrenderer(SDL_Renderer * renderer)
 {
     SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
     uint32_t it;
 
+    /* Destroy graphics context */
+    if (rdata->gc!=NULL)
+    {
+       PgDestroyGC(rdata->gc);
+       rdata->gc=NULL;
+    }
+
+    switch (rdata->surfaces_type)
+    {
+       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
+            {
+               /* Destroy current surfaces */
+               for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
+               {
+                  if (rdata->osurfaces[it] != NULL)
+                  {
+                     PhDCRelease(rdata->osurfaces[it]);
+                     rdata->osurfaces[it] = NULL;
+                  }
+               }
+            }
+            break;
+       case SDL_PHOTON_SURFTYPE_PHIMAGE:
+            {
+               /* Destroy current surfaces */
+               for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
+               {
+                  if (rdata->pcontexts[it]!=NULL)
+                  {
+                     PmMemReleaseMC(rdata->pcontexts[it]);
+                     rdata->pcontexts[it]=NULL;
+                  }
+                  if (rdata->psurfaces[it]!=NULL)
+                  {
+                     if (rdata->psurfaces[it]->palette!=NULL)
+                     {
+                        SDL_free(rdata->psurfaces[it]->palette);
+                        rdata->psurfaces[it]->palette=NULL;
+                     }
+                     /* Destroy shared memory for PhImage_t */
+                     PgShmemDestroy(rdata->psurfaces[it]->image);
+                     rdata->psurfaces[it]->image=NULL;
+                     SDL_free(rdata->psurfaces[it]);
+                     rdata->psurfaces[it]=NULL;
+                  }
+               }
+            }
+            break;
+       case SDL_PHOTON_SURFTYPE_UNKNOWN:
+            {
+               /* nothing to do */
+            }
+            break;
+    }
 }
 
 /* vi: set ts=4 sw=4 expandtab: */