diff --git a/legacy/evas/Makefile.am b/legacy/evas/Makefile.am index 7b28d3e9ab..0ca7f154e1 100644 --- a/legacy/evas/Makefile.am +++ b/legacy/evas/Makefile.am @@ -46,6 +46,7 @@ evas-software-16-ddraw.pc.in \ evas-direct3d.pc.in \ evas-software-16-wince.pc.in \ evas-software-sdl.pc.in \ +evas-psl1ght.pc.in \ evas.spec.in \ evas.spec \ m4/efl_attribute.m4 \ @@ -124,6 +125,10 @@ if BUILD_ENGINE_SOFTWARE_SDL pkgconfig_DATA += evas-software-sdl.pc endif +if BUILD_ENGINE_PSL1GHT +pkgconfig_DATA += evas-psl1ght.pc +endif + .PHONY: doc coverage doc: diff --git a/legacy/evas/configure.ac b/legacy/evas/configure.ac index 05f0850577..2dee0c3ca1 100644 --- a/legacy/evas/configure.ac +++ b/legacy/evas/configure.ac @@ -111,6 +111,7 @@ want_evas_engine_gl_cocoa="yes" want_evas_engine_direct3d="no" want_evas_engine_fb="no" want_evas_engine_directfb="no" +want_evas_engine_psl1ght="no" want_evas_image_loader_edb="yes" want_evas_image_loader_eet="yes" @@ -163,6 +164,12 @@ case "$host_os" in ;; esac +case "$host_vendor" in + ps3*) + want_evas_engine_psl1ght="static" + ;; +esac + requirement_evas="" @@ -677,6 +684,8 @@ EVAS_CHECK_ENGINE([direct3d], [${want_evas_engine_direct3d}], [no], [Direct3D]) EVAS_CHECK_ENGINE([software-sdl], [${want_evas_engine_software_sdl}], [no], [Software SDL]) +EVAS_CHECK_ENGINE([psl1ght], [${want_evas_engine_psl1ght}], [no], [PSL1GHT]) + EVAS_CHECK_ENGINE([gl-sdl], [${want_evas_engine_gl_sdl}], [no], [OpenGL SDL]) EVAS_CHECK_ENGINE([gl-cocoa], [${want_evas_engine_gl_cocoa}], [no], [OpenGL Cocoa]) @@ -1785,6 +1794,7 @@ evas-software-16-ddraw.pc evas-direct3d.pc evas-software-16-wince.pc evas-software-sdl.pc +evas-psl1ght.pc evas.pc doc/evas.dox doc/Makefile @@ -1821,6 +1831,7 @@ src/modules/engines/gl_common/Makefile src/modules/engines/gl_x11/Makefile src/modules/engines/gl_sdl/Makefile src/modules/engines/gl_cocoa/Makefile +src/modules/engines/psl1ght/Makefile src/modules/engines/software_sdl/Makefile src/modules/engines/software_8/Makefile src/modules/engines/software_8_x11/Makefile @@ -1917,6 +1928,7 @@ fi echo " OpenGL Cocoa...............: $have_evas_engine_gl_cocoa" echo " Software Framebuffer.......: $have_evas_engine_fb" echo " DirectFB...................: $have_evas_engine_directfb" +echo " PSL1GHT....................: $have_evas_engine_psl1ght" echo " Software 8bit grayscale....: $have_evas_engine_software_8" # FIXME: kill software 16bit echo " Software 16bit ............: $have_evas_engine_software_16" diff --git a/legacy/evas/evas-psl1ght.pc.in b/legacy/evas/evas-psl1ght.pc.in new file mode 100644 index 0000000000..ba17d58c78 --- /dev/null +++ b/legacy/evas/evas-psl1ght.pc.in @@ -0,0 +1,3 @@ +Name: evas-psl1ght +Description: Evas PSL1GHT engine +Version: @VERSION@ diff --git a/legacy/evas/m4/evas_check_engine.m4 b/legacy/evas/m4/evas_check_engine.m4 index 7330a3f066..a3f3b219d8 100644 --- a/legacy/evas/m4/evas_check_engine.m4 +++ b/legacy/evas/m4/evas_check_engine.m4 @@ -797,6 +797,28 @@ fi ]) +dnl use: EVAS_CHECK_ENGINE_DEP_PSL1GHT(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) + +AC_DEFUN([EVAS_CHECK_ENGINE_DEP_PSL1GHT], +[ + +have_dep="no" +evas_engine_[]$1[]_cflags="" +evas_engine_[]$1[]_libs="" + +AC_CHECK_HEADER([rsx/rsx.h], [have_dep="yes"]) + +AC_SUBST([evas_engine_$1_cflags]) +AC_SUBST([evas_engine_$1_libs]) + +if test "x${have_dep}" = "xyes" ; then + m4_default([$4], [:]) +else + m4_default([$5], [:]) +fi + +]) + dnl use: EVAS_CHECK_ENGINE(engine, want_engine, simple, description) diff --git a/legacy/evas/src/lib/Makefile.am b/legacy/evas/src/lib/Makefile.am index 6f848664f6..6b82555eaa 100644 --- a/legacy/evas/src/lib/Makefile.am +++ b/legacy/evas/src/lib/Makefile.am @@ -43,6 +43,11 @@ EVAS_STATIC_MODULE += \ ../modules/engines/gl_sdl/libevas_engine_gl_sdl.la EVAS_STATIC_LIBADD += @evas_engine_gl_common_libs@ @evas_engine_gl_sdl_libs@ endif +if EVAS_STATIC_BUILD_PSL1GHT +SUBDIRS += ../modules/engines/psl1ght/ +EVAS_STATIC_MODULE += ../modules/engines/psl1ght/libevas_engine_psl1ght.la +EVAS_STATIC_LIBADD += @evas_engine_psl1ght_libs@ +endif if EVAS_STATIC_BUILD_SOFTWARE_16 SUBDIRS += ../modules/engines/software_16/ EVAS_STATIC_MODULE += ../modules/engines/software_16/libevas_engine_software_16.la diff --git a/legacy/evas/src/lib/file/evas_module.c b/legacy/evas/src/lib/file/evas_module.c index b335dbae0e..6b4d4f64df 100644 --- a/legacy/evas/src/lib/file/evas_module.c +++ b/legacy/evas/src/lib/file/evas_module.c @@ -87,6 +87,7 @@ EVAS_EINA_STATIC_MODULE_DEFINE(engine, directfb); EVAS_EINA_STATIC_MODULE_DEFINE(engine, fb); EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_x11); EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_sdl); +EVAS_EINA_STATIC_MODULE_DEFINE(engine, psl1ght); EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16); EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_ddraw); EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_sdl); @@ -142,6 +143,9 @@ static const struct { #ifdef EVAS_STATIC_BUILD_GL_SDL EVAS_EINA_STATIC_MODULE_USE(engine, gl_sdl), #endif +#ifdef EVAS_STATIC_BUILD_PSL1GHT + EVAS_EINA_STATIC_MODULE_USE(engine, psl1ght), +#endif #ifdef EVAS_STATIC_BUILD_SOFTWARE_16 EVAS_EINA_STATIC_MODULE_USE(engine, software_16), #endif diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index e8d461213f..1992dd7dc5 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -9,6 +9,10 @@ # include #endif +#ifdef HAVE_ESCAPE +# include +#endif + #include #include "Evas.h" //#include "Evas_GL.h" diff --git a/legacy/evas/src/modules/engines/Makefile.am b/legacy/evas/src/modules/engines/Makefile.am index b307fb98c2..7d870a191c 100644 --- a/legacy/evas/src/modules/engines/Makefile.am +++ b/legacy/evas/src/modules/engines/Makefile.am @@ -18,6 +18,10 @@ if !EVAS_STATIC_BUILD_FB SUBDIRS += fb endif +if !EVAS_STATIC_BUILD_PSL1GHT +SUBDIRS += psl1ght +endif + if !EVAS_STATIC_BUILD_GL_COMMON SUBDIRS += gl_common endif diff --git a/legacy/evas/src/modules/engines/psl1ght/Evas_Engine_PSL1GHT.h b/legacy/evas/src/modules/engines/psl1ght/Evas_Engine_PSL1GHT.h new file mode 100644 index 0000000000..f1d5636df2 --- /dev/null +++ b/legacy/evas/src/modules/engines/psl1ght/Evas_Engine_PSL1GHT.h @@ -0,0 +1,16 @@ +#ifndef _EVAS_ENGINE_PSL1GHT_H +#define _EVAS_ENGINE_PSL1GHT_H + +typedef struct _Evas_Engine_Info_PSL1GHT Evas_Engine_Info_PSL1GHT; + +struct _Evas_Engine_Info_PSL1GHT +{ + /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ + /* at you and make nasty noises */ + Evas_Engine_Info magic; + + /* non-blocking or blocking mode */ + Evas_Engine_Render_Mode render_mode; +}; +#endif + diff --git a/legacy/evas/src/modules/engines/psl1ght/Makefile.am b/legacy/evas/src/modules/engines/psl1ght/Makefile.am new file mode 100644 index 0000000000..92ccea7940 --- /dev/null +++ b/legacy/evas/src/modules/engines/psl1ght/Makefile.am @@ -0,0 +1,47 @@ + +MAINTAINERCLEANFILES = Makefile.in + +AM_CPPFLAGS = \ +-I. \ +-I$(top_srcdir)/src/lib \ +-I$(top_srcdir)/src/lib/include \ +-I$(top_srcdir)/src/modules/engines \ +@FREETYPE_CFLAGS@ \ +@PIXMAN_CFLAGS@ \ +@EINA_CFLAGS@ \ +@evas_engine_psl1ght_cflags@ + +if BUILD_ENGINE_PSL1GHT + +PSL1GHT_SOURCES = \ +evas_engine.c \ +rsxutil.c + +PSL1GHT_LIBADD = @evas_engine_psl1ght_libs@ + + +includes_HEADERS = Evas_Engine_PSL1GHT.h +includesdir = $(includedir)/evas-@VMAJ@ + +if !EVAS_STATIC_BUILD_PSL1GHT + +pkgdir = $(libdir)/evas/modules/engines/psl1ght/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la +module_la_SOURCES = $(PSL1GHT_SOURCES) +module_la_LIBADD = @EINA_LIBS@ $(PSL1GHT_LIBADD) $(top_builddir)/src/lib/libevas.la +module_la_LDFLAGS = -module -avoid-version +module_la_LIBTOOLFLAGS = --tag=disable-static + +else + +noinst_LTLIBRARIES = libevas_engine_psl1ght.la + +libevas_engine_psl1ght_la_SOURCES = $(PSL1GHT_SOURCES) +libevas_engine_psl1ght_la_LIBADD = $(PSL1GHT_LIBADD) + +endif +endif + +EXTRA_DIST = \ +evas_engine.h \ +rsxutil.h diff --git a/legacy/evas/src/modules/engines/psl1ght/evas_engine.c b/legacy/evas/src/modules/engines/psl1ght/evas_engine.c new file mode 100644 index 0000000000..750c0982a9 --- /dev/null +++ b/legacy/evas/src/modules/engines/psl1ght/evas_engine.c @@ -0,0 +1,511 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "rsxutil.h" +#include "Evas_Engine_PSL1GHT.h" + +#include + +int _evas_engine_psl1ght_log_dom = -1; + +/* function tables - filled in later (func and parent func) */ +static Evas_Func func, pfunc; + +/* engine struct data */ +typedef struct _Render_Engine Render_Engine; + +#define MAX_BUFFERS 2 + +struct _Render_Engine +{ + Tilebuf *tb; + Tilebuf_Rect *rects; + Eina_Inlist *cur_rect; + + /* RSX device context */ + gcmContextData *context; + void *host_addr; + + /* The buffers we will be drawing into. */ + rsxBuffer buffers[MAX_BUFFERS]; + int currentBuffer; + int width; + int height; + RGBA_Image *rgba_image; + uint32_t rgba_image_offset; + + int end : 1; +}; + +/* prototypes we will use here */ +static void *_output_setup(int w, int h); + +static void *eng_info(Evas *e); +static void + eng_info_free(Evas *e, void *info); +static int + eng_setup(Evas *e, void *info); +static void + eng_output_free(void *data); +static void + eng_output_resize(void *data, int w, int h); +static void + eng_output_tile_size_set(void *data, int w, int h); +static void + eng_output_redraws_rect_add(void *data, int x, int y, int w, int h); +static void + eng_output_redraws_rect_del(void *data, int x, int y, int w, int h); +static void + eng_output_redraws_clear(void *data); +static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch); +static void + eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h); +static void + eng_output_flush(void *data); +static void + eng_output_idle_flush(void *data); + +/* internal engine routines */ +static void * +_output_setup(int w, int h) +{ + Render_Engine *re; + int i; + u16 width, height; + DATA32 *image_data = NULL; + int image_size; + + printf ("_output_setup called : %dx%d\n", w, h); + re = calloc(1, sizeof(Render_Engine)); + if (!re) + return NULL; + + /* Allocate a 1Mb buffer, alligned to a 1Mb boundary + * to be our shared IO memory with the RSX. */ + re->host_addr = memalign (1024 * 1024, HOST_SIZE); + if (re->host_addr == NULL) + { + free (re); + return NULL; + } + re->context = initScreen (re->host_addr, HOST_SIZE); + if (re->context == NULL) + { + free (re->host_addr); + free (re); + return NULL; + } + width = w; + height = h; + setResolution (re->context, &width, &height); + re->currentBuffer = 0; + re->width = width; + re->height = height; + + for (i = 0; i < MAX_BUFFERS; i++) + makeBuffer (&re->buffers[i], width, height, i); + + flipBuffer(re->context, MAX_BUFFERS - 1); + + /* if we haven't initialized - init (automatic abort if already done) */ + evas_common_cpu_init(); + evas_common_blend_init(); + evas_common_image_init(); + evas_common_convert_init(); + evas_common_scale_init(); + evas_common_rectangle_init(); + evas_common_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); + + re->tb = evas_common_tilebuf_new(w, h); + + /* in preliminary tests 16x16 gave highest framerates */ + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + + /* Allocate our memaligned backbuffer */ + image_size = ((w * h * sizeof(u32)) + 0xfffff) & - 0x100000; + image_data = memalign (1024 * 1024, image_size); + re->rgba_image = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), + w, h, image_data, 1, EVAS_COLORSPACE_ARGB8888); + gcmMapMainMemory(image_data, image_size, &re->rgba_image_offset); + + return re; +} + +/* engine api this module provides */ +static void * +eng_info(Evas *e) +{ + Evas_Engine_Info_PSL1GHT *info; + + printf ("eng_info called\n"); + info = calloc(1, sizeof(Evas_Engine_Info_PSL1GHT)); + if (!info) + return NULL; + + info->magic.magic = rand(); + info->render_mode = EVAS_RENDER_MODE_BLOCKING; + + return info; +} + +static void +eng_info_free(Evas *e __UNUSED__, void *info) +{ + Evas_Engine_Info_PSL1GHT *in; + + printf ("eng_info_free called\n"); + in = (Evas_Engine_Info_PSL1GHT *)info; + free(in); +} + +static int +eng_setup(Evas *e, void *in) +{ + Evas_Engine_Info_PSL1GHT *info; + + printf ("eng_setup called\n"); + info = (Evas_Engine_Info_PSL1GHT *)in; + + e->engine.data.output = _output_setup(e->output.w, e->output.h); + if (!e->engine.data.output) + return 0; + + e->engine.func = &func; + e->engine.data.context = e->engine.func->context_new(e->engine.data.output); + + return 1; +} + +static void +eng_output_free(void *data) +{ + Render_Engine *re; + int i; + + printf ("eng_output_free called\n"); + re = (Render_Engine *)data; + + gcmSetWaitFlip(re->context); + for (i = 0; i < MAX_BUFFERS; i++) + rsxFree (re->buffers[i].ptr); + + if (re->rgba_image) + { + DATA32 *image_data; + + image_data = re->rgba_image->image.data; + evas_cache_image_drop(&re->rgba_image->cache_entry); + free (image_data); + } + + freeScreen (re->context); + free (re->host_addr); + + evas_common_tilebuf_free(re->tb); + if (re->rects) + evas_common_tilebuf_free_render_rects(re->rects); + + free(re); + + evas_common_font_shutdown(); + evas_common_image_shutdown(); +} + +static void +eng_output_resize(void *data, int w, int h) +{ + Render_Engine *re; + int i; + u16 width, height; + DATA32 *image_data; + int image_size; + + printf ("eng_output_resize called : %dx%d\n", w, h); + re = (Render_Engine *)data; + + width = w; + height = h; + if (setResolution (re->context, &width, &height)) + { + re->width = width; + re->height = height; + + gcmSetWaitFlip(re->context); + for (i = 0; i < MAX_BUFFERS; i++) { + rsxFree (re->buffers[i].ptr); + makeBuffer (&re->buffers[i], width, height, i); + } + + flipBuffer(re->context, MAX_BUFFERS - 1); + + evas_common_tilebuf_free(re->tb); + re->tb = evas_common_tilebuf_new(w, h); + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + + /* Realloc our backbuf image */ + if (re->rgba_image) + { + image_data = re->rgba_image->image.data; + evas_cache_image_drop(&re->rgba_image->cache_entry); + free (image_data); + } + image_size = ((w * h * sizeof(u32)) + 0xfffff) & - 0x100000; + image_data = memalign (1024 * 1024, image_size); + re->rgba_image = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), + w, h, image_data, 1, EVAS_COLORSPACE_ARGB8888); + gcmMapMainMemory(image_data, image_size, &re->rgba_image_offset); + } +} + +static void +eng_output_tile_size_set(void *data, int w, int h) +{ + Render_Engine *re; + + printf ("eng_output_tile_size_set called : %dx%d\n", w, h); + re = (Render_Engine *)data; + evas_common_tilebuf_set_tile_size(re->tb, w, h); +} + +static void +eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + //printf ("eng_output_redraws_rect_add called : %d,%d %dx%d\n", x, y, w, h); + re = (Render_Engine *)data; + evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); +} + +static void +eng_output_redraws_rect_del(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + //printf ("eng_output_redraws_rect_del called : %d,%d %dx%d\n", x, y, w, h); + re = (Render_Engine *)data; + evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); +} + +static void +eng_output_redraws_clear(void *data) +{ + Render_Engine *re; + + //printf ("eng_output_redraws_clear called\n"); + re = (Render_Engine *)data; + evas_common_tilebuf_clear(re->tb); +} + +static void * +eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re; + Tilebuf_Rect *rect; + int ux, uy, uw, uh; + + re = (Render_Engine *)data; + /*printf ("eng_output_redraws_next_update_get called : %d,%d %dx%d -- %d,%d %dx%d\n", + *x, *y, *w, *h, *cx, *cy, *cw, *ch);*/ + if (re->end) + { + re->end = 0; + return NULL; + } + if (!re->rects) + { + re->rects = evas_common_tilebuf_get_render_rects(re->tb); + re->cur_rect = EINA_INLIST_GET(re->rects); + } + if (!re->cur_rect) + return NULL; + + rect = (Tilebuf_Rect *)re->cur_rect; + ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h; + re->cur_rect = re->cur_rect->next; + if (!re->cur_rect) + { + evas_common_tilebuf_free_render_rects(re->rects); + re->rects = NULL; + re->end = 1; + } + + *x = *cx = ux; + *y = *cy = uy; + *w = *cw = uw; + *h = *ch = uh; + /*printf ("eng_output_redraws_next_update_get returning : %d,%d %dx%d -- %d,%d %dx%d\n", + *x, *y, *w, *h, *cx, *cy, *cw, *ch);*/ + + return re->rgba_image; +} + +static void +eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) +{ + /* Don't do anything, we'll just coy the whole buffer when it's time to flush */ +} + +static void +eng_output_flush(void *data) +{ + Render_Engine *re; + rsxBuffer *buffer; + int width; + int height; + + //printf ("eng_output_flush called\n"); + re = (Render_Engine *)data; + buffer = &re->buffers[re->currentBuffer]; + width = re->rgba_image->cache_entry.w; + height = re->rgba_image->cache_entry.h; + + /* Wait for the flip before copying the buffer */ + waitFlip (); + + if (re->width == width && + re->height == height) + { + /* DMA the back buffer into the rsx buffer */ + rsxSetTransferImage (re->context, + GCM_TRANSFER_MAIN_TO_LOCAL, + buffer->offset, buffer->width * sizeof(u32), + 0, 0, + re->rgba_image_offset, re->width * sizeof(u32), + 0, 0, re->width, re->height, sizeof(u32)); + } + else + { + gcmTransferScale gcm_scale; + gcmTransferSurface gcm_surface; + + gcm_surface.format = GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8; + gcm_surface.pitch = buffer->width * sizeof(u32); + gcm_surface._pad0[0] = gcm_surface._pad0[1] = 0; + gcm_surface.offset = buffer->offset; + + gcm_scale.interp = GCM_TRANSFER_INTERPOLATOR_LINEAR; + gcm_scale.conversion = GCM_TRANSFER_CONVERSION_TRUNCATE; + gcm_scale.format = GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8; + gcm_scale.origin = GCM_TRANSFER_ORIGIN_CORNER; + gcm_scale.operation = GCM_TRANSFER_OPERATION_SRCCOPY; + gcm_scale.offset = re->rgba_image_offset; + gcm_scale.clipX = 0; + gcm_scale.clipY = 0; + gcm_scale.clipW = re->width; + gcm_scale.clipH = re->height; + gcm_scale.outX = 0; + gcm_scale.outY = 0; + gcm_scale.outW = re->width; + gcm_scale.outH = re->height; + gcm_scale.ratioX = rsxGetFixedSint32 ((float)width / (float)re->width); + gcm_scale.ratioY = rsxGetFixedSint32 ((float)height / (float)re->height); + gcm_scale.inX = 0; + gcm_scale.inY = 0; + gcm_scale.inW = (width & ~1); // Width must be a multiple of 2 + gcm_scale.inH = height; + if (gcm_scale.inW < 2) // Minimum inW value is 2 + gcm_scale.inW = 2; + if (gcm_scale.inW > 2046) // Maximum inW value is 2046 + gcm_scale.inW = 2046; + if (gcm_scale.inH < 1) // Minimum inH value is 1 + gcm_scale.inH = 1; + if (gcm_scale.inH > 2047) // Maximum inW value is 2047 + gcm_scale.inH = 2047; + gcm_scale.pitch = sizeof(u32) * width; + + rsxSetTransferScaleMode (re->context, GCM_TRANSFER_MAIN_TO_LOCAL, GCM_TRANSFER_SURFACE); + rsxSetTransferScaleSurface (re->context, &gcm_scale, &gcm_surface); + } + /* Wait for the DMA to finish */ + flushRSX (re->context); + + /* Flip buffer onto screen */ + flipBuffer (re->context, re->currentBuffer); + re->currentBuffer = (re->currentBuffer + 1) % MAX_BUFFERS; +} + +static void +eng_output_idle_flush(void *data) +{ + Render_Engine *re; + + printf ("eng_output_idle_flush called\n"); + re = (Render_Engine *)data; +} + +static Eina_Bool +eng_canvas_alpha_get(void *data, void *context __UNUSED__) +{ + Render_Engine *re; + + // printf ("eng_output_alpha_get called\n"); + re = (Render_Engine *)data; + return EINA_TRUE; +} + +/* module advertising code */ +static int +module_open(Evas_Module *em) +{ + if (!em) return 0; + /* get whatever engine module we inherit from */ + if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; + _evas_engine_psl1ght_log_dom = eina_log_domain_register + ("evas-psl1ght", EVAS_DEFAULT_LOG_COLOR); + if (_evas_engine_psl1ght_log_dom < 0) + { + EINA_LOG_ERR("Can not create a module log domain."); + return 0; + } + + /* store it for later use */ + func = pfunc; + /* now to override methods */ +#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) + ORD(info); + ORD(info_free); + ORD(setup); + ORD(canvas_alpha_get); + ORD(output_free); + ORD(output_resize); + ORD(output_tile_size_set); + ORD(output_redraws_rect_add); + ORD(output_redraws_rect_del); + ORD(output_redraws_clear); + ORD(output_redraws_next_update_get); + ORD(output_redraws_next_update_push); + ORD(output_flush); + ORD(output_idle_flush); + + /* now advertise out own api */ + em->functions = (void *)(&func); + return 1; +} + +static void +module_close(Evas_Module *em __UNUSED__) +{ + eina_log_domain_unregister(_evas_engine_psl1ght_log_dom); +} + +static Evas_Module_Api evas_modapi = +{ + EVAS_MODULE_API_VERSION, + "psl1ght", + "none", + { + module_open, + module_close + } +}; + +EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, psl1ght); + +#ifndef EVAS_STATIC_BUILD_PSL1GHT +EVAS_EINA_MODULE_DEFINE(engine, psl1ght); +#endif diff --git a/legacy/evas/src/modules/engines/psl1ght/evas_engine.h b/legacy/evas/src/modules/engines/psl1ght/evas_engine.h new file mode 100644 index 0000000000..0ea6cb1d27 --- /dev/null +++ b/legacy/evas/src/modules/engines/psl1ght/evas_engine.h @@ -0,0 +1,30 @@ +#ifndef EVAS_ENGINE_H +#define EVAS_ENGINE_H + +extern int _evas_engine_psl1ght_log_dom; +#ifdef ERR +# undef ERR +#endif +#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_psl1ght_log_dom, __VA_ARGS__) + +#ifdef DBG +# undef DBG +#endif +#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_psl1ght_log_dom, __VA_ARGS__) + +#ifdef INF +# undef INF +#endif +#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_psl1ght_log_dom, __VA_ARGS__) + +#ifdef WRN +# undef WRN +#endif +#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_psl1ght_log_dom, __VA_ARGS__) + +#ifdef CRIT +# undef CRIT +#endif +#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_engine_psl1ght_log_dom, __VA_ARGS__) + +#endif diff --git a/legacy/evas/src/modules/engines/psl1ght/rsxutil.c b/legacy/evas/src/modules/engines/psl1ght/rsxutil.c new file mode 100644 index 0000000000..7567a8c285 --- /dev/null +++ b/legacy/evas/src/modules/engines/psl1ght/rsxutil.c @@ -0,0 +1,275 @@ +/* + * This software is distributed under the terms of the MIT License + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rsxutil.h" + +#define GCM_LABEL_INDEX 255 + +static void +waitRSXIdle(gcmContextData *context); + +static int flipped = FALSE; + +void +waitFlip() +{ + if (flipped) + { + while (gcmGetFlipStatus () != 0) + usleep (200); /* Sleep, to not stress the cpu. */ + gcmResetFlipStatus (); + flipped = FALSE; + } +} + +int +flipBuffer(gcmContextData *context, s32 buffer) +{ + if (gcmSetFlip (context, buffer) == 0) + { + rsxFlushBuffer (context); + // Prevent the RSX from continuing until the flip has finished. + gcmSetWaitFlip (context); + + flipped = TRUE; + return TRUE; + } + return FALSE; +} + +int +makeBuffer(rsxBuffer *buffer, u16 width, u16 height, int id) +{ + int depth = sizeof(u32); + int pitch = depth * width; + int size = depth * width * height; + + buffer->ptr = (uint32_t *)rsxMemalign (64, size); + + if (buffer->ptr == NULL) + goto error; + + if (rsxAddressToOffset (buffer->ptr, &buffer->offset) != 0) + goto error; + + /* Register the display buffer with the RSX */ + if (gcmSetDisplayBuffer (id, buffer->offset, pitch, width, height) != 0) + goto error; + + buffer->width = width; + buffer->height = height; + buffer->id = id; + + return TRUE; + +error: + if (buffer->ptr != NULL) + rsxFree (buffer->ptr); + + return FALSE; +} + +int +copyBuffer(gcmContextData *context, rsxBuffer *source, rsxBuffer *destination) +{ + rsxSetTransferData(context, GCM_TRANSFER_LOCAL_TO_LOCAL, + destination->offset, + destination->width * sizeof(u32), + source->offset, + source->width * sizeof(u32), + source->width * sizeof(u32), + source->height); +} + +int +getResolution(u16 *width, u16 *height) +{ + videoState state; + videoResolution resolution; + + /* Get the state of the display */ + if (videoGetState (0, 0, &state) == 0 && + videoGetResolution (state.displayMode.resolution, &resolution) == 0) + { + if (width) + *width = resolution.width; + if (height) + *height = resolution.height; + + return TRUE; + } + return FALSE; +} + +static u8 +getPreferredResolution(u16 width, u16 height) +{ + videoDeviceInfo info; + videoResolution res; + int area = width * height; + int mode_area; + int min_area_diff = abs (area - (720 * 480)); + int area_diff; + u8 resolution = VIDEO_RESOLUTION_480; + int i; + + videoGetDeviceInfo(0, 0, &info); + + for (i = 0; i < info.availableModeCount; i++) { + videoGetResolution (info.availableModes[i].resolution, &res); + mode_area = res.width * res.height; + area_diff = abs (area - mode_area); + if (area_diff < min_area_diff) + { + min_area_diff = area_diff; + resolution = info.availableModes[i].resolution; + } + } + + return resolution; +} + +int +setResolution(gcmContextData *context, u16 *width, u16 *height) +{ + videoState state; + videoConfiguration vconfig; + videoResolution res; + u8 resolution; + + resolution = getPreferredResolution (*width, *height); + + /* Get the state of the display */ + if (videoGetState (0, 0, &state) != 0) + return FALSE; + + /* Make sure display is enabled */ + if (state.state != 0) + return FALSE; + + if (videoGetResolution (resolution, &res) != 0) + return FALSE; + + /* Configure the buffer format to xRGB */ + memset (&vconfig, 0, sizeof(videoConfiguration)); + vconfig.resolution = resolution; + vconfig.format = VIDEO_BUFFER_FORMAT_XRGB; + vconfig.pitch = res.width * sizeof(u32); + vconfig.aspect = VIDEO_ASPECT_AUTO; + + flushRSX(context); + + if (videoConfigure (0, &vconfig, NULL, 0) != 0) + return FALSE; + + *width = res.width; + *height = res.height; + + return TRUE; +} + +gcmContextData * +initScreen(void *host_addr, u32 size) +{ + gcmContextData *context = NULL; /* Context to keep track of the RSX buffer. */ + videoState state; + videoConfiguration vconfig; + videoResolution res; /* Screen Resolution */ + + /* Initilise Reality, which sets up the command buffer and shared IO memory */ + context = rsxInit (CB_SIZE, size, host_addr); + if (context == NULL) + goto error; + + /* Get the state of the display */ + if (videoGetState (0, 0, &state) != 0) + goto error; + + /* Make sure display is enabled */ + if (state.state != 0) + goto error; + + /* Get the current resolution */ + if (videoGetResolution (state.displayMode.resolution, &res) != 0) + goto error; + + /* Configure the buffer format to xRGB */ + memset (&vconfig, 0, sizeof(videoConfiguration)); + vconfig.resolution = state.displayMode.resolution; + vconfig.format = VIDEO_BUFFER_FORMAT_XRGB; + vconfig.pitch = res.width * sizeof(u32); + vconfig.aspect = state.displayMode.aspect; + + flushRSX(context); + + if (videoConfigure (0, &vconfig, NULL, 0) != 0) + goto error; + + if (videoGetState (0, 0, &state) != 0) + goto error; + + gcmSetFlipMode (GCM_FLIP_VSYNC); // Wait for VSYNC to flip + + gcmResetFlipStatus(); + + return context; + +error: + if (context) + rsxFinish (context, 0); + + return NULL; +} + +void +freeScreen(gcmContextData *context) +{ + rsxFinish (context, 0); +} + +static void +waitFinish(gcmContextData *context, u32 sLabelVal) +{ + rsxSetWriteBackendLabel (context, GCM_LABEL_INDEX, sLabelVal); + + rsxFlushBuffer (context); + + while (*(vu32 *)gcmGetLabelAddress (GCM_LABEL_INDEX) != sLabelVal) + usleep(30); +} + +static void +waitRSXIdle(gcmContextData *context) +{ + static u32 sLabelVal = 1; + + rsxSetWriteBackendLabel (context, GCM_LABEL_INDEX, sLabelVal); + rsxSetWaitLabel (context, GCM_LABEL_INDEX, sLabelVal); + + sLabelVal++; + + waitFinish(context, sLabelVal++); +} + +void +flushRSX(gcmContextData *context) +{ + if (flipped) + waitFlip (); + waitRSXIdle(context); +} + diff --git a/legacy/evas/src/modules/engines/psl1ght/rsxutil.h b/legacy/evas/src/modules/engines/psl1ght/rsxutil.h new file mode 100644 index 0000000000..838a751b86 --- /dev/null +++ b/legacy/evas/src/modules/engines/psl1ght/rsxutil.h @@ -0,0 +1,43 @@ +/* + * This software is distributed under the terms of the MIT License + */ + +#ifndef __RSXUTIL_H__ +#define __RSXUTIL_H__ + +#include +#include + +#define CB_SIZE 0x100000 +#define HOST_SIZE (32 * 1024 * 1024) + +typedef struct +{ + int height; + int width; + int id; + uint32_t *ptr; + // Internal stuff + uint32_t offset; +} rsxBuffer; + +/* Initilize the RSX properly. Returns NULL on error */ +gcmContextData *initScreen(void *host_addr, u32 size); +/* Block the PPU thread untill the previous flip operation has finished. */ +void waitFlip(void); +/* Flip a buffer onto the screen. Returns TRUE on success */ +int flipBuffer(gcmContextData *context, s32 buffer); +/* Create a buffer to draw into and assign it to @id. Returns NULL on error */ +int makeBuffer(rsxBuffer *buffer, u16 width, u16 height, int id); +/* Copy the contents of a buffer to another buffer */ +int copyBuffer(gcmContextData *context, rsxBuffer *source, rsxBuffer *destination); +/* Get current screen resolution. returns TRUE on success */ +int getResolution(u16 *width, u16 *height); +/* Set screen resolution to closest matching and. returns TRUE on success */ +int setResolution(gcmContextData *context, u16 *width, u16 *height); +/* Initilize the RSX properly. Returns NULL on error */ +void freeScreen(gcmContextData *context); +/* Flush the RSX pipeline (any commands and wait for flip) */ +void flushRSX(gcmContextData *context); + +#endif /* __RSXUTIL_H__ */