Search
lxdream.org :: lxdream :: r1275:83b15705cdde
lxdream 0.9.1
released Jun 29
Download Now
changeset1275:83b15705cdde
parent1274:4dff831f1a2e
child1276:e20a69167093
authornkeynes
dateTue Mar 20 08:29:38 2012 +1000 (7 years ago)
More android WIP
- Implement onPause/onResume (although resume is not actually working yet)
- Implement BGRA => RGBA texture conversion (BGRA doesn't seem to work on the TFP)

Boot swirl is now displayed, albeit depth buffering seems to be broken.
android/src/org/lxdream/Dreamcast.java
android/src/org/lxdream/LxdreamActivity.java
src/drivers/video_egl.c
src/gui_android.c
src/pvr2/glrender.c
src/pvr2/glutil.c
src/pvr2/glutil.h
src/pvr2/pvr2.h
src/pvr2/texcache.c
1.1 --- a/android/src/org/lxdream/Dreamcast.java Tue Mar 20 08:18:22 2012 +1000
1.2 +++ b/android/src/org/lxdream/Dreamcast.java Tue Mar 20 08:29:38 2012 +1000
1.3 @@ -33,6 +33,9 @@
1.4 public static native boolean isRunnable();
1.5 public static native boolean isRunning();
1.6
1.7 + public static native void onAppPause();
1.8 + public static native void onAppResume();
1.9 +
1.10 /* GD-Rom */
1.11 public static native boolean mount( String filename );
1.12 public static native void unmount();
2.1 --- a/android/src/org/lxdream/LxdreamActivity.java Tue Mar 20 08:18:22 2012 +1000
2.2 +++ b/android/src/org/lxdream/LxdreamActivity.java Tue Mar 20 08:29:38 2012 +1000
2.3 @@ -63,12 +63,13 @@
2.4
2.5 @Override
2.6 protected void onPause() {
2.7 + Dreamcast.onAppPause();
2.8 super.onPause();
2.9 - Dreamcast.stop();
2.10 }
2.11
2.12 @Override
2.13 protected void onResume() {
2.14 + Dreamcast.onAppResume();
2.15 super.onResume();
2.16 }
2.17
3.1 --- a/src/drivers/video_egl.c Tue Mar 20 08:18:22 2012 +1000
3.2 +++ b/src/drivers/video_egl.c Tue Mar 20 08:29:38 2012 +1000
3.3 @@ -76,7 +76,7 @@
3.4 EGL_CONTEXT_CLIENT_VERSION, 2,
3.5 EGL_NONE, EGL_NONE };
3.6
3.7 -static EGLDisplay display;
3.8 +static EGLDisplay display = EGL_NO_DISPLAY;
3.9 static EGLContext context = EGL_NO_CONTEXT;
3.10 static EGLSurface surface = EGL_NO_SURFACE;
3.11 static gboolean fbo_created = FALSE;
3.12 @@ -117,6 +117,7 @@
3.13 }
3.14
3.15 if( eglMakeCurrent( display, surface, surface, context ) == EGL_FALSE ) {
3.16 + logEGLError( "Unable to make EGL context current" );
3.17 video_egl_clear_window();
3.18 return FALSE;
3.19 }
3.20 @@ -129,13 +130,14 @@
3.21 fbo_created = TRUE;
3.22 gl_set_video_size(width, height, 0);
3.23 pvr2_setup_gl_context();
3.24 - INFO( "Initialised EGL %d.%d\n", major, minor );
3.25 + INFO( "Initialised EGL %d.%d", major, minor );
3.26 return TRUE;
3.27 }
3.28
3.29 void video_egl_clear_window()
3.30 {
3.31 if( fbo_created ) {
3.32 + pvr2_shutdown_gl_context();
3.33 gl_fbo_shutdown();
3.34 fbo_created = FALSE;
3.35 }
3.36 @@ -148,7 +150,11 @@
3.37 eglDestroyContext(display, context);
3.38 context = EGL_NO_CONTEXT;
3.39 }
3.40 - eglTerminate(display);
3.41 + if( display != EGL_NO_DISPLAY ) {
3.42 + eglTerminate(display);
3.43 + display = EGL_NO_DISPLAY;
3.44 + }
3.45 + INFO( "Terminated EGL" );
3.46 }
3.47
3.48 static void video_egl_swap_buffers()
4.1 --- a/src/gui_android.c Tue Mar 20 08:18:22 2012 +1000
4.2 +++ b/src/gui_android.c Tue Mar 20 08:29:38 2012 +1000
4.3 @@ -45,7 +45,7 @@
4.4 int width, height, format;
4.5 };
4.6
4.7 -static struct surface_info current_surface;
4.8 +static struct surface_info current_surface = { NULL, 0, 0, 0 };
4.9 static const char *appHome = NULL;
4.10
4.11 /**
4.12 @@ -89,14 +89,30 @@
4.13 return 0;
4.14 }
4.15
4.16 +int android_do_pause(void *data)
4.17 +{
4.18 + if( dreamcast_is_running() ) {
4.19 + dreamcast_stop();
4.20 + }
4.21 + video_egl_clear_window();
4.22 + INFO( "Paused" );
4.23 + return 0;
4.24 +}
4.25 +
4.26 +int android_do_resume(void *data)
4.27 +{
4.28 + struct surface_info *surface = (struct surface_info *)data;
4.29 + if( surface->win != NULL )
4.30 + video_egl_set_window(surface->win, surface->width, surface->height, surface->format);
4.31 + INFO( "Resumed" );
4.32 + return 0;
4.33 +}
4.34 +
4.35 int android_clear_surface(void *data)
4.36 {
4.37 struct surface_info *surface = (struct surface_info *)data;
4.38
4.39 - if( dreamcast_is_running() ) {
4.40 - dreamcast_stop();
4.41 - }
4.42 - video_egl_clear_window();
4.43 + android_do_pause(data); /* If we haven't already stopped, stop now */
4.44 ANativeWindow_release(surface->win);
4.45 surface->win = NULL;
4.46 return 0;
4.47 @@ -287,6 +303,17 @@
4.48 tqueue_send_message( android_callback_wrapper, dreamcast_stop );
4.49 }
4.50
4.51 +JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_onAppPause(JNIEnv * env, jclass obj)
4.52 +{
4.53 + /* Need to make sure this completely shuts down before we return */
4.54 + tqueue_send_message( android_do_pause, &current_surface );
4.55 +}
4.56 +
4.57 +JNIEXPORT void JNICALL Java_org_lxdream_Dreamcast_onAppResume(JNIEnv * env, jclass obj)
4.58 +{
4.59 + tqueue_post_message( android_do_resume, &current_surface );
4.60 +}
4.61 +
4.62 JNIEXPORT jboolean JNICALL Java_org_lxdream_Dreamcast_isRunning(JNIEnv *env, jclass obj)
4.63 {
4.64 return dreamcast_is_running();
4.65 @@ -322,6 +349,7 @@
4.66 } else {
4.67 current_surface.format = COLFMT_RGB888;
4.68 }
4.69 + INFO( "Setting surface" );
4.70 tqueue_post_message( android_set_surface, &current_surface );
4.71 }
4.72
5.1 --- a/src/pvr2/glrender.c Tue Mar 20 08:18:22 2012 +1000
5.2 +++ b/src/pvr2/glrender.c Tue Mar 20 08:29:38 2012 +1000
5.3 @@ -150,6 +150,11 @@
5.4 glClearStencil(0);
5.5 }
5.6
5.7 +void pvr2_shutdown_gl_context()
5.8 +{
5.9 + texcache_gl_shutdown();
5.10 +}
5.11 +
5.12 /**
5.13 * Setup the basic context that's shared between normal and modified modes -
5.14 * depth, culling
6.1 --- a/src/pvr2/glutil.c Tue Mar 20 08:18:22 2012 +1000
6.2 +++ b/src/pvr2/glutil.c Tue Mar 20 08:29:38 2012 +1000
6.3 @@ -49,6 +49,14 @@
6.4 return isGLExtensionSupported("GL_ARB_texture_mirrored_repeat");
6.5 }
6.6
6.7 +gboolean isGLBGRATextureSupported()
6.8 +{
6.9 + /* Note: e.g. Tegra 3 reports GL_EXT_bgra, but it doesn't actually work.
6.10 + * Need to check this with NVIDIA, in meantime assume GLES2 doesn't have
6.11 + * BGRA support */
6.12 + return !isOpenGLES2() && isGLExtensionSupported("GL_EXT_bgra");
6.13 +}
6.14 +
6.15
6.16 gboolean isGLShaderSupported()
6.17 {
7.1 --- a/src/pvr2/glutil.h Tue Mar 20 08:18:22 2012 +1000
7.2 +++ b/src/pvr2/glutil.h Tue Mar 20 08:29:38 2012 +1000
7.3 @@ -56,6 +56,7 @@
7.4 gboolean isGLPixelBufferSupported();
7.5 gboolean isGLMultitextureSupported();
7.6 gboolean isGLMirroredTextureSupported();
7.7 +gboolean isGLBGRATextureSupported();
7.8 gboolean isGLShaderSupported();
7.9 GLint glGetMaxColourAttachments();
7.10
8.1 --- a/src/pvr2/pvr2.h Tue Mar 20 08:18:22 2012 +1000
8.2 +++ b/src/pvr2/pvr2.h Tue Mar 20 08:29:38 2012 +1000
8.3 @@ -279,6 +279,8 @@
8.4 */
8.5 void pvr2_setup_gl_context();
8.6
8.7 +void pvr2_shutdown_gl_context();
8.8 +
8.9 void render_backplane( uint32_t *polygon, uint32_t width, uint32_t height, uint32_t mode );
8.10
8.11 void render_autosort_tile( pvraddr_t tile_entry, int render_mode );
8.12 @@ -320,10 +322,10 @@
8.13
8.14 /**
8.15 * Flush all textures and delete. The cache will be non-functional until
8.16 - * the next call to texcache_init(). This would typically be done if
8.17 + * the next call to texcache_gl_init(). This would typically be done if
8.18 * switching GL targets.
8.19 */
8.20 -void texcache_shutdown( void );
8.21 +void texcache_gl_shutdown( void );
8.22
8.23 /**
8.24 * Flush (ie free) all textures.
9.1 --- a/src/pvr2/texcache.c Tue Mar 20 08:18:22 2012 +1000
9.2 +++ b/src/pvr2/texcache.c Tue Mar 20 08:29:38 2012 +1000
9.3 @@ -61,6 +61,7 @@
9.4 static uint32_t texcache_palette_mode;
9.5 static uint32_t texcache_stride_width;
9.6 static gboolean texcache_have_palette_shader;
9.7 +static gboolean texcache_have_bgra;
9.8 static gboolean texcache_palette_valid;
9.9 static GLuint texcache_palette_texid;
9.10
9.11 @@ -85,41 +86,10 @@
9.12 texcache_stride_width = 0;
9.13 }
9.14
9.15 -/**
9.16 - * Setup the initial texture ids (must be called after the GL context is
9.17 - * prepared)
9.18 - */
9.19 -void texcache_gl_init( )
9.20 -{
9.21 - int i;
9.22 - GLuint texids[MAX_TEXTURES];
9.23 -
9.24 - if( display_driver->capabilities.has_sl ) {
9.25 - texcache_have_palette_shader = TRUE;
9.26 - texcache_palette_valid = FALSE;
9.27 - glGenTextures(1, &texcache_palette_texid );
9.28 -
9.29 - /* Bind the texture and set the params */
9.30 - glActiveTexture(GL_TEXTURE1);
9.31 - glBindTexture(GL_TEXTURE_2D, texcache_palette_texid);
9.32 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9.33 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9.34 - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
9.35 - glActiveTexture(GL_TEXTURE0);
9.36 -
9.37 - } else {
9.38 - texcache_have_palette_shader = FALSE;
9.39 - }
9.40 -
9.41 - glGenTextures( MAX_TEXTURES, texids );
9.42 - for( i=0; i<MAX_TEXTURES; i++ ) {
9.43 - texcache_active_list[i].texture_id = texids[i];
9.44 - }
9.45 -}
9.46
9.47 void texcache_release_render_buffer( render_buffer_t buffer )
9.48 {
9.49 - if( !buffer->flushed )
9.50 + if( !buffer->flushed )
9.51 pvr2_render_buffer_copy_to_sh4(buffer);
9.52 pvr2_destroy_render_buffer(buffer);
9.53 }
9.54 @@ -148,21 +118,59 @@
9.55 }
9.56
9.57 /**
9.58 + * Setup the initial texture ids (must be called after the GL context is
9.59 + * prepared)
9.60 + */
9.61 +void texcache_gl_init( )
9.62 +{
9.63 + int i;
9.64 + GLuint texids[MAX_TEXTURES];
9.65 +
9.66 + if( display_driver->capabilities.has_sl ) {
9.67 + texcache_have_palette_shader = TRUE;
9.68 + texcache_palette_valid = FALSE;
9.69 + glGenTextures(1, &texcache_palette_texid );
9.70 +
9.71 + /* Bind the texture and set the params */
9.72 + glActiveTexture(GL_TEXTURE1);
9.73 + glBindTexture(GL_TEXTURE_2D, texcache_palette_texid);
9.74 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9.75 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9.76 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
9.77 + glActiveTexture(GL_TEXTURE0);
9.78 +
9.79 + } else {
9.80 + texcache_have_palette_shader = FALSE;
9.81 + }
9.82 + texcache_have_bgra = isGLBGRATextureSupported();
9.83 +
9.84 + glGenTextures( MAX_TEXTURES, texids );
9.85 + for( i=0; i<MAX_TEXTURES; i++ ) {
9.86 + texcache_active_list[i].texture_id = texids[i];
9.87 + }
9.88 + INFO( "Texcache initialized (%s, %s)", (texcache_have_palette_shader ? "Palette shader" : "No palette support"),
9.89 + (texcache_have_bgra ? "BGRA" : "RGBA") );
9.90 +}
9.91 +
9.92 +/**
9.93 * Flush all textures and delete. The cache will be non-functional until
9.94 - * the next call to texcache_init(). This would typically be done if
9.95 + * the next call to texcache_gl_init(). This would typically be done if
9.96 * switching GL targets.
9.97 */
9.98 -void texcache_shutdown( )
9.99 +void texcache_gl_shutdown( )
9.100 {
9.101 GLuint texids[MAX_TEXTURES];
9.102 int i;
9.103 texcache_flush();
9.104
9.105 - if( texcache_have_palette_shader )
9.106 + if( texcache_have_palette_shader ) {
9.107 glDeleteTextures( 1, &texcache_palette_texid );
9.108 + texcache_palette_texid = -1;
9.109 + }
9.110
9.111 for( i=0; i<MAX_TEXTURES; i++ ) {
9.112 texids[i] = texcache_active_list[i].texture_id;
9.113 + texcache_active_list[i].texture_id = -1;
9.114 }
9.115 glDeleteTextures( MAX_TEXTURES, texids );
9.116 }
9.117 @@ -244,6 +252,73 @@
9.118 }
9.119
9.120 /**
9.121 + * Convert BGRA data in buffer to RGBA format (for systems that don't natively
9.122 + * support BGRA).
9.123 + * @return converted format type
9.124 + * @param data BGRA pixel data
9.125 + * @param nPixels total number of pixels (width*height)
9.126 + * @param glFormatType GL format of source data. One of
9.127 + * GL_UNSIGNED_SHORT_1_5_5_5_REV, GL_UNSIGNED_SHORT_4_4_4_4_REV, or GL_UNSIGNED_BYTE
9.128 + */
9.129 +static int bgra_to_rgba( unsigned char *data, unsigned nPixels, int glFormatType )
9.130 +{
9.131 + unsigned i;
9.132 + switch( glFormatType ) {
9.133 + case GL_UNSIGNED_SHORT_1_5_5_5_REV: {
9.134 + uint16_t *p = (uint16_t *)data;
9.135 + uint16_t *end = p + nPixels;
9.136 + while( p != end ) {
9.137 + uint16_t v = *p;
9.138 + *p = (v >> 15) | (v<<1);
9.139 + p++;
9.140 + }
9.141 + return GL_UNSIGNED_SHORT_5_5_5_1;
9.142 + }
9.143 + case GL_UNSIGNED_SHORT_4_4_4_4_REV: { /* ARGB => RGBA */
9.144 + uint16_t *p = (uint16_t *)data;
9.145 + uint16_t *end = p + nPixels;
9.146 + while( p != end ) {
9.147 + uint16_t v = *p;
9.148 + *p = (v >> 12) | (v<<4);
9.149 + p++;
9.150 + }
9.151 + return GL_UNSIGNED_SHORT_4_4_4_4;
9.152 + }
9.153 + case GL_UNSIGNED_BYTE: { /* ARGB => ABGR */
9.154 + uint32_t *p = (uint32_t *)data;
9.155 + uint32_t *end = p + nPixels;
9.156 + while( p != end ) {
9.157 + uint32_t v = *p;
9.158 + *p = (v&0xFF000000) | ((v<<16) & 0x00FF0000) | (v & 0x0000FF00) | ((v>>16) & 0x000000FF);
9.159 + p++;
9.160 + }
9.161 + return GL_UNSIGNED_BYTE;
9.162 + }
9.163 + default:
9.164 + assert( 0 && "Unsupported BGRA format" );
9.165 + return glFormatType;
9.166 + }
9.167 +}
9.168 +
9.169 +/**
9.170 + * Install the image data in the currently bound 2D texture.
9.171 + * May modify the buffered data if needed to make the texture compatible with
9.172 + * the GL.
9.173 + */
9.174 +static void texcache_load_image_2D( int level, GLint intFormat, int width, int height, GLint format, GLint type, unsigned char *data )
9.175 +{
9.176 + if( format == GL_BGRA && !texcache_have_bgra ) {
9.177 + GLint rgbaType = bgra_to_rgba( data, width*height, type );
9.178 + glTexImage2D( GL_TEXTURE_2D, level, intFormat, width, height, 0, GL_RGBA, rgbaType,
9.179 + data );
9.180 + } else {
9.181 + glTexImage2D( GL_TEXTURE_2D, level, intFormat, width, height, 0, format, type,
9.182 + data );
9.183 + }
9.184 +
9.185 +}
9.186 +
9.187 +/**
9.188 * Load the palette into 4 textures of 256 entries each. This mirrors the
9.189 * banking done by the PVR2 for 8-bit textures, and also ensures that we
9.190 * can use 8-bit paletted textures ourselves.
9.191 @@ -254,7 +329,7 @@
9.192 unsigned i;
9.193 int bpp = 2;
9.194 uint32_t *palette = (uint32_t *)mmio_region_PVR2PAL.mem;
9.195 - uint16_t packed_palette[1024];
9.196 + char buf[4096];
9.197 char *data = (char *)palette;
9.198
9.199 switch( texcache_palette_mode ) {
9.200 @@ -280,13 +355,21 @@
9.201 break; /* Can't happen */
9.202 }
9.203
9.204 -
9.205 if( bpp == 2 ) {
9.206 + data = buf;
9.207 + uint16_t *packed_palette = (uint16_t *)buf;
9.208 for( i=0; i<1024; i++ ) {
9.209 packed_palette[i] = (uint16_t)palette[i];
9.210 }
9.211 - data = (char *)packed_palette;
9.212 -
9.213 + if( !texcache_have_bgra && format == GL_BGRA ) {
9.214 + type = bgra_to_rgba(data, 1024, type);
9.215 + format = GL_RGBA;
9.216 + }
9.217 + } else if( !texcache_have_bgra && format == GL_BGRA ) { /* bpp == 4 */
9.218 + data = buf;
9.219 + memcpy( buf, palette, 4096 );
9.220 + type = bgra_to_rgba(buf, 1024, type);
9.221 + format = GL_RGBA;
9.222 }
9.223
9.224 glActiveTexture(GL_TEXTURE1);
9.225 @@ -448,7 +531,7 @@
9.226 if( r > 255 ) { r = 255; } else if( r < 0 ) { r = 0; }
9.227 if( g > 255 ) { g = 255; } else if( g < 0 ) { g = 0; }
9.228 if( b > 255 ) { b = 255; } else if( b < 0 ) { b = 0; }
9.229 - return 0xFF000000 | (r<<16) | (g<<8) | (b);
9.230 + return 0xFF000000 | (b<<16) | (g<<8) | (r);
9.231 }
9.232
9.233
9.234 @@ -555,10 +638,10 @@
9.235 break;
9.236 case PVR2_TEX_FORMAT_YUV422:
9.237 /* YUV422 isn't directly supported by most implementations, so decode
9.238 - * it to a (reasonably) standard ARGB32.
9.239 + * it to a (reasonably) standard RGBA8.
9.240 */
9.241 bpp_shift = 2;
9.242 - format = GL_BGRA;
9.243 + format = GL_RGBA;
9.244 type = GL_UNSIGNED_BYTE;
9.245 break;
9.246 case PVR2_TEX_FORMAT_BUMPMAP:
9.247 @@ -577,7 +660,7 @@
9.248 } else {
9.249 pvr2_vram64_read_stride( data, width<<bpp_shift, texture_addr, texcache_stride_width<<bpp_shift, height );
9.250 }
9.251 - glTexImage2D( GL_TEXTURE_2D, 0, intFormat, width, height, 0, format, type, data );
9.252 + texcache_load_image_2D( 0, intFormat, width, height, format, type, data );
9.253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
9.254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
9.255 return;
9.256 @@ -678,11 +761,10 @@
9.257
9.258 /* Pass to GL */
9.259 if( level == last_level && level != 0 ) { /* 1x1 stored within a 2x2 */
9.260 - glTexImage2D( GL_TEXTURE_2D, level, intFormat, 1, 1, 0, format, type,
9.261 + texcache_load_image_2D( level, intFormat, 1, 1, format, type,
9.262 data + (3 << bpp_shift) );
9.263 } else {
9.264 - glTexImage2D( GL_TEXTURE_2D, level, intFormat, mip_width, mip_height, 0, format, type,
9.265 - data );
9.266 + texcache_load_image_2D( level, intFormat, mip_width, mip_height, format, type, data );
9.267 if( mip_width > 2 ) {
9.268 mip_width >>= 1;
9.269 mip_height >>= 1;
9.270 @@ -780,7 +862,10 @@
9.271 unsigned height = POLY2_TEX_HEIGHT(poly2_word);
9.272
9.273 glBindTexture( GL_TEXTURE_2D, texcache_active_list[slot].texture_id );
9.274 + glGetError();
9.275 texcache_load_texture( texture_addr, width, height, texture_word );
9.276 + INFO( "Loaded texture %d: %x %dx%d %x (%x)", texcache_active_list[slot].texture_id, texture_addr, width, height, texture_word,
9.277 + glGetError() );
9.278
9.279 /* Set texture parameters from the poly2 word */
9.280 if( POLY2_TEX_CLAMP_U(poly2_word) ) {
.