From 433b788ee43c820a9b95e475183e9117e35a08ef Mon Sep 17 00:00:00 2001 From: Mike Gorchak Date: Sat, 10 Oct 2009 20:15:20 +0000 Subject: [PATCH] Continue working on 2D support for Photon/QNX. --- src/video/photon/SDL_photon.c | 73 +++- src/video/photon/SDL_photon_render.c | 530 ++++++++++++++++++++++++++- src/video/photon/SDL_photon_render.h | 24 +- 3 files changed, 584 insertions(+), 43 deletions(-) diff --git a/src/video/photon/SDL_photon.c b/src/video/photon/SDL_photon.c index 0652c1233..611b87293 100644 --- a/src/video/photon/SDL_photon.c +++ b/src/video/photon/SDL_photon.c @@ -44,7 +44,7 @@ #if defined(SDL_VIDEO_OPENGL_ES) #include "../qnxgf/SDL_gf_pixelfmt.h" - /* If GF driver is not compiled in, include some of usefull functions */ +/* If GF driver is not compiled in, include some of usefull functions */ #if !defined(SDL_VIDEO_DRIVER_QNXGF) #include "../qnxgf/SDL_gf_pixelfmt.c" #endif /* SDL_VIDEO_DRIVER_QNXGF */ @@ -54,7 +54,7 @@ #if defined(SDL_VIDEO_OPENGL_ES) #include "../qnxgf/SDL_gf_opengles.h" - /* If GF driver is not compiled in, include some of usefull functions */ +/* If GF driver is not compiled in, include some of usefull functions */ #if !defined(SDL_VIDEO_DRIVER_QNXGF) #include "../qnxgf/SDL_gf_opengles.c" #endif /* SDL_VIDEO_DRIVER_QNXGF */ @@ -137,7 +137,7 @@ static const Photon_DeviceCaps photon_devicename[] = { /* VIA UniChrome graphics driver (devg-unichrome.so) */ {"unichrome", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D} , - /* VESA unaccelerated gfx driver (devg-vesa.so) */ + /* VESA unaccelerated gfx driver (devg-vesabios.so) */ {"vesa", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D} , /* VmWare graphics driver (devg-volari.so) */ @@ -155,7 +155,7 @@ static SDL_bool photon_initialized = SDL_FALSE; static int photon_available(void) { - int status; + int32_t status; /* Check if Photon was initialized before */ if (photon_initialized == SDL_FALSE) { @@ -194,7 +194,7 @@ photon_create(int devindex) { SDL_VideoDevice *device; SDL_VideoData *phdata; - int status; + int32_t status; /* Check if photon could be initialized */ status = photon_available(); @@ -883,6 +883,13 @@ photon_createwindow(_THIS, SDL_Window * window) PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY); + /* Special case, do not handle maximize events, if window can't be resized */ + if ((window->flags & SDL_WINDOW_RESIZABLE) != SDL_WINDOW_RESIZABLE) + { + PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, + Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_RESIZE); + } + /* Set window dimension */ winsize.w = window->w; winsize.h = window->h; @@ -1305,7 +1312,7 @@ photon_gl_loadlibrary(_THIS, const char *path) if (phdata->gfinitialized != SDL_TRUE) { SDL_SetError ("Photon: GF initialization failed, no OpenGL ES support"); - return NULL; + return -1; } /* Check if OpenGL ES library is specified for GF driver */ @@ -1918,6 +1925,7 @@ photon_gl_swapwindow(_THIS, SDL_Window * window) (SDL_DisplayData *) SDL_CurrentDisplay.driverdata; PhRect_t dst_rect; PhRect_t src_rect; + int32_t status; if (phdata->gfinitialized != SDL_TRUE) { SDL_SetError @@ -1951,6 +1959,17 @@ photon_gl_swapwindow(_THIS, SDL_Window * window) src_rect.lr.x = window->w - 1; src_rect.lr.y = window->h - 1; + /* 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; + } + phdata->current_device_id = didata->device_id; + } + /* Blit OpenGL ES pixmap surface directly to window region */ PgFFlush(Ph_START_DRAW); PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window)); @@ -2324,12 +2343,8 @@ photon_pumpevents(_THIS) if ((wdata != NULL) && (window != NULL)) { /* Check if window uses OpenGL ES */ if (wdata->uses_gles == SDL_TRUE) { - PhRect_t dst_rect; - PhRect_t src_rect; - /* Cycle through each rectangle */ - for (it = 0; it < event->num_rects; - it++) { + for (it = 0; it < event->num_rects; it++) { /* Blit OpenGL ES pixmap surface directly to window region */ PgFFlush(Ph_START_DRAW); PgSetRegionCx(PhDCGetCurrent(), @@ -2345,8 +2360,14 @@ photon_pumpevents(_THIS) PgWaitHWIdle(); } } else { - /* Normal window */ - /* TODO: update the damaged rectangles */ + /* Cycle through each rectangle */ + for (it = 0; it < event->num_rects; + it++) { + /* Blit 2D pixmap surface directly to window region */ + _photon_update_rectangles(window->renderer, &rects[it]); + } + PgFlush(); + PgWaitHWIdle(); } } @@ -2385,10 +2406,19 @@ photon_pumpevents(_THIS) PgFFlush(Ph_DONE_DRAW); PgWaitHWIdle(); } else { - /* Normal window */ - /* TODO: update the damaged rectangles */ + PhRect_t rect; /* We need to redraw entire window */ + rect.ul.x = 0; + rect.ul.y = 0; + rect.lr.x = window->w - 1; + rect.lr.y = window->h - 1; + + /* Blit 2D pixmap surface directly to window region */ + PgFFlush(Ph_START_DRAW); + _photon_update_rectangles(window->renderer, &rect); + PgFFlush(Ph_DONE_DRAW); + PgWaitHWIdle(); } } } @@ -2693,9 +2723,16 @@ photon_pumpevents(_THIS) case Ph_WM_MAX: { if (window != NULL) { - SDL_SendWindowEvent(window->id, - SDL_WINDOWEVENT_MAXIMIZED, - 0, 0); + if ((window->flags & SDL_WINDOW_RESIZABLE)==SDL_WINDOW_RESIZABLE) + { + SDL_SendWindowEvent(window->id, + SDL_WINDOWEVENT_MAXIMIZED, + 0, 0); + } + else + { + /* otherwise ignor the resize events */ + } } } break; diff --git a/src/video/photon/SDL_photon_render.c b/src/video/photon/SDL_photon_render.c index 6b6a96fbf..bd627fda4 100644 --- a/src/video/photon/SDL_photon_render.c +++ b/src/video/photon/SDL_photon_render.c @@ -68,6 +68,8 @@ static void photon_unlocktexture(SDL_Renderer * renderer, 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 @@ static void photon_destroytexture(SDL_Renderer * renderer, 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_RenderDriver photon_renderdriver = { 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 @@ photon_createrenderer(SDL_Window * window, Uint32 flags) 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 @@ photon_createrenderer(SDL_Window * window, Uint32 flags) 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 @@ photon_createrenderer(SDL_Window * window, Uint32 flags) } } + /* Create new graphics context */ + if (rdata->gc==NULL) + { + rdata->gc=PgCreateGC(0); + PgDefaultGC(rdata->gc); + } + return renderer; } @@ -228,28 +236,347 @@ photon_addrenderdriver(_THIS) } /****************************************************************************/ -/* 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; + + /* 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; itosurfaces[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; itpcontexts[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; + } - /* Remove all allocated surfaces, they are no more valid */ + switch (allocate_task) + { + case SDL_PHOTON_SURFTYPE_OFFSCREEN: + { + int32_t it; + int32_t jt; + + /* Try the hardware accelerated offscreen surfaces first */ + for (it=0; itsurfaces_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; + } + } + + /* 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; itsurfaces_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; + } - /* TODO: Add video mode change detection and new parameters detection */ + 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); + } + + 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; +} - return 0; +static int +photon_displaymodechanged(SDL_Renderer * renderer) +{ + return _photon_recreate_surfaces(renderer); } static int @@ -269,7 +596,6 @@ photon_createtexture(SDL_Renderer * renderer, SDL_Texture * texture) /* Set texture driver data */ texture->driverdata = tdata; - } static int @@ -335,19 +661,80 @@ photon_dirtytexture(SDL_Renderer * renderer, SDL_Texture * texture, { } +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 @@ photon_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture, 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 @@ static void 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; itosurfaces[it] != NULL) + { + PhDCRelease(rdata->osurfaces[it]); + rdata->osurfaces[it] = NULL; + } + } + } + break; + case SDL_PHOTON_SURFTYPE_PHIMAGE: + { + /* Destroy current surfaces */ + for (it=0; itpcontexts[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: */ diff --git a/src/video/photon/SDL_photon_render.h b/src/video/photon/SDL_photon_render.h index 7bc0d0ce6..9ad4d2c62 100644 --- a/src/video/photon/SDL_photon_render.h +++ b/src/video/photon/SDL_photon_render.h @@ -30,16 +30,27 @@ #include "../SDL_sysvideo.h" #include +#include #define SDL_PHOTON_MAX_SURFACES 3 +#define SDL_PHOTON_SURFTYPE_UNKNOWN 0x00000000 +#define SDL_PHOTON_SURFTYPE_OFFSCREEN 0x00000001 +#define SDL_PHOTON_SURFTYPE_PHIMAGE 0x00000002 + typedef struct SDL_RenderData { - SDL_Window *window; /* SDL window type */ - SDL_bool enable_vsync; /* VSYNC flip synchronization enable */ - uint32_t surface_visible_idx; /* Index of visible surface */ - uint32_t surface_render_idx; /* Index of render surface */ - uint32_t surfaces_count; /* Amount of allocated surfaces */ + SDL_bool enable_vsync; /* VSYNC flip synchronization enable */ + uint32_t surface_visible_idx; /* Index of visible surface */ + uint32_t surface_render_idx; /* Index of render surface */ + uint32_t surfaces_count; /* Amount of allocated surfaces */ + uint32_t surfaces_type; /* Type of allocated surfaces */ + uint32_t window_width; /* Last active window width */ + uint32_t window_height; /* Last active window height */ + PhGC_t* gc; /* Graphics context */ + PdOffscreenContext_t* osurfaces[SDL_PHOTON_MAX_SURFACES]; + PhImage_t* psurfaces[SDL_PHOTON_MAX_SURFACES]; + PmMemoryContext_t* pcontexts[SDL_PHOTON_MAX_SURFACES]; } SDL_RenderData; typedef struct SDL_TextureData @@ -48,6 +59,9 @@ typedef struct SDL_TextureData extern void photon_addrenderdriver(_THIS); +/* Helper function, which redraws the backbuffer */ +int _photon_update_rectangles(SDL_Renderer* renderer, PhRect_t* rect); + #endif /* __SDL_PHOTON_RENDER_H__ */ /* vi: set ts=4 sw=4 expandtab: */