Commit 53036179 authored by Mike Gorchak's avatar Mike Gorchak

Continue working on 2D support for Photon/QNX.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%404047
parent 345698f1
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#if defined(SDL_VIDEO_OPENGL_ES) #if defined(SDL_VIDEO_OPENGL_ES)
#include "../qnxgf/SDL_gf_pixelfmt.h" #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) #if !defined(SDL_VIDEO_DRIVER_QNXGF)
#include "../qnxgf/SDL_gf_pixelfmt.c" #include "../qnxgf/SDL_gf_pixelfmt.c"
#endif /* SDL_VIDEO_DRIVER_QNXGF */ #endif /* SDL_VIDEO_DRIVER_QNXGF */
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#if defined(SDL_VIDEO_OPENGL_ES) #if defined(SDL_VIDEO_OPENGL_ES)
#include "../qnxgf/SDL_gf_opengles.h" #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) #if !defined(SDL_VIDEO_DRIVER_QNXGF)
#include "../qnxgf/SDL_gf_opengles.c" #include "../qnxgf/SDL_gf_opengles.c"
#endif /* SDL_VIDEO_DRIVER_QNXGF */ #endif /* SDL_VIDEO_DRIVER_QNXGF */
...@@ -137,7 +137,7 @@ static const Photon_DeviceCaps photon_devicename[] = { ...@@ -137,7 +137,7 @@ static const Photon_DeviceCaps photon_devicename[] = {
/* VIA UniChrome graphics driver (devg-unichrome.so) */ /* VIA UniChrome graphics driver (devg-unichrome.so) */
{"unichrome", SDL_PHOTON_ACCELERATED | SDL_PHOTON_UNACCELERATED_3D} {"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} {"vesa", SDL_PHOTON_UNACCELERATED | SDL_PHOTON_UNACCELERATED_3D}
, ,
/* VmWare graphics driver (devg-volari.so) */ /* VmWare graphics driver (devg-volari.so) */
...@@ -155,7 +155,7 @@ static SDL_bool photon_initialized = SDL_FALSE; ...@@ -155,7 +155,7 @@ static SDL_bool photon_initialized = SDL_FALSE;
static int static int
photon_available(void) photon_available(void)
{ {
int status; int32_t status;
/* Check if Photon was initialized before */ /* Check if Photon was initialized before */
if (photon_initialized == SDL_FALSE) { if (photon_initialized == SDL_FALSE) {
...@@ -194,7 +194,7 @@ photon_create(int devindex) ...@@ -194,7 +194,7 @@ photon_create(int devindex)
{ {
SDL_VideoDevice *device; SDL_VideoDevice *device;
SDL_VideoData *phdata; SDL_VideoData *phdata;
int status; int32_t status;
/* Check if photon could be initialized */ /* Check if photon could be initialized */
status = photon_available(); status = photon_available();
...@@ -883,6 +883,13 @@ photon_createwindow(_THIS, SDL_Window * window) ...@@ -883,6 +883,13 @@ photon_createwindow(_THIS, SDL_Window * window)
PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE, PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE,
Ph_WM_STATE_ISALTKEY); 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 */ /* Set window dimension */
winsize.w = window->w; winsize.w = window->w;
winsize.h = window->h; winsize.h = window->h;
...@@ -1305,7 +1312,7 @@ photon_gl_loadlibrary(_THIS, const char *path) ...@@ -1305,7 +1312,7 @@ photon_gl_loadlibrary(_THIS, const char *path)
if (phdata->gfinitialized != SDL_TRUE) { if (phdata->gfinitialized != SDL_TRUE) {
SDL_SetError SDL_SetError
("Photon: GF initialization failed, no OpenGL ES support"); ("Photon: GF initialization failed, no OpenGL ES support");
return NULL; return -1;
} }
/* Check if OpenGL ES library is specified for GF driver */ /* Check if OpenGL ES library is specified for GF driver */
...@@ -1918,6 +1925,7 @@ photon_gl_swapwindow(_THIS, SDL_Window * window) ...@@ -1918,6 +1925,7 @@ photon_gl_swapwindow(_THIS, SDL_Window * window)
(SDL_DisplayData *) SDL_CurrentDisplay.driverdata; (SDL_DisplayData *) SDL_CurrentDisplay.driverdata;
PhRect_t dst_rect; PhRect_t dst_rect;
PhRect_t src_rect; PhRect_t src_rect;
int32_t status;
if (phdata->gfinitialized != SDL_TRUE) { if (phdata->gfinitialized != SDL_TRUE) {
SDL_SetError SDL_SetError
...@@ -1951,6 +1959,17 @@ photon_gl_swapwindow(_THIS, SDL_Window * window) ...@@ -1951,6 +1959,17 @@ photon_gl_swapwindow(_THIS, SDL_Window * window)
src_rect.lr.x = window->w - 1; src_rect.lr.x = window->w - 1;
src_rect.lr.y = window->h - 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 */ /* Blit OpenGL ES pixmap surface directly to window region */
PgFFlush(Ph_START_DRAW); PgFFlush(Ph_START_DRAW);
PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window)); PgSetRegionCx(PhDCGetCurrent(), PtWidgetRid(wdata->window));
...@@ -2324,12 +2343,8 @@ photon_pumpevents(_THIS) ...@@ -2324,12 +2343,8 @@ photon_pumpevents(_THIS)
if ((wdata != NULL) && (window != NULL)) { if ((wdata != NULL) && (window != NULL)) {
/* Check if window uses OpenGL ES */ /* Check if window uses OpenGL ES */
if (wdata->uses_gles == SDL_TRUE) { if (wdata->uses_gles == SDL_TRUE) {
PhRect_t dst_rect;
PhRect_t src_rect;
/* Cycle through each rectangle */ /* Cycle through each rectangle */
for (it = 0; it < event->num_rects; for (it = 0; it < event->num_rects; it++) {
it++) {
/* Blit OpenGL ES pixmap surface directly to window region */ /* Blit OpenGL ES pixmap surface directly to window region */
PgFFlush(Ph_START_DRAW); PgFFlush(Ph_START_DRAW);
PgSetRegionCx(PhDCGetCurrent(), PgSetRegionCx(PhDCGetCurrent(),
...@@ -2345,8 +2360,14 @@ photon_pumpevents(_THIS) ...@@ -2345,8 +2360,14 @@ photon_pumpevents(_THIS)
PgWaitHWIdle(); PgWaitHWIdle();
} }
} else { } else {
/* Normal window */ /* Cycle through each rectangle */
/* TODO: update the damaged rectangles */ 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) ...@@ -2385,10 +2406,19 @@ photon_pumpevents(_THIS)
PgFFlush(Ph_DONE_DRAW); PgFFlush(Ph_DONE_DRAW);
PgWaitHWIdle(); PgWaitHWIdle();
} else { } else {
/* Normal window */ PhRect_t rect;
/* TODO: update the damaged rectangles */
/* We need to redraw entire window */ /* 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,10 +2723,17 @@ photon_pumpevents(_THIS) ...@@ -2693,10 +2723,17 @@ photon_pumpevents(_THIS)
case Ph_WM_MAX: case Ph_WM_MAX:
{ {
if (window != NULL) { if (window != NULL) {
if ((window->flags & SDL_WINDOW_RESIZABLE)==SDL_WINDOW_RESIZABLE)
{
SDL_SendWindowEvent(window->id, SDL_SendWindowEvent(window->id,
SDL_WINDOWEVENT_MAXIMIZED, SDL_WINDOWEVENT_MAXIMIZED,
0, 0); 0, 0);
} }
else
{
/* otherwise ignor the resize events */
}
}
} }
break; break;
case Ph_WM_RESTORE: case Ph_WM_RESTORE:
......
...@@ -68,6 +68,8 @@ static void photon_unlocktexture(SDL_Renderer * renderer, ...@@ -68,6 +68,8 @@ static void photon_unlocktexture(SDL_Renderer * renderer,
static void photon_dirtytexture(SDL_Renderer * renderer, static void photon_dirtytexture(SDL_Renderer * renderer,
SDL_Texture * texture, int numrects, SDL_Texture * texture, int numrects,
const SDL_Rect * rects); 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_renderpoint(SDL_Renderer * renderer, int x, int y);
static int photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2, static int photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2,
int y2); int y2);
...@@ -80,6 +82,8 @@ static void photon_destroytexture(SDL_Renderer * renderer, ...@@ -80,6 +82,8 @@ static void photon_destroytexture(SDL_Renderer * renderer,
SDL_Texture * texture); SDL_Texture * texture);
static void photon_destroyrenderer(SDL_Renderer * renderer); static void photon_destroyrenderer(SDL_Renderer * renderer);
static int _photon_recreate_surfaces(SDL_Renderer * renderer);
SDL_RenderDriver photon_renderdriver = { SDL_RenderDriver photon_renderdriver = {
photon_createrenderer, photon_createrenderer,
{ {
...@@ -92,18 +96,15 @@ SDL_RenderDriver photon_renderdriver = { ...@@ -92,18 +96,15 @@ SDL_RenderDriver photon_renderdriver = {
SDL_TEXTUREMODULATE_ALPHA), SDL_TEXTUREMODULATE_ALPHA),
(SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK |
SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD), SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
(SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_SLOW), (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_SLOW |
13, SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_BEST),
{ 10,
SDL_PIXELFORMAT_INDEX8, {SDL_PIXELFORMAT_INDEX8,
SDL_PIXELFORMAT_RGB555, SDL_PIXELFORMAT_RGB555,
SDL_PIXELFORMAT_RGB565, SDL_PIXELFORMAT_RGB565,
SDL_PIXELFORMAT_RGB24,
SDL_PIXELFORMAT_RGB888, SDL_PIXELFORMAT_RGB888,
SDL_PIXELFORMAT_BGR888,
SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ARGB8888,
SDL_PIXELFORMAT_RGBA8888,
SDL_PIXELFORMAT_ABGR8888,
SDL_PIXELFORMAT_BGRA8888,
SDL_PIXELFORMAT_YV12, SDL_PIXELFORMAT_YV12,
SDL_PIXELFORMAT_YUY2, SDL_PIXELFORMAT_YUY2,
SDL_PIXELFORMAT_UYVY, SDL_PIXELFORMAT_UYVY,
...@@ -150,6 +151,8 @@ photon_createrenderer(SDL_Window * window, Uint32 flags) ...@@ -150,6 +151,8 @@ photon_createrenderer(SDL_Window * window, Uint32 flags)
renderer->LockTexture = photon_locktexture; renderer->LockTexture = photon_locktexture;
renderer->UnlockTexture = photon_unlocktexture; renderer->UnlockTexture = photon_unlocktexture;
renderer->DirtyTexture = photon_dirtytexture; renderer->DirtyTexture = photon_dirtytexture;
renderer->SetDrawColor = photon_setdrawcolor;
renderer->SetDrawBlendMode = photon_setdrawblendmode;
renderer->RenderPoint = photon_renderpoint; renderer->RenderPoint = photon_renderpoint;
renderer->RenderLine = photon_renderline; renderer->RenderLine = photon_renderline;
renderer->RenderFill = photon_renderfill; renderer->RenderFill = photon_renderfill;
...@@ -168,8 +171,6 @@ photon_createrenderer(SDL_Window * window, Uint32 flags) ...@@ -168,8 +171,6 @@ photon_createrenderer(SDL_Window * window, Uint32 flags)
renderer->info.flags &= ~(SDL_RENDERER_ACCELERATED); renderer->info.flags &= ~(SDL_RENDERER_ACCELERATED);
} }
rdata->window = window;
/* Check if upper level requested synchronization on vsync signal */ /* Check if upper level requested synchronization on vsync signal */
if ((flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) { if ((flags & SDL_RENDERER_PRESENTVSYNC) == SDL_RENDERER_PRESENTVSYNC) {
rdata->enable_vsync = SDL_TRUE; rdata->enable_vsync = SDL_TRUE;
...@@ -214,6 +215,13 @@ photon_createrenderer(SDL_Window * window, Uint32 flags) ...@@ -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; return renderer;
} }
...@@ -228,30 +236,349 @@ photon_addrenderdriver(_THIS) ...@@ -228,30 +236,349 @@ 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_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; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->osurfaces[it] != NULL)
{
PhDCRelease(rdata->osurfaces[it]);
rdata->osurfaces[it] = NULL;
}
}
}
else
{
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_PHIMAGE)
{
/* Create shared phimage surfaces */
allocate_task=SDL_PHOTON_SURFTYPE_PHIMAGE;
/* Destroy current surfaces */
for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->pcontexts[it]!=NULL)
{
PmMemReleaseMC(rdata->pcontexts[it]);
rdata->pcontexts[it]=NULL;
}
if (rdata->psurfaces[it]!=NULL)
{
if (rdata->psurfaces[it]->palette!=NULL)
{
SDL_free(rdata->psurfaces[it]->palette);
rdata->psurfaces[it]->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(rdata->psurfaces[it]->image);
rdata->psurfaces[it]->image=NULL;
SDL_free(rdata->psurfaces[it]);
rdata->psurfaces[it]=NULL;
}
}
}
}
}
/* Remove all allocated surfaces, they are no more valid */ /* 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;
}
/* TODO: Add video mode change detection and new parameters detection */ switch (allocate_task)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
{
int32_t it;
int32_t jt;
/* Try the hardware accelerated offscreen surfaces first */
for (it=0; it<rdata->surfaces_count; it++)
{
rdata->osurfaces[it]=PdCreateOffscreenContext(0, window->w, window->h,
Pg_OSC_MEM_LINEAR_ACCESSIBLE |
/* in case if 2D acceleration is not available use CPU optimized surfaces */
Pg_OSC_MEM_HINT_CPU_READ | Pg_OSC_MEM_HINT_CPU_WRITE |
/* in case if 2D acceleration is available use it */
Pg_OSC_MEM_2D_WRITABLE | Pg_OSC_MEM_2D_READABLE);
/* If we can't create an offscreen surface, then fallback to software */
if (rdata->osurfaces[it]==NULL)
{
/* Destroy previously allocated surface(s) */
for (jt = it - 1; jt > 0; jt--)
{
PhDCRelease(rdata->osurfaces[jt]);
rdata->osurfaces[jt] = NULL;
}
break;
}
}
/* Check if all required surfaces have been created */
if (rdata->osurfaces[0]!=NULL)
{
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_OFFSCREEN;
/* exit from switch if surfaces have been created */
break;
}
else
{
/* else fall through to software phimage surface allocation */
}
}
/* fall through */
case SDL_PHOTON_SURFTYPE_PHIMAGE:
{
int32_t it;
int32_t jt;
uint32_t image_pfmt=photon_sdl_to_image_pixelformat(didata->current_mode.format);
/* Try to allocate the software surfaces in shared memory */
for (it=0; it<rdata->surfaces_count; it++)
{
/* If this surface with palette, create a palette space */
if (image_pfmt==Pg_IMAGE_PALETTE_BYTE)
{
rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
image_pfmt, NULL, 256, 1);
}
else
{
rdata->psurfaces[it]=PhCreateImage(NULL, window->w, window->h,
image_pfmt, NULL, 0, 1);
}
if (rdata->psurfaces[it]!=NULL)
{
PhPoint_t translation={0, 0};
PhDim_t dimension={window->w, window->h};
/* Create memory context for PhImage_t */
rdata->pcontexts[it]=PmMemCreateMC(rdata->psurfaces[it], &dimension, &translation);
}
if ((rdata->psurfaces[it]==NULL) || (rdata->pcontexts[it]==NULL))
{
/* Destroy previously allocated surface(s) */
for (jt = it - 1; jt > 0; jt--)
{
if (rdata->pcontexts[jt]!=NULL)
{
PmMemReleaseMC(rdata->pcontexts[it]);
rdata->pcontexts[jt]=NULL;
}
if (rdata->psurfaces[jt]!=NULL)
{
if (rdata->psurfaces[jt]->palette!=NULL)
{
SDL_free(rdata->psurfaces[jt]->palette);
rdata->psurfaces[jt]->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(rdata->psurfaces[jt]->image);
rdata->psurfaces[jt]->image=NULL;
SDL_free(rdata->psurfaces[jt]);
rdata->psurfaces[jt] = NULL;
}
}
break;
}
}
/* Check if all required surfaces have been created */
if (rdata->psurfaces[0]!=NULL)
{
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_PHIMAGE;
}
else
{
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
}
}
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
{
/* do nothing with surface allocation */
rdata->surfaces_type=SDL_PHOTON_SURFTYPE_UNKNOWN;
}
break;
}
/* Check if one of two allocation scheme was successful */
if (rdata->surfaces_type==SDL_PHOTON_SURFTYPE_UNKNOWN)
{
SDL_SetError("Photon: primary surface(s) allocation failure");
return -1;
}
/* Store current surface dimensions */
rdata->window_width=window->w;
rdata->window_height=window->h;
/* If current copy/flip scheme is single buffer, then set initial parameters */
if ((renderer->info.flags & SDL_RENDERER_SINGLEBUFFER)==SDL_RENDERER_SINGLEBUFFER)
{
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 0;
}
/* If current copy/flip scheme is double buffer, then set initial parameters */
if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP2)==SDL_RENDERER_PRESENTFLIP2)
{
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
}
/* If current copy/flip scheme is triple buffer, then set initial parameters */
if ((renderer->info.flags & SDL_RENDERER_PRESENTFLIP3)==SDL_RENDERER_PRESENTFLIP3)
{
rdata->surface_visible_idx = 0;
rdata->surface_render_idx = 1;
}
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
PgSetGCCx(rdata->osurfaces[rdata->surface_render_idx], rdata->gc);
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
PgSetGCCx(rdata->pcontexts[rdata->surface_render_idx], rdata->gc);
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
break;
}
return 0; 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 static int
photon_activaterenderer(SDL_Renderer * renderer) photon_activaterenderer(SDL_Renderer * renderer)
{ {
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata; SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(rdata->window); SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_DisplayData *didata = (SDL_DisplayData *) display->driverdata; 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 static int
photon_createtexture(SDL_Renderer * renderer, SDL_Texture * texture) photon_createtexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
...@@ -269,7 +596,6 @@ photon_createtexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -269,7 +596,6 @@ photon_createtexture(SDL_Renderer * renderer, SDL_Texture * texture)
/* Set texture driver data */ /* Set texture driver data */
texture->driverdata = tdata; texture->driverdata = tdata;
} }
static int static int
...@@ -335,19 +661,80 @@ photon_dirtytexture(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -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 static int
photon_renderpoint(SDL_Renderer * renderer, int x, int y) 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 static int
photon_renderline(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) 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 static int
photon_renderfill(SDL_Renderer * renderer, const SDL_Rect * rect) 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 static int
...@@ -359,6 +746,53 @@ photon_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -359,6 +746,53 @@ photon_rendercopy(SDL_Renderer * renderer, SDL_Texture * texture,
static void static void
photon_renderpresent(SDL_Renderer * renderer) 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 static void
...@@ -370,8 +804,64 @@ static void ...@@ -370,8 +804,64 @@ static void
photon_destroyrenderer(SDL_Renderer * renderer) photon_destroyrenderer(SDL_Renderer * renderer)
{ {
SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata; SDL_RenderData *rdata = (SDL_RenderData *) renderer->driverdata;
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata;
uint32_t it; uint32_t it;
/* Destroy graphics context */
if (rdata->gc!=NULL)
{
PgDestroyGC(rdata->gc);
rdata->gc=NULL;
}
switch (rdata->surfaces_type)
{
case SDL_PHOTON_SURFTYPE_OFFSCREEN:
{
/* Destroy current surfaces */
for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->osurfaces[it] != NULL)
{
PhDCRelease(rdata->osurfaces[it]);
rdata->osurfaces[it] = NULL;
}
}
}
break;
case SDL_PHOTON_SURFTYPE_PHIMAGE:
{
/* Destroy current surfaces */
for (it=0; it<SDL_PHOTON_MAX_SURFACES; it++)
{
if (rdata->pcontexts[it]!=NULL)
{
PmMemReleaseMC(rdata->pcontexts[it]);
rdata->pcontexts[it]=NULL;
}
if (rdata->psurfaces[it]!=NULL)
{
if (rdata->psurfaces[it]->palette!=NULL)
{
SDL_free(rdata->psurfaces[it]->palette);
rdata->psurfaces[it]->palette=NULL;
}
/* Destroy shared memory for PhImage_t */
PgShmemDestroy(rdata->psurfaces[it]->image);
rdata->psurfaces[it]->image=NULL;
SDL_free(rdata->psurfaces[it]);
rdata->psurfaces[it]=NULL;
}
}
}
break;
case SDL_PHOTON_SURFTYPE_UNKNOWN:
{
/* nothing to do */
}
break;
}
} }
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
...@@ -30,16 +30,27 @@ ...@@ -30,16 +30,27 @@
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
#include <Ph.h> #include <Ph.h>
#include <photon/PhRender.h>
#define SDL_PHOTON_MAX_SURFACES 3 #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 typedef struct SDL_RenderData
{ {
SDL_Window *window; /* SDL window type */
SDL_bool enable_vsync; /* VSYNC flip synchronization enable */ SDL_bool enable_vsync; /* VSYNC flip synchronization enable */
uint32_t surface_visible_idx; /* Index of visible surface */ uint32_t surface_visible_idx; /* Index of visible surface */
uint32_t surface_render_idx; /* Index of render surface */ uint32_t surface_render_idx; /* Index of render surface */
uint32_t surfaces_count; /* Amount of allocated surfaces */ 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; } SDL_RenderData;
typedef struct SDL_TextureData typedef struct SDL_TextureData
...@@ -48,6 +59,9 @@ typedef struct SDL_TextureData ...@@ -48,6 +59,9 @@ typedef struct SDL_TextureData
extern void photon_addrenderdriver(_THIS); 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__ */ #endif /* __SDL_PHOTON_RENDER_H__ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment