src/video/qnxgf/SDL_gf_render.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 31 Jan 2011 23:23:57 -0800
changeset 5140 e743b9c3f6d6
parent 5138 da10636e5eca
child 5141 31e7f523ab3d
permissions -rw-r--r--
Making the API simpler, the blend modes are "none, blend, add" and are supported by all renderers.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 
    22     QNX Graphics Framework SDL driver
    23     Copyright (C) 2009 Mike Gorchak
    24     (mike@malva.ua, lestat@i.com.ua)
    25 */
    26 
    27 #include "SDL_config.h"
    28 
    29 #include "../SDL_pixels_c.h"
    30 #include "../SDL_yuv_sw_c.h"
    31 
    32 #include "SDL_video.h"
    33 
    34 #include "SDL_gf_render.h"
    35 #include "SDL_qnxgf.h"
    36 
    37 static SDL_Renderer *gf_createrenderer(SDL_Window * window, Uint32 flags);
    38 static int gf_displaymodechanged(SDL_Renderer * renderer);
    39 static int gf_activaterenderer(SDL_Renderer * renderer);
    40 static int gf_createtexture(SDL_Renderer * renderer, SDL_Texture * texture);
    41 static int gf_querytexturepixels(SDL_Renderer * renderer,
    42                                  SDL_Texture * texture, void **pixels,
    43                                  int *pitch);
    44 static int gf_settexturepalette(SDL_Renderer * renderer,
    45                                 SDL_Texture * texture,
    46                                 const SDL_Color * colors, int firstcolor,
    47                                 int ncolors);
    48 static int gf_gettexturepalette(SDL_Renderer * renderer,
    49                                 SDL_Texture * texture, SDL_Color * colors,
    50                                 int firstcolor, int ncolors);
    51 static int gf_settexturecolormod(SDL_Renderer * renderer,
    52                                  SDL_Texture * texture);
    53 static int gf_settexturealphamod(SDL_Renderer * renderer,
    54                                  SDL_Texture * texture);
    55 static int gf_settexturescalemode(SDL_Renderer * renderer,
    56                                   SDL_Texture * texture);
    57 static int gf_updatetexture(SDL_Renderer * renderer, SDL_Texture * texture,
    58                             const SDL_Rect * rect, const void *pixels,
    59                             int pitch);
    60 static int gf_locktexture(SDL_Renderer * renderer, SDL_Texture * texture,
    61                           const SDL_Rect * rect, int markDirty, void **pixels,
    62                           int *pitch);
    63 static void gf_unlocktexture(SDL_Renderer * renderer, SDL_Texture * texture);
    64 static void gf_dirtytexture(SDL_Renderer * renderer, SDL_Texture * texture,
    65                             int numrects, const SDL_Rect * rects);
    66 static int gf_renderpoint(SDL_Renderer * renderer, int x, int y);
    67 static int gf_renderline(SDL_Renderer * renderer, int x1, int y1, int x2,
    68                          int y2);
    69 static int gf_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect);
    70 static int gf_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture,
    71                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
    72 static void gf_renderpresent(SDL_Renderer * renderer);
    73 static void gf_destroytexture(SDL_Renderer * renderer, SDL_Texture * texture);
    74 static void gf_destroyrenderer(SDL_Renderer * renderer);
    75 
    76 SDL_RenderDriver gf_renderdriver = {
    77     gf_createrenderer,
    78     {
    79      "qnxgf",
    80      (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
    81       SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
    82       SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_PRESENTDISCARD |
    83       SDL_RENDERER_ACCELERATED),
    84      (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
    85       SDL_TEXTUREMODULATE_ALPHA),
    86      13,
    87      {
    88       SDL_PIXELFORMAT_INDEX8,
    89       SDL_PIXELFORMAT_RGB555,
    90       SDL_PIXELFORMAT_RGB565,
    91       SDL_PIXELFORMAT_RGB888,
    92       SDL_PIXELFORMAT_BGR888,
    93       SDL_PIXELFORMAT_ARGB8888,
    94       SDL_PIXELFORMAT_RGBA8888,
    95       SDL_PIXELFORMAT_ABGR8888,
    96       SDL_PIXELFORMAT_BGRA8888,
    97       SDL_PIXELFORMAT_YV12,
    98       SDL_PIXELFORMAT_YUY2,
    99       SDL_PIXELFORMAT_UYVY,
   100       SDL_PIXELFORMAT_YVYU},
   101      0,
   102      0}
   103 };
   104 
   105 static SDL_Renderer *
   106 gf_createrenderer(SDL_Window * window, Uint32 flags)
   107 {
   108     SDL_VideoDisplay *display = window->display;
   109     SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
   110     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
   111     SDL_Renderer *renderer = NULL;
   112     SDL_RenderData *rdata = NULL;
   113     uint32_t it;
   114     int32_t jt;
   115     int32_t status;
   116 
   117     /* Check if it is OpenGL ES window */
   118     if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
   119         /* No error, just no need to create 2D renderer for OpenGL ES window */
   120         return NULL;
   121     }
   122 
   123     /* Allocate new renderer structure */
   124     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(SDL_Renderer));
   125     if (renderer == NULL) {
   126         SDL_OutOfMemory();
   127         return NULL;
   128     }
   129 
   130     /* Allocate renderer data */
   131     rdata = (SDL_RenderData *) SDL_calloc(1, sizeof(SDL_RenderData));
   132     if (rdata == NULL) {
   133         SDL_free(renderer);
   134         SDL_OutOfMemory();
   135         return NULL;
   136     }
   137 
   138     renderer->DisplayModeChanged = gf_displaymodechanged;
   139     renderer->ActivateRenderer = gf_activaterenderer;
   140     renderer->CreateTexture = gf_createtexture;
   141     renderer->QueryTexturePixels = gf_querytexturepixels;
   142     renderer->SetTexturePalette = gf_settexturepalette;
   143     renderer->GetTexturePalette = gf_gettexturepalette;
   144     renderer->SetTextureAlphaMod = gf_settexturealphamod;
   145     renderer->SetTextureColorMod = gf_settexturecolormod;
   146     renderer->UpdateTexture = gf_updatetexture;
   147     renderer->LockTexture = gf_locktexture;
   148     renderer->UnlockTexture = gf_unlocktexture;
   149     renderer->DirtyTexture = gf_dirtytexture;
   150     renderer->RenderPoint = gf_renderpoint;
   151     renderer->RenderLine = gf_renderline;
   152     renderer->RenderFill = gf_renderfill;
   153     renderer->RenderCopy = gf_rendercopy;
   154     renderer->RenderPresent = gf_renderpresent;
   155     renderer->DestroyTexture = gf_destroytexture;
   156     renderer->DestroyRenderer = gf_destroyrenderer;
   157     renderer->info = gf_renderdriver.info;
   158     renderer->window = window;
   159     renderer->driverdata = rdata;
   160 
   161     /* Set render acceleration flag in case it is accelerated */
   162     if ((didata->caps & SDL_GF_ACCELERATED) == SDL_GF_ACCELERATED) {
   163         renderer->info.flags = SDL_RENDERER_ACCELERATED;
   164     } else {
   165         renderer->info.flags &= ~(SDL_RENDERER_ACCELERATED);
   166     }
   167 
   168     rdata->window = window;
   169 
   170     /* Check if upper level requested synchronization on vsync signal */
   171     if ((flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) {
   172         rdata->enable_vsync = SDL_TRUE;
   173     } else {
   174         rdata->enable_vsync = SDL_FALSE;
   175     }
   176 
   177     /* Check what buffer copy/flip scheme is requested */
   178     rdata->surfaces_count = 0;
   179     if ((flags & SDL_RENDERER_SINGLEBUFFER) == SDL_RENDERER_SINGLEBUFFER) {
   180         if ((flags & SDL_RENDERER_PRESENTDISCARD) ==
   181             SDL_RENDERER_PRESENTDISCARD) {
   182             renderer->info.flags |=
   183                 SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD;
   184         } else {
   185             renderer->info.flags |=
   186                 SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY;
   187         }
   188         rdata->surfaces_count = 1;
   189         rdata->surface_visible_idx = 0;
   190         rdata->surface_render_idx = 0;
   191     } else {
   192         if ((flags & SDL_RENDERER_PRESENTFLIP2) == SDL_RENDERER_PRESENTFLIP2) {
   193             renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
   194             rdata->surfaces_count = 2;
   195             rdata->surface_visible_idx = 0;
   196             rdata->surface_render_idx = 1;
   197         } else {
   198             if ((flags & SDL_RENDERER_PRESENTFLIP3) ==
   199                 SDL_RENDERER_PRESENTFLIP3) {
   200                 renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
   201                 rdata->surfaces_count = 3;
   202                 rdata->surface_visible_idx = 0;
   203                 rdata->surface_render_idx = 1;
   204             } else {
   205                 renderer->info.flags |=
   206                     SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY;
   207                 rdata->surfaces_count = 1;
   208                 rdata->surface_visible_idx = 0;
   209                 rdata->surface_render_idx = 0;
   210             }
   211         }
   212     }
   213 
   214     /* Create layer surfaces, which could be visible */
   215     for (it = 0; it < rdata->surfaces_count; it++) {
   216         /* TODO: add palette creation */
   217 
   218         /* Create displayable surfaces */
   219         status =
   220             gf_surface_create_layer(&rdata->surface[it], &didata->layer, 1, 0,
   221                                     didata->current_mode.w,
   222                                     didata->current_mode.h,
   223                                     qnxgf_sdl_to_gf_pixelformat(didata->
   224                                                                 current_mode.
   225                                                                 format), NULL,
   226                                     GF_SURFACE_CREATE_2D_ACCESSIBLE);
   227 
   228         if (status != GF_ERR_OK) {
   229             /* Free already allocated surfaces */
   230             for (jt = it - 1; jt > 0; jt--) {
   231                 gf_surface_free(rdata->surface[jt]);
   232                 rdata->surface[jt] = NULL;
   233             }
   234             SDL_free(rdata);
   235             SDL_free(renderer);
   236             if (status == GF_ERR_MEM) {
   237                 SDL_SetError("unsufficient free video memory");
   238             } else {
   239                 SDL_SetError("error during displayable surface creation");
   240             }
   241             return NULL;
   242         }
   243 
   244         /* Get detailed information about allocated surface */
   245         gf_surface_get_info(rdata->surface[it], &rdata->surface_info[it]);
   246     }
   247 
   248     return renderer;
   249 }
   250 
   251 void
   252 gf_addrenderdriver(_THIS)
   253 {
   254     uint32_t it;
   255 
   256     for (it = 0; it < _this->num_displays; it++) {
   257         SDL_AddRenderDriver(&_this->displays[it], &gf_renderdriver);
   258     }
   259 }
   260 
   261 /****************************************************************************/
   262 /* SDL render interface                                                     */
   263 /****************************************************************************/
   264 static int
   265 gf_displaymodechanged(SDL_Renderer * renderer)
   266 {
   267     SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   268 
   269     /* Remove all allocated surfaces, they are no more valid */
   270 
   271     /* TODO: Add video mode change detection and new parameters detection */
   272 
   273     return 0;
   274 }
   275 
   276 static int
   277 gf_activaterenderer(SDL_Renderer * renderer)
   278 {
   279     SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   280     SDL_VideoDisplay *display = rdata->window->display;
   281     SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata;
   282 
   283     /* Setup current surface as visible */
   284 //   gf_layer_set_surfaces(didata->layer, &rdata->surface[rdata->surface_visible_idx], 1);
   285 
   286     /* Set visible surface when hardware in idle state */
   287 //   gf_layer_update(didata->layer, GF_LAYER_UPDATE_NO_WAIT_IDLE);
   288 
   289     return 0;
   290 }
   291 
   292 static int
   293 gf_createtexture(SDL_Renderer * renderer, SDL_Texture * texture)
   294 {
   295     SDL_RenderData *renderdata = (SDL_RenderData *) renderer->driverdata;
   296     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   297     SDL_VideoDisplay *display = window->display;
   298     SDL_TextureData *tdata = NULL;
   299 
   300     /* Allocate texture driver data */
   301     tdata = (SDL_TextureData *) SDL_calloc(1, sizeof(SDL_TextureData));
   302     if (tdata == NULL) {
   303         SDL_OutOfMemory();
   304         return -1;
   305     }
   306 
   307     /* Set texture driver data */
   308     texture->driverdata = tdata;
   309 
   310 }
   311 
   312 static int
   313 gf_querytexturepixels(SDL_Renderer * renderer, SDL_Texture * texture,
   314                       void **pixels, int *pitch)
   315 {
   316 }
   317 
   318 static int
   319 gf_settexturepalette(SDL_Renderer * renderer, SDL_Texture * texture,
   320                      const SDL_Color * colors, int firstcolor, int ncolors)
   321 {
   322 }
   323 
   324 static int
   325 gf_gettexturepalette(SDL_Renderer * renderer, SDL_Texture * texture,
   326                      SDL_Color * colors, int firstcolor, int ncolors)
   327 {
   328 }
   329 
   330 static int
   331 gf_settexturecolormod(SDL_Renderer * renderer, SDL_Texture * texture)
   332 {
   333 }
   334 
   335 static int
   336 gf_settexturealphamod(SDL_Renderer * renderer, SDL_Texture * texture)
   337 {
   338 }
   339 
   340 static int
   341 gf_updatetexture(SDL_Renderer * renderer, SDL_Texture * texture,
   342                  const SDL_Rect * rect, const void *pixels, int pitch)
   343 {
   344 }
   345 
   346 static int
   347 gf_locktexture(SDL_Renderer * renderer, SDL_Texture * texture,
   348                const SDL_Rect * rect, int markDirty, void **pixels,
   349                int *pitch)
   350 {
   351 }
   352 
   353 static void
   354 gf_unlocktexture(SDL_Renderer * renderer, SDL_Texture * texture)
   355 {
   356 }
   357 
   358 static void
   359 gf_dirtytexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
   360                 const SDL_Rect * rects)
   361 {
   362 }
   363 
   364 static int
   365 gf_renderpoint(SDL_Renderer * renderer, int x, int y)
   366 {
   367 }
   368 
   369 static int
   370 gf_renderline(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
   371 {
   372 }
   373 
   374 static int
   375 gf_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect)
   376 {
   377 }
   378 
   379 static int
   380 gf_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture,
   381               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
   382 {
   383 }
   384 
   385 static void
   386 gf_renderpresent(SDL_Renderer * renderer)
   387 {
   388 }
   389 
   390 static void
   391 gf_destroytexture(SDL_Renderer * renderer, SDL_Texture * texture)
   392 {
   393 }
   394 
   395 static void
   396 gf_destroyrenderer(SDL_Renderer * renderer)
   397 {
   398     SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
   399     uint32_t it;
   400 
   401     for (it = 0; it < rdata->surfaces_count; it++) {
   402         if (rdata->surface[it] != NULL) {
   403             gf_surface_free(rdata->surface[it]);
   404         }
   405     }
   406 }
   407 
   408 /* vi: set ts=4 sw=4 expandtab: */