src/video/photon/SDL_ph_image.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 28 May 2002 19:31:32 +0000
changeset 380 bce7171e7a85
parent 370 ba72f259bc88
child 571 8e3ce997621c
permissions -rw-r--r--
Date: Wed, 22 May 2002 22:30:58 +0300
From: "Mike Gorchak" <mike@malva.com.ua>
Subject: One more QNX patch

Hi !

- Fixed graywin test application. Added properly support for
window size not equal to 640x480.
- Added support for not aligned pitch of image in SDL_SWSURFACE
and SDL_HWSURFACE. Using Photon builtin alignes.
- Added memory clear after each malloc to avoid problems in the
future :)
- Removed unused variables and static variables, fixed some warnings.
- Updated readme.QNX file.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 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     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #include <stdlib.h>
    29 #include <Ph.h>
    30 #include <photon/Pg.h>
    31 
    32 #include "SDL_error.h"
    33 #include "SDL_endian.h"
    34 #include "SDL_ph_image_c.h"
    35 
    36 /* remove this line, if photon headers updates */
    37 int PgWaitHWIdle(void);
    38 
    39 int ph_SetupImage(_THIS, SDL_Surface *screen)
    40 {
    41     PgColor_t* palette=NULL;
    42     int type=0;
    43     int bpp;
    44     
    45     bpp=screen->format->BitsPerPixel;
    46 
    47     /* Determine image type */
    48     switch(bpp)
    49     {
    50         case 8:{
    51             type = Pg_IMAGE_PALETTE_BYTE;
    52         }
    53         break;
    54         case 15:{
    55             type = Pg_IMAGE_DIRECT_555; 
    56         }
    57         break;
    58         case 16:{
    59             type = Pg_IMAGE_DIRECT_565; 
    60         }
    61         break;
    62         case 24:{
    63             type = Pg_IMAGE_DIRECT_888;
    64         }
    65         break;
    66         case 32:{
    67             type = Pg_IMAGE_DIRECT_8888;
    68         }
    69         break;
    70         default:{
    71             fprintf(stderr,"ph_SetupImage(): unsupported bbp = %d\n", bpp);
    72             return -1;
    73         }
    74         break;
    75     }
    76 
    77     /* palette emulation code */
    78     if ((bpp==8) && (desktoppal==SDLPH_PAL_EMULATE))
    79     {
    80         /* creating image palette */
    81         palette=malloc(_Pg_MAX_PALETTE*sizeof(PgColor_t));
    82         PgGetPalette(palette);
    83 
    84         /* using shared memory for speed (set last param to 1) */
    85         if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, palette, _Pg_MAX_PALETTE, 1)) == NULL)
    86         {
    87             fprintf(stderr,"ph_SetupImage(): PhCreateImage failed for bpp=8.\n");
    88             return -1;
    89         }
    90     }
    91     else
    92     {
    93         /* using shared memory for speed (set last param to 1) */
    94         if ((SDL_Image = PhCreateImage(NULL, screen->w, screen->h, type, NULL, 0, 1)) == NULL)
    95         {
    96             fprintf(stderr,"ph_SetupImage: PhCreateImage failed.\n");
    97             return -1;
    98         }
    99     }
   100     
   101     screen->pixels = SDL_Image->image;
   102     screen->pitch = SDL_Image->bpl; /* Recalculated pitch, created by PhCreateImage */
   103 
   104     this->UpdateRects = ph_NormalUpdate;
   105 
   106     return 0;
   107 }
   108 
   109 int ph_SetupOCImage(_THIS, SDL_Surface *screen)
   110 {
   111     int type = 0;
   112     int bpp;
   113     
   114     bpp=screen->format->BitsPerPixel;
   115 
   116     /* Determine image type */
   117     switch(bpp)
   118     {
   119         case 8: {
   120                     type = Pg_IMAGE_PALETTE_BYTE;
   121                 }
   122                 break;
   123         case 15:{
   124                     type = Pg_IMAGE_DIRECT_555; 
   125 		}
   126 		break;
   127         case 16:{
   128                     type = Pg_IMAGE_DIRECT_565; 
   129                 }
   130                 break;
   131         case 24:{
   132                     type = Pg_IMAGE_DIRECT_888;
   133                 }
   134                 break;
   135         case 32:{
   136                     type = Pg_IMAGE_DIRECT_8888;
   137                 }
   138                 break;
   139         default:{
   140                     fprintf(stderr,"ph_SetupOCImage(): unsupported bpp = %d\n", bpp);
   141                     return -1;
   142                 }
   143                 break;
   144     }
   145 
   146     OCImage.FrameData0 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
   147     OCImage.FrameData1 = (FRAMEDATA *) malloc((size_t)(sizeof(FRAMEDATA)));
   148     memset(OCImage.FrameData0, 0x00, (size_t)(sizeof(FRAMEDATA)));
   149     memset(OCImage.FrameData1, 0x00, (size_t)(sizeof(FRAMEDATA)));
   150 
   151     if(OCImage.direct_context == NULL)
   152     {
   153         OCImage.direct_context = PdCreateDirectContext();
   154     }
   155 
   156     OCImage.offscreen_context = PdCreateOffscreenContext(0, screen->w, screen->h, Pg_OSC_MEM_PAGE_ALIGN);
   157 
   158     if (OCImage.offscreen_context == NULL)
   159     {
   160         fprintf(stderr, "ph_SetupOCImage(): PdCreateOffscreenContext failed !\n");
   161         return -1;
   162     }
   163 
   164     screen->pitch = OCImage.offscreen_context->pitch; /* Recalculated pitch */
   165 
   166     if (OCImage.flags & SDL_DOUBLEBUF)
   167     {
   168         fprintf(stderr, "ph_SetupOCImage(): Hardware flag for doublebuf offscreen context\n");
   169     }
   170 
   171     OCImage.dc_ptr.ptr8 = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
   172 
   173     if (OCImage.dc_ptr.ptr8 == NULL)
   174     {
   175         fprintf(stderr, "ph_SetupOCImage(): PdGetOffscreenContextPtr failed !\n");
   176         return -1;
   177     }
   178 
   179     OCImage.CurrentFrameData = OCImage.FrameData0;
   180     OCImage.CurrentFrameData->Y = OCImage.dc_ptr.ptr8;
   181     OCImage.CurrentFrameData->U = NULL;
   182     OCImage.CurrentFrameData->V = NULL;
   183     OCImage.current = 0;
   184 
   185     PhDCSetCurrent(OCImage.offscreen_context);
   186 
   187     screen->pixels = OCImage.CurrentFrameData->Y;
   188 
   189     this->UpdateRects = ph_OCUpdate;
   190 
   191     return 0;
   192 }
   193 
   194 int ph_SetupOpenGLImage(_THIS, SDL_Surface* screen)
   195 {
   196    this->UpdateRects = ph_OpenGLUpdate;
   197    
   198    return 0;
   199 }
   200 
   201 void ph_DestroyImage(_THIS, SDL_Surface *screen)
   202 {
   203     if (OCImage.offscreen_context != NULL)
   204     {
   205         PhDCRelease(OCImage.offscreen_context);
   206         OCImage.offscreen_context = NULL;
   207         free(OCImage.FrameData0);
   208         OCImage.FrameData0 = NULL;
   209         free(OCImage.FrameData1);
   210         OCImage.FrameData1 = NULL;
   211     }
   212 
   213     if (SDL_Image)
   214     {
   215         /* if palette allocated, free it */
   216         if (SDL_Image->palette)
   217         {
   218             free(SDL_Image->palette);
   219         }
   220         PgShmemDestroy(SDL_Image->image);
   221         free(SDL_Image);
   222     }
   223 
   224     /* Must be zeroed everytime */
   225     SDL_Image = NULL;
   226 
   227     if (screen)
   228     {
   229         screen->pixels = NULL;
   230     }
   231 }
   232 
   233 int ph_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags)
   234 {
   235     ph_DestroyImage(this, screen);
   236     
   237     if (flags & SDL_HWSURFACE)
   238     {
   239         OCImage.flags = flags;  /* needed for SDL_DOUBLEBUF check */
   240         return ph_SetupOCImage(this, screen);
   241     }
   242     else if (flags & SDL_OPENGL)
   243     {
   244         return ph_SetupOpenGLImage(this, screen);
   245     } 
   246     else
   247     {
   248         return ph_SetupImage(this, screen);
   249     }      
   250 }
   251 int ph_AllocHWSurface(_THIS, SDL_Surface *surface)
   252 {
   253     return(-1);
   254 }
   255 
   256 void ph_FreeHWSurface(_THIS, SDL_Surface *surface)
   257 {
   258     return;
   259 }
   260 
   261 int ph_FlipHWSurface(_THIS, SDL_Surface *surface)
   262 {
   263     return(0);
   264 }
   265 
   266 int ph_LockHWSurface(_THIS, SDL_Surface *surface)
   267 {
   268     if ((surface == SDL_VideoSurface) && blit_queued) {
   269 	PgFlush();
   270         blit_queued = 0;
   271     }
   272 
   273     return(0);
   274 }
   275 
   276 void ph_UnlockHWSurface(_THIS, SDL_Surface *surface)
   277 {
   278     return;
   279 }
   280 
   281 void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects)
   282 {
   283    this->GL_SwapBuffers(this);
   284    
   285    return;
   286 }
   287 
   288 void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
   289 {
   290     PhPoint_t ph_pos;
   291     PhRect_t ph_rect;
   292     int i;
   293 
   294     for (i=0; i<numrects; ++i) 
   295     {
   296     	if (rects[i].w==0) /* Clipped? */
   297         { 
   298             continue;
   299         }
   300 
   301         ph_pos.x = rects[i].x;
   302         ph_pos.y = rects[i].y;
   303         ph_rect.ul.x = rects[i].x;
   304         ph_rect.ul.y = rects[i].y;
   305         ph_rect.lr.x = rects[i].x + rects[i].w;
   306         ph_rect.lr.y = rects[i].y + rects[i].h;
   307 
   308         if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
   309         {
   310             fprintf(stderr,"ph_NormalUpdate(): PgDrawPhImageRectmx failed.\n");
   311         }
   312     }
   313 
   314     if (PgFlush() < 0)
   315     {
   316     	fprintf(stderr,"ph_NormalUpdate(): PgFlush failed.\n");
   317     }
   318 }
   319 
   320 void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects)
   321 {
   322     int i;
   323 
   324     PhPoint_t zero = {0};
   325     PhArea_t src_rect;
   326     PhArea_t dest_rect;
   327 
   328     if(OCImage.direct_context == NULL)
   329     {
   330         return;
   331     }
   332 
   333     PgSetRegion(PtWidgetRid(window));
   334     PgSetClipping(0, NULL);
   335     PgWaitHWIdle();
   336 
   337     for (i=0; i<numrects; ++i)
   338     {
   339         if (rects[i].w == 0)  /* Clipped? */
   340         {
   341             continue;
   342         }
   343 
   344         src_rect.pos.x=rects[i].x;
   345         src_rect.pos.y=rects[i].y;
   346         dest_rect.pos.x=rects[i].x;
   347         dest_rect.pos.y=rects[i].y;
   348 
   349         src_rect.size.w=rects[i].w;
   350         src_rect.size.h=rects[i].h;
   351         dest_rect.size.w=rects[i].w;
   352         dest_rect.size.h=rects[i].h;
   353 
   354         zero.x = 0;
   355         zero.y = 0;
   356         PgSetTranslation(&zero, 0);
   357         PgSetRegion(PtWidgetRid(window));
   358         PgSetClipping(0, NULL);
   359         PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect);
   360     }
   361 
   362     if (PgFlush() < 0)
   363     {
   364         fprintf(stderr,"ph_OCUpdate(): PgFlush failed.\n");
   365     }
   366     
   367     /* later used to toggling double buffer */
   368     if (OCImage.current == 0)
   369     {
   370         OCImage.CurrentFrameData = OCImage.FrameData0;
   371     }
   372     else
   373     {
   374         OCImage.CurrentFrameData = OCImage.FrameData1;
   375     }
   376 }