Continue working on 2D support for Photon/QNX.
authorMike Gorchak <lestat@i.com.ua>
Sat, 10 Oct 2009 20:15:20 +0000
changeset 3375dd105b317335
parent 3374 725b16784e96
child 3376 106a409ceeef
Continue working on 2D support for Photon/QNX.
src/video/photon/SDL_photon.c
src/video/photon/SDL_photon_render.c
src/video/photon/SDL_photon_render.h
     1.1 --- a/src/video/photon/SDL_photon.c	Sat Oct 10 18:37:35 2009 +0000
     1.2 +++ b/src/video/photon/SDL_photon.c	Sat Oct 10 20:15:20 2009 +0000
     1.3 @@ -44,7 +44,7 @@
     1.4  #if defined(SDL_VIDEO_OPENGL_ES)
     1.5  #include "../qnxgf/SDL_gf_pixelfmt.h"
     1.6  
     1.7 -   /* If GF driver is not compiled in, include some of usefull functions */
     1.8 +/* If GF driver is not compiled in, include some of usefull functions */
     1.9  #if !defined(SDL_VIDEO_DRIVER_QNXGF)
    1.10  #include "../qnxgf/SDL_gf_pixelfmt.c"
    1.11  #endif /* SDL_VIDEO_DRIVER_QNXGF */
    1.12 @@ -54,7 +54,7 @@
    1.13  #if defined(SDL_VIDEO_OPENGL_ES)
    1.14  #include "../qnxgf/SDL_gf_opengles.h"
    1.15  
    1.16 -   /* If GF driver is not compiled in, include some of usefull functions */
    1.17 +/* If GF driver is not compiled in, include some of usefull functions */
    1.18  #if !defined(SDL_VIDEO_DRIVER_QNXGF)
    1.19  #include "../qnxgf/SDL_gf_opengles.c"
    1.20  #endif /* SDL_VIDEO_DRIVER_QNXGF */
    1.21 @@ -137,7 +137,7 @@
    1.22      /* VIA UniChrome graphics driver (devg-unichrome.so)    */
    1.23      {"unichrome", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D}
    1.24      ,
    1.25 -    /* VESA unaccelerated gfx driver (devg-vesa.so)         */
    1.26 +    /* VESA unaccelerated gfx driver (devg-vesabios.so)     */
    1.27      {"vesa", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D}
    1.28      ,
    1.29      /* VmWare graphics driver (devg-volari.so)              */
    1.30 @@ -155,7 +155,7 @@
    1.31  static int
    1.32  photon_available(void)
    1.33  {
    1.34 -    int status;
    1.35 +    int32_t status;
    1.36  
    1.37      /* Check if Photon was initialized before */
    1.38      if (photon_initialized == SDL_FALSE) {
    1.39 @@ -194,7 +194,7 @@
    1.40  {
    1.41      SDL_VideoDevice *device;
    1.42      SDL_VideoData *phdata;
    1.43 -    int status;
    1.44 +    int32_t status;
    1.45  
    1.46      /* Check if photon could be initialized */
    1.47      status = photon_available();
    1.48 @@ -883,6 +883,13 @@
    1.49      PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE,
    1.50               Ph_WM_STATE_ISALTKEY);
    1.51  
    1.52 +    /* Special case, do not handle maximize events, if window can't be resized */
    1.53 +    if ((window->flags & SDL_WINDOW_RESIZABLE) != SDL_WINDOW_RESIZABLE)
    1.54 +    {
    1.55 +       PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE,
    1.56 +                Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_RESIZE);
    1.57 +    }
    1.58 +
    1.59      /* Set window dimension */
    1.60      winsize.w = window->w;
    1.61      winsize.h = window->h;
    1.62 @@ -1305,7 +1312,7 @@
    1.63      if (phdata->gfinitialized != SDL_TRUE) {
    1.64          SDL_SetError
    1.65              ("Photon: GF initialization failed, no OpenGL ES support");
    1.66 -        return NULL;
    1.67 +        return -1;
    1.68      }
    1.69  
    1.70      /* Check if OpenGL ES library is specified for GF driver */
    1.71 @@ -1918,6 +1925,7 @@
    1.72          (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
    1.73      PhRect_t dst_rect;
    1.74      PhRect_t src_rect;
    1.75 +    int32_t status;
    1.76  
    1.77      if (phdata->gfinitialized != SDL_TRUE) {
    1.78          SDL_SetError
    1.79 @@ -1951,6 +1959,17 @@
    1.80      src_rect.lr.x = window->w - 1;
    1.81      src_rect.lr.y = window->h - 1;
    1.82  
    1.83 +    /* Check if current device is not the same as target */
    1.84 +    if (phdata->current_device_id != didata->device_id) {
    1.85 +        /* Set target device as default for Pd and Pg functions */
    1.86 +        status = PdSetTargetDevice(NULL, phdata->rid[didata->device_id]);
    1.87 +        if (status != 0) {
    1.88 +            SDL_SetError("Photon: Can't set default target device\n");
    1.89 +            return;
    1.90 +        }
    1.91 +        phdata->current_device_id = didata->device_id;
    1.92 +    }
    1.93 +
    1.94      /* Blit OpenGL ES pixmap surface directly to window region */
    1.95      PgFFlush(Ph_START_DRAW);
    1.96      PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
    1.97 @@ -2324,12 +2343,8 @@
    1.98                                  if ((wdata != NULL) && (window != NULL)) {
    1.99                                      /* Check if window uses OpenGL ES */
   1.100                                      if (wdata->uses_gles == SDL_TRUE) {
   1.101 -                                        PhRect_t dst_rect;
   1.102 -                                        PhRect_t src_rect;
   1.103 -
   1.104                                          /* Cycle through each rectangle */
   1.105 -                                        for (it = 0; it < event->num_rects;
   1.106 -                                             it++) {
   1.107 +                                        for (it = 0; it < event->num_rects; it++) {
   1.108                                              /* Blit OpenGL ES pixmap surface directly to window region */
   1.109                                              PgFFlush(Ph_START_DRAW);
   1.110                                              PgSetRegionCx(PhDCGetCurrent(),
   1.111 @@ -2345,8 +2360,14 @@
   1.112                                              PgWaitHWIdle();
   1.113                                          }
   1.114                                      } else {
   1.115 -                                        /* Normal window */
   1.116 -                                        /* TODO: update the damaged rectangles */
   1.117 +                                        /* Cycle through each rectangle */
   1.118 +                                        for (it = 0; it < event->num_rects;
   1.119 +                                             it++) {
   1.120 +                                            /* Blit 2D pixmap surface directly to window region */
   1.121 +                                            _photon_update_rectangles(window->renderer, &rects[it]);
   1.122 +                                        }
   1.123 +                                        PgFlush();
   1.124 +                                        PgWaitHWIdle();
   1.125                                      }
   1.126                                  }
   1.127  
   1.128 @@ -2385,10 +2406,19 @@
   1.129                                          PgFFlush(Ph_DONE_DRAW);
   1.130                                          PgWaitHWIdle();
   1.131                                      } else {
   1.132 -                                        /* Normal window */
   1.133 -                                        /* TODO: update the damaged rectangles */
   1.134 +                                        PhRect_t rect;
   1.135  
   1.136                                          /* We need to redraw entire window */
   1.137 +                                        rect.ul.x = 0;
   1.138 +                                        rect.ul.y = 0;
   1.139 +                                        rect.lr.x = window->w - 1;
   1.140 +                                        rect.lr.y = window->h - 1;
   1.141 +
   1.142 +                                        /* Blit 2D pixmap surface directly to window region */
   1.143 +                                        PgFFlush(Ph_START_DRAW);
   1.144 +                                        _photon_update_rectangles(window->renderer, &rect);
   1.145 +                                        PgFFlush(Ph_DONE_DRAW);
   1.146 +                                        PgWaitHWIdle();
   1.147                                      }
   1.148                                  }
   1.149                              }
   1.150 @@ -2693,9 +2723,16 @@
   1.151                          case Ph_WM_MAX:
   1.152                              {
   1.153                                  if (window != NULL) {
   1.154 -                                    SDL_SendWindowEvent(window->id,
   1.155 -                                                        SDL_WINDOWEVENT_MAXIMIZED,
   1.156 -                                                        0, 0);
   1.157 +                                    if ((window->flags & SDL_WINDOW_RESIZABLE)==SDL_WINDOW_RESIZABLE)
   1.158 +                                    {
   1.159 +                                       SDL_SendWindowEvent(window->id,
   1.160 +                                                           SDL_WINDOWEVENT_MAXIMIZED,
   1.161 +                                                           0, 0);
   1.162 +                                    }
   1.163 +                                    else
   1.164 +                                    {
   1.165 +                                       /* otherwise ignor the resize events */
   1.166 +                                    }
   1.167                                  }
   1.168                              }
   1.169                              break;
     2.1 --- a/src/video/photon/SDL_photon_render.c	Sat Oct 10 18:37:35 2009 +0000
     2.2 +++ b/src/video/photon/SDL_photon_render.c	Sat Oct 10 20:15:20 2009 +0000
     2.3 @@ -68,6 +68,8 @@
     2.4  static void photon_dirtytexture(SDL_Renderer * renderer,
     2.5                                  SDL_Texture * texture, int numrects,
     2.6                                  const SDL_Rect * rects);
     2.7 +static int photon_setdrawcolor(SDL_Renderer * renderer);
     2.8 +static int photon_setdrawblendmode(SDL_Renderer * renderer);
     2.9  static int photon_renderpoint(SDL_Renderer * renderer, int x, int y);
    2.10  static int photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2,
    2.11                               int y2);
    2.12 @@ -80,6 +82,8 @@
    2.13                                    SDL_Texture * texture);
    2.14  static void photon_destroyrenderer(SDL_Renderer * renderer);
    2.15  
    2.16 +static int _photon_recreate_surfaces(SDL_Renderer * renderer);
    2.17 +
    2.18  SDL_RenderDriver photon_renderdriver = {
    2.19      photon_createrenderer,
    2.20      {
    2.21 @@ -92,18 +96,15 @@
    2.22        SDL_TEXTUREMODULATE_ALPHA),
    2.23       (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK |
    2.24        SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
    2.25 -     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_SLOW),
    2.26 -     13,
    2.27 -     {
    2.28 -      SDL_PIXELFORMAT_INDEX8,
    2.29 +     (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_SLOW |
    2.30 +      SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_BEST),
    2.31 +     10,
    2.32 +     {SDL_PIXELFORMAT_INDEX8,
    2.33        SDL_PIXELFORMAT_RGB555,
    2.34        SDL_PIXELFORMAT_RGB565,
    2.35 +      SDL_PIXELFORMAT_RGB24,
    2.36        SDL_PIXELFORMAT_RGB888,
    2.37 -      SDL_PIXELFORMAT_BGR888,
    2.38        SDL_PIXELFORMAT_ARGB8888,
    2.39 -      SDL_PIXELFORMAT_RGBA8888,
    2.40 -      SDL_PIXELFORMAT_ABGR8888,
    2.41 -      SDL_PIXELFORMAT_BGRA8888,
    2.42        SDL_PIXELFORMAT_YV12,
    2.43        SDL_PIXELFORMAT_YUY2,
    2.44        SDL_PIXELFORMAT_UYVY,
    2.45 @@ -150,6 +151,8 @@
    2.46      renderer->LockTexture = photon_locktexture;
    2.47      renderer->UnlockTexture = photon_unlocktexture;
    2.48      renderer->DirtyTexture = photon_dirtytexture;
    2.49 +    renderer->SetDrawColor = photon_setdrawcolor;
    2.50 +    renderer->SetDrawBlendMode = photon_setdrawblendmode;
    2.51      renderer->RenderPoint = photon_renderpoint;
    2.52      renderer->RenderLine = photon_renderline;
    2.53      renderer->RenderFill = photon_renderfill;
    2.54 @@ -168,8 +171,6 @@
    2.55          renderer->info.flags &= ~(SDL_RENDERER_ACCELERATED);
    2.56      }
    2.57  
    2.58 -    rdata->window = window;
    2.59 -
    2.60      /* Check if upper level requested synchronization on vsync signal */
    2.61      if ((flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) {
    2.62          rdata->enable_vsync = SDL_TRUE;
    2.63 @@ -214,6 +215,13 @@
    2.64          }
    2.65      }
    2.66  
    2.67 +    /* Create new graphics context */
    2.68 +    if (rdata->gc==NULL)
    2.69 +    {
    2.70 +       rdata->gc=PgCreateGC(0);
    2.71 +       PgDefaultGC(rdata->gc);
    2.72 +    }
    2.73 +
    2.74      return renderer;
    2.75  }
    2.76  
    2.77 @@ -228,28 +236,347 @@
    2.78  }
    2.79  
    2.80  /****************************************************************************/
    2.81 -/* SDL render interface                                                     */
    2.82 +/* Render helper functions                                                  */
    2.83  /****************************************************************************/
    2.84 -static int
    2.85 -photon_displaymodechanged(SDL_Renderer * renderer)
    2.86 +
    2.87 +static int _photon_recreate_surfaces(SDL_Renderer * renderer)
    2.88  {
    2.89      SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
    2.90 +    SDL_VideoDisplay *display = NULL;
    2.91 +    SDL_DisplayData *didata = NULL;
    2.92 +    SDL_Window *window = NULL;
    2.93 +    SDL_WindowData *wdata = NULL;
    2.94 +    SDL_VideoData *phdata = NULL;
    2.95 +    uint32_t allocate_task=SDL_PHOTON_SURFTYPE_UNKNOWN;
    2.96 +    int32_t status;
    2.97  
    2.98 -    /* Remove all allocated surfaces, they are no more valid */
    2.99 +    /* Obtain window and display structures */
   2.100 +    window=SDL_GetWindowFromID(renderer->window);
   2.101 +    wdata=(SDL_WindowData*)window->driverdata;
   2.102 +    display=SDL_GetDisplayFromWindow(window);
   2.103 +    didata=(SDL_DisplayData *) display->driverdata;
   2.104 +    phdata=(SDL_VideoData *) display->device->driverdata;
   2.105  
   2.106 -    /* TODO: Add video mode change detection and new parameters detection */
   2.107 +    /* Check if it is OpenGL ES window */
   2.108 +    if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
   2.109 +        /* If so, do not waste surfaces */
   2.110 +        rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
   2.111 +        return 0;
   2.112 +    }
   2.113 +
   2.114 +    if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
   2.115 +    {
   2.116 +       /* Try to allocate offscreen surfaces */
   2.117 +       allocate_task=SDL_PHOTON_SURFTYPE_OFFSCREEN;
   2.118 +    }
   2.119 +    else
   2.120 +    {
   2.121 +       uint32_t it;
   2.122 +
   2.123 +       if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_OFFSCREEN)
   2.124 +       {
   2.125 +          /* Create offscreen surfaces */
   2.126 +          allocate_task=SDL_PHOTON_SURFTYPE_OFFSCREEN;
   2.127 +
   2.128 +          /* Destroy current surfaces */
   2.129 +          for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
   2.130 +          {
   2.131 +             if (rdata->osurfaces[it] != NULL)
   2.132 +             {
   2.133 +                PhDCRelease(rdata->osurfaces[it]);
   2.134 +                rdata->osurfaces[it] = NULL;
   2.135 +             }
   2.136 +          }
   2.137 +       }
   2.138 +       else
   2.139 +       {
   2.140 +          if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_PHIMAGE)
   2.141 +          {
   2.142 +             /* Create shared phimage surfaces */
   2.143 +             allocate_task=SDL_PHOTON_SURFTYPE_PHIMAGE;
   2.144 +
   2.145 +             /* Destroy current surfaces */
   2.146 +             for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
   2.147 +             {
   2.148 +                if (rdata->pcontexts[it]!=NULL)
   2.149 +                {
   2.150 +                   PmMemReleaseMC(rdata->pcontexts[it]);
   2.151 +                   rdata->pcontexts[it]=NULL;
   2.152 +                }
   2.153 +                if (rdata->psurfaces[it]!=NULL)
   2.154 +                {
   2.155 +                   if (rdata->psurfaces[it]->palette!=NULL)
   2.156 +                   {
   2.157 +                      SDL_free(rdata->psurfaces[it]->palette);
   2.158 +                      rdata->psurfaces[it]->palette=NULL;
   2.159 +                   }
   2.160 +                   /* Destroy shared memory for PhImage_t */
   2.161 +                   PgShmemDestroy(rdata->psurfaces[it]->image);
   2.162 +                   rdata->psurfaces[it]->image=NULL;
   2.163 +                   SDL_free(rdata->psurfaces[it]);
   2.164 +                   rdata->psurfaces[it]=NULL;
   2.165 +                }
   2.166 +             }
   2.167 +          }
   2.168 +       }
   2.169 +    }
   2.170 +
   2.171 +    /* Check if current device is not the same as target */
   2.172 +    if (phdata->current_device_id != didata->device_id) {
   2.173 +        /* Set target device as default for Pd and Pg functions */
   2.174 +        status = PdSetTargetDevice(NULL, phdata->rid[didata->device_id]);
   2.175 +        if (status != 0) {
   2.176 +            SDL_SetError("Photon: Can't set default target device\n");
   2.177 +            return -1;
   2.178 +        }
   2.179 +        phdata->current_device_id = didata->device_id;
   2.180 +    }
   2.181 +
   2.182 +    switch (allocate_task)
   2.183 +    {
   2.184 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.185 +            {
   2.186 +               int32_t it;
   2.187 +               int32_t jt;
   2.188 +
   2.189 +               /* Try the hardware accelerated offscreen surfaces first */
   2.190 +               for (it=0; it<rdata->surfaces_count; it++)
   2.191 +               {
   2.192 +                  rdata->osurfaces[it]=PdCreateOffscreenContext(0, window->w, window->h,
   2.193 +                  Pg_OSC_MEM_LINEAR_ACCESSIBLE |
   2.194 +                  /* in case if 2D acceleration is not available use CPU optimized surfaces */
   2.195 +                  Pg_OSC_MEM_HINT_CPU_READ | Pg_OSC_MEM_HINT_CPU_WRITE |
   2.196 +                  /* in case if 2D acceleration is available use it */
   2.197 +                  Pg_OSC_MEM_2D_WRITABLE | Pg_OSC_MEM_2D_READABLE);
   2.198 +
   2.199 +                  /* If we can't create an offscreen surface, then fallback to software */
   2.200 +                  if (rdata->osurfaces[it]==NULL)
   2.201 +                  {
   2.202 +                     /* Destroy previously allocated surface(s) */
   2.203 +                     for (jt = it - 1; jt > 0; jt--)
   2.204 +                     {
   2.205 +                        PhDCRelease(rdata->osurfaces[jt]);
   2.206 +                        rdata->osurfaces[jt] = NULL;
   2.207 +                     }
   2.208 +                     break;
   2.209 +                  }
   2.210 +               }
   2.211 +
   2.212 +               /* Check if all required surfaces have been created */
   2.213 +               if (rdata->osurfaces[0]!=NULL)
   2.214 +               {
   2.215 +                  rdata->surfaces_type=SDL_PHOTON_SURFTYPE_OFFSCREEN;
   2.216 +                  /* exit from switch if surfaces have been created */
   2.217 +                  break;
   2.218 +               }
   2.219 +               else
   2.220 +               {
   2.221 +                  /* else fall through to software phimage surface allocation */
   2.222 +               }
   2.223 +            }
   2.224 +            /* fall through */
   2.225 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.226 +            {
   2.227 +               int32_t it;
   2.228 +               int32_t jt;
   2.229 +               uint32_t image_pfmt=photon_sdl_to_image_pixelformat(didata->current_mode.format);
   2.230 +
   2.231 +               /* Try to allocate the software surfaces in shared memory */
   2.232 +               for (it=0; it<rdata->surfaces_count; it++)
   2.233 +               {
   2.234 +                  /* If this surface with palette, create a palette space */
   2.235 +                  if (image_pfmt==Pg_IMAGE_PALETTE_BYTE)
   2.236 +                  {
   2.237 +                     rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
   2.238 +                        image_pfmt, NULL, 256, 1);
   2.239 +                  }
   2.240 +                  else
   2.241 +                  {
   2.242 +                     rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
   2.243 +                        image_pfmt, NULL, 0, 1);
   2.244 +                  }
   2.245 +
   2.246 +                  if (rdata->psurfaces[it]!=NULL)
   2.247 +                  {
   2.248 +                     PhPoint_t translation={0, 0};
   2.249 +                     PhDim_t   dimension={window->w, window->h};
   2.250 +
   2.251 +                     /* Create memory context for PhImage_t */
   2.252 +                     rdata->pcontexts[it]=PmMemCreateMC(rdata->psurfaces[it], &dimension, &translation);
   2.253 +                  }
   2.254 +
   2.255 +                  if ((rdata->psurfaces[it]==NULL) || (rdata->pcontexts[it]==NULL))
   2.256 +                  {
   2.257 +                     /* Destroy previously allocated surface(s) */
   2.258 +                     for (jt = it - 1; jt > 0; jt--)
   2.259 +                     {
   2.260 +                        if (rdata->pcontexts[jt]!=NULL)
   2.261 +                        {
   2.262 +                           PmMemReleaseMC(rdata->pcontexts[it]);
   2.263 +                           rdata->pcontexts[jt]=NULL;
   2.264 +                        }
   2.265 +                        if (rdata->psurfaces[jt]!=NULL)
   2.266 +                        {
   2.267 +                           if (rdata->psurfaces[jt]->palette!=NULL)
   2.268 +                           {
   2.269 +                              SDL_free(rdata->psurfaces[jt]->palette);
   2.270 +                              rdata->psurfaces[jt]->palette=NULL;
   2.271 +                           }
   2.272 +                           /* Destroy shared memory for PhImage_t */
   2.273 +                           PgShmemDestroy(rdata->psurfaces[jt]->image);
   2.274 +                           rdata->psurfaces[jt]->image=NULL;
   2.275 +                           SDL_free(rdata->psurfaces[jt]);
   2.276 +                           rdata->psurfaces[jt] = NULL;
   2.277 +                        }
   2.278 +                     }
   2.279 +                     break;
   2.280 +                  }
   2.281 +               }
   2.282 +
   2.283 +               /* Check if all required surfaces have been created */
   2.284 +               if (rdata->psurfaces[0]!=NULL)
   2.285 +               {
   2.286 +                  rdata->surfaces_type=SDL_PHOTON_SURFTYPE_PHIMAGE;
   2.287 +               }
   2.288 +               else
   2.289 +               {
   2.290 +                  rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
   2.291 +               }
   2.292 +            }
   2.293 +            break;
   2.294 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.295 +            {
   2.296 +               /* do nothing with surface allocation */
   2.297 +               rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
   2.298 +            }
   2.299 +            break;
   2.300 +    }
   2.301 +
   2.302 +    /* Check if one of two allocation scheme was successful */
   2.303 +    if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
   2.304 +    {
   2.305 +       SDL_SetError("Photon: primary surface(s) allocation failure");
   2.306 +       return -1;
   2.307 +    }
   2.308 +
   2.309 +    /* Store current surface dimensions */
   2.310 +    rdata->window_width=window->w;
   2.311 +    rdata->window_height=window->h;
   2.312 +
   2.313 +    /* If current copy/flip scheme is single buffer, then set initial parameters */
   2.314 +    if ((renderer->info.flags & SDL_RENDERER_SINGLEBUFFER)==SDL_RENDERER_SINGLEBUFFER)
   2.315 +    {
   2.316 +       rdata->surface_visible_idx = 0;
   2.317 +       rdata->surface_render_idx = 0;
   2.318 +    }
   2.319 +
   2.320 +    /* If current copy/flip scheme is double buffer, then set initial parameters */
   2.321 +    if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP2)==SDL_RENDERER_PRESENTFLIP2)
   2.322 +    {
   2.323 +       rdata->surface_visible_idx = 0;
   2.324 +       rdata->surface_render_idx = 1;
   2.325 +    }
   2.326 +
   2.327 +    /* If current copy/flip scheme is triple buffer, then set initial parameters */
   2.328 +    if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP3)==SDL_RENDERER_PRESENTFLIP3)
   2.329 +    {
   2.330 +       rdata->surface_visible_idx = 0;
   2.331 +       rdata->surface_render_idx = 1;
   2.332 +    }
   2.333 +
   2.334 +    switch (rdata->surfaces_type)
   2.335 +    {
   2.336 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.337 +            PgSetGCCx(rdata->osurfaces[rdata->surface_render_idx], rdata->gc);
   2.338 +            break;
   2.339 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.340 +            PgSetGCCx(rdata->pcontexts[rdata->surface_render_idx], rdata->gc);
   2.341 +            break;
   2.342 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.343 +            break;
   2.344 +    }
   2.345  
   2.346      return 0;
   2.347  }
   2.348  
   2.349 +int _photon_update_rectangles(SDL_Renderer* renderer, PhRect_t* rect)
   2.350 +{
   2.351 +   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.352 +   SDL_Window *window = window=SDL_GetWindowFromID(renderer->window);
   2.353 +   SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
   2.354 +   PhPoint_t src_point;
   2.355 +
   2.356 +   /* If currently single buffer is in use, we have to flush all data */
   2.357 +   if (rdata->surface_render_idx==rdata->surface_visible_idx)
   2.358 +   {
   2.359 +      /* Flush all undrawn graphics data to surface */
   2.360 +      switch (rdata->surfaces_type)
   2.361 +      {
   2.362 +          case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.363 +               PgFlushCx(rdata->osurfaces[rdata->surface_visible_idx]);
   2.364 +               PgWaitHWIdle();
   2.365 +               break;
   2.366 +          case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.367 +               PmMemFlush(rdata->pcontexts[rdata->surface_visible_idx], rdata->psurfaces[rdata->surface_visible_idx]);
   2.368 +               break;
   2.369 +          case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.370 +               return;
   2.371 +      }
   2.372 +   }
   2.373 +
   2.374 +   PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
   2.375 +
   2.376 +   src_point.x = rect->ul.x;
   2.377 +   src_point.y = rect->ul.y;
   2.378 +
   2.379 +   switch (rdata->surfaces_type)
   2.380 +   {
   2.381 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.382 +            PgContextBlit(rdata->osurfaces[rdata->surface_visible_idx], rect, NULL, rect);
   2.383 +            break;
   2.384 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.385 +            PgDrawPhImageRectv(&src_point, rdata->psurfaces[rdata->surface_visible_idx], rect, 0);
   2.386 +            break;
   2.387 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.388 +            break;
   2.389 +   }
   2.390 +}
   2.391 +
   2.392 +/****************************************************************************/
   2.393 +/* SDL render interface                                                     */
   2.394 +/****************************************************************************/
   2.395 +
   2.396  static int
   2.397  photon_activaterenderer(SDL_Renderer * renderer)
   2.398  {
   2.399 -    SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.400 -    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(rdata->window);
   2.401 -    SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
   2.402 +   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.403 +   SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   2.404 +   SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
   2.405  
   2.406 -    return 0;
   2.407 +   if ((rdata->window_width!=window->w) || (rdata->window_height!=window->h))
   2.408 +   {
   2.409 +      return _photon_recreate_surfaces(renderer);
   2.410 +   }
   2.411 +
   2.412 +   switch (rdata->surfaces_type)
   2.413 +   {
   2.414 +      case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.415 +           PgSetGCCx(rdata->osurfaces[rdata->surface_render_idx], rdata->gc);
   2.416 +           break;
   2.417 +      case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.418 +           PgSetGCCx(rdata->pcontexts[rdata->surface_render_idx], rdata->gc);
   2.419 +           break;
   2.420 +      case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.421 +           break;
   2.422 +   }
   2.423 +
   2.424 +   return 0;
   2.425 +}
   2.426 +
   2.427 +static int
   2.428 +photon_displaymodechanged(SDL_Renderer * renderer)
   2.429 +{
   2.430 +    return _photon_recreate_surfaces(renderer);
   2.431  }
   2.432  
   2.433  static int
   2.434 @@ -269,7 +596,6 @@
   2.435  
   2.436      /* Set texture driver data */
   2.437      texture->driverdata = tdata;
   2.438 -
   2.439  }
   2.440  
   2.441  static int
   2.442 @@ -336,18 +662,79 @@
   2.443  }
   2.444  
   2.445  static int
   2.446 +photon_setdrawcolor(SDL_Renderer * renderer)
   2.447 +{
   2.448 +   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.449 +
   2.450 +   switch (rdata->surfaces_type)
   2.451 +   {
   2.452 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.453 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.454 +            PgSetFillColorCx(rdata->gc, PgRGB(renderer->r, renderer->g, renderer->b));
   2.455 +            PgSetStrokeColorCx(rdata->gc, PgRGB(renderer->r, renderer->g, renderer->b));
   2.456 +            break;
   2.457 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.458 +            break;
   2.459 +   }
   2.460 +}
   2.461 +
   2.462 +static int
   2.463 +photon_setdrawblendmode(SDL_Renderer * renderer)
   2.464 +{
   2.465 +}
   2.466 +
   2.467 +static int
   2.468  photon_renderpoint(SDL_Renderer * renderer, int x, int y)
   2.469  {
   2.470 +   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.471 +
   2.472 +   switch (rdata->surfaces_type)
   2.473 +   {
   2.474 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.475 +            PgDrawIPixelCx(rdata->osurfaces[rdata->surface_render_idx], x, y);
   2.476 +            break;
   2.477 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.478 +            PgDrawIPixelCx(rdata->pcontexts[rdata->surface_render_idx], x, y);
   2.479 +            break;
   2.480 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.481 +            break;
   2.482 +   }
   2.483  }
   2.484  
   2.485  static int
   2.486  photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   2.487  {
   2.488 +   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.489 +
   2.490 +   switch (rdata->surfaces_type)
   2.491 +   {
   2.492 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.493 +            PgDrawILineCx(rdata->osurfaces[rdata->surface_render_idx], x1, y1, x2, y2);
   2.494 +            break;
   2.495 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.496 +            PgDrawILineCx(rdata->pcontexts[rdata->surface_render_idx], x1, y1, x2, y2);
   2.497 +            break;
   2.498 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.499 +            break;
   2.500 +   }
   2.501  }
   2.502  
   2.503  static int
   2.504  photon_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect)
   2.505  {
   2.506 +   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.507 +
   2.508 +   switch (rdata->surfaces_type)
   2.509 +   {
   2.510 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.511 +            PgDrawIRectCx(rdata->osurfaces[rdata->surface_render_idx], rect->x, rect->y, rect->w+rect->x-1, rect->h+rect->y-1, Pg_DRAW_FILL);
   2.512 +            break;
   2.513 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.514 +            PgDrawIRectCx(rdata->pcontexts[rdata->surface_render_idx], rect->x, rect->y, rect->w+rect->x-1, rect->h+rect->y-1, Pg_DRAW_FILL);
   2.515 +            break;
   2.516 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.517 +            break;
   2.518 +   }
   2.519  }
   2.520  
   2.521  static int
   2.522 @@ -359,6 +746,53 @@
   2.523  static void
   2.524  photon_renderpresent(SDL_Renderer * renderer)
   2.525  {
   2.526 +   SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.527 +   SDL_Window *window = window=SDL_GetWindowFromID(renderer->window);
   2.528 +   SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
   2.529 +   PhRect_t src_rect;
   2.530 +   PhPoint_t src_point;
   2.531 +
   2.532 +   /* Flush all undrawn graphics data to surface */
   2.533 +   switch (rdata->surfaces_type)
   2.534 +   {
   2.535 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.536 +            PgFlushCx(rdata->osurfaces[rdata->surface_render_idx]);
   2.537 +            PgWaitHWIdle();
   2.538 +            break;
   2.539 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.540 +            PmMemFlush(rdata->pcontexts[rdata->surface_render_idx], rdata->psurfaces[rdata->surface_render_idx]);
   2.541 +            break;
   2.542 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.543 +            return;
   2.544 +   }
   2.545 +
   2.546 +   PgFFlush(Ph_START_DRAW);
   2.547 +   PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
   2.548 +
   2.549 +   /* Set blit area */
   2.550 +   src_rect.ul.x = 0;
   2.551 +   src_rect.ul.y = 0;
   2.552 +   src_rect.lr.x = rdata->window_width - 1;
   2.553 +   src_rect.lr.y = rdata->window_height - 1;
   2.554 +
   2.555 +   src_point.x = 0;
   2.556 +   src_point.y = 0;
   2.557 +
   2.558 +   switch (rdata->surfaces_type)
   2.559 +   {
   2.560 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.561 +            PgContextBlit(rdata->osurfaces[rdata->surface_render_idx], &src_rect, NULL, &src_rect);
   2.562 +            break;
   2.563 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.564 +            PgDrawPhImagev(&src_point, rdata->psurfaces[rdata->surface_render_idx], 0);
   2.565 +            break;
   2.566 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.567 +            break;
   2.568 +   }
   2.569 +
   2.570 +   /* finish blit */
   2.571 +   PgFFlush(Ph_DONE_DRAW);
   2.572 +   PgWaitHWIdle();
   2.573  }
   2.574  
   2.575  static void
   2.576 @@ -370,8 +804,64 @@
   2.577  photon_destroyrenderer(SDL_Renderer * renderer)
   2.578  {
   2.579      SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   2.580 +    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   2.581 +    SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
   2.582      uint32_t it;
   2.583  
   2.584 +    /* Destroy graphics context */
   2.585 +    if (rdata->gc!=NULL)
   2.586 +    {
   2.587 +       PgDestroyGC(rdata->gc);
   2.588 +       rdata->gc=NULL;
   2.589 +    }
   2.590 +
   2.591 +    switch (rdata->surfaces_type)
   2.592 +    {
   2.593 +       case SDL_PHOTON_SURFTYPE_OFFSCREEN:
   2.594 +            {
   2.595 +               /* Destroy current surfaces */
   2.596 +               for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
   2.597 +               {
   2.598 +                  if (rdata->osurfaces[it] != NULL)
   2.599 +                  {
   2.600 +                     PhDCRelease(rdata->osurfaces[it]);
   2.601 +                     rdata->osurfaces[it] = NULL;
   2.602 +                  }
   2.603 +               }
   2.604 +            }
   2.605 +            break;
   2.606 +       case SDL_PHOTON_SURFTYPE_PHIMAGE:
   2.607 +            {
   2.608 +               /* Destroy current surfaces */
   2.609 +               for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
   2.610 +               {
   2.611 +                  if (rdata->pcontexts[it]!=NULL)
   2.612 +                  {
   2.613 +                     PmMemReleaseMC(rdata->pcontexts[it]);
   2.614 +                     rdata->pcontexts[it]=NULL;
   2.615 +                  }
   2.616 +                  if (rdata->psurfaces[it]!=NULL)
   2.617 +                  {
   2.618 +                     if (rdata->psurfaces[it]->palette!=NULL)
   2.619 +                     {
   2.620 +                        SDL_free(rdata->psurfaces[it]->palette);
   2.621 +                        rdata->psurfaces[it]->palette=NULL;
   2.622 +                     }
   2.623 +                     /* Destroy shared memory for PhImage_t */
   2.624 +                     PgShmemDestroy(rdata->psurfaces[it]->image);
   2.625 +                     rdata->psurfaces[it]->image=NULL;
   2.626 +                     SDL_free(rdata->psurfaces[it]);
   2.627 +                     rdata->psurfaces[it]=NULL;
   2.628 +                  }
   2.629 +               }
   2.630 +            }
   2.631 +            break;
   2.632 +       case SDL_PHOTON_SURFTYPE_UNKNOWN:
   2.633 +            {
   2.634 +               /* nothing to do */
   2.635 +            }
   2.636 +            break;
   2.637 +    }
   2.638  }
   2.639  
   2.640  /* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/src/video/photon/SDL_photon_render.h	Sat Oct 10 18:37:35 2009 +0000
     3.2 +++ b/src/video/photon/SDL_photon_render.h	Sat Oct 10 20:15:20 2009 +0000
     3.3 @@ -30,16 +30,27 @@
     3.4  #include "../SDL_sysvideo.h"
     3.5  
     3.6  #include <Ph.h>
     3.7 +#include <photon/PhRender.h>
     3.8  
     3.9  #define SDL_PHOTON_MAX_SURFACES 3
    3.10  
    3.11 +#define SDL_PHOTON_SURFTYPE_UNKNOWN    0x00000000
    3.12 +#define SDL_PHOTON_SURFTYPE_OFFSCREEN  0x00000001
    3.13 +#define SDL_PHOTON_SURFTYPE_PHIMAGE    0x00000002
    3.14 +
    3.15  typedef struct SDL_RenderData
    3.16  {
    3.17 -    SDL_Window *window;         /* SDL window type                    */
    3.18 -    SDL_bool enable_vsync;      /* VSYNC flip synchronization enable  */
    3.19 -    uint32_t surface_visible_idx;       /* Index of visible surface     */
    3.20 -    uint32_t surface_render_idx;        /* Index of render surface      */
    3.21 -    uint32_t surfaces_count;    /* Amount of allocated surfaces */
    3.22 +    SDL_bool enable_vsync;              /* VSYNC flip synchronization enable  */
    3.23 +    uint32_t surface_visible_idx;       /* Index of visible surface           */
    3.24 +    uint32_t surface_render_idx;        /* Index of render surface            */
    3.25 +    uint32_t surfaces_count;            /* Amount of allocated surfaces       */
    3.26 +    uint32_t surfaces_type;             /* Type of allocated surfaces         */
    3.27 +    uint32_t window_width;              /* Last active window width           */
    3.28 +    uint32_t window_height;             /* Last active window height          */
    3.29 +    PhGC_t* gc;                         /* Graphics context                   */
    3.30 +    PdOffscreenContext_t* osurfaces[SDL_PHOTON_MAX_SURFACES];
    3.31 +    PhImage_t* psurfaces[SDL_PHOTON_MAX_SURFACES];
    3.32 +    PmMemoryContext_t* pcontexts[SDL_PHOTON_MAX_SURFACES];
    3.33  } SDL_RenderData;
    3.34  
    3.35  typedef struct SDL_TextureData
    3.36 @@ -48,6 +59,9 @@
    3.37  
    3.38  extern void photon_addrenderdriver(_THIS);
    3.39  
    3.40 +/* Helper function, which redraws the backbuffer */
    3.41 +int _photon_update_rectangles(SDL_Renderer* renderer, PhRect_t* rect);
    3.42 +
    3.43  #endif /* __SDL_PHOTON_RENDER_H__ */
    3.44  
    3.45  /* vi: set ts=4 sw=4 expandtab: */