Support for querying video surface pixles in SDL 1.2 HW mode - it's VERY slow

This commit is contained in:
pelya
2010-11-02 15:38:45 +02:00
parent 9a7efcffc0
commit 123f2c14df
4 changed files with 52 additions and 8 deletions

View File

@@ -2,7 +2,7 @@
KEYSTORE=~/.ssh/android.keystore
ALIAS=pelya
APPS_SKIP="src jooleem_0.1.4 lbreakout2 glxgears atari800"
APPS_SKIP="src jooleem_0.1.4 lbreakout2 glxgears atari800 scummvm"
mkdir -p apk

View File

@@ -115,6 +115,7 @@ public class MainActivity extends Activity {
if( Parent._tv == null )
{
Parent._tv = new TextView(Parent);
Parent._tv.setMaxLines(1);
Parent._tv.setText(R.string.init);
Parent._layout2.addView(Parent._tv);
}

View File

@@ -300,6 +300,7 @@ SDL_Surface *ANDROID_SetVideoMode(_THIS, SDL_Surface *current,
SDL_memset(current->pixels, 0, width * height * ANDROID_BYTESPERPIXEL);
current->hwdata = (struct private_hwdata *)SDL_CreateTexture(SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STATIC, width, height);
if( !current->hwdata ) {
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate texture for SDL_CurrentVideoSurface");
SDL_free(current->pixels);
current->pixels = NULL;
SDL_OutOfMemory();
@@ -480,9 +481,49 @@ static int ANDROID_LockHWSurface(_THIS, SDL_Surface *surface)
{
if( surface == SDL_CurrentVideoSurface )
{
return -1; // Do not allow that, we're HW accelerated
// Copy pixels from pixelbuffer to video surface - this is slow!
Uint16 * row = NULL;
int fakeH = SDL_ANDROID_sFakeWindowHeight, fakeW = SDL_ANDROID_sFakeWindowWidth;
int realH = SDL_ANDROID_sWindowHeight, realW = SDL_ANDROID_sWindowWidth;
int x, y;
if( ! SDL_CurrentVideoSurface->pixels )
{
glPixelStorei(GL_PACK_ALIGNMENT, 1);
SDL_CurrentVideoSurface->pixels = SDL_malloc(SDL_ANDROID_sFakeWindowWidth * SDL_ANDROID_sFakeWindowHeight * ANDROID_BYTESPERPIXEL);
if ( ! SDL_CurrentVideoSurface->pixels ) {
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate buffer for SDL_CurrentVideoSurface");
SDL_SetError("Couldn't allocate buffer for SDL_CurrentVideoSurface");
return(-1);
}
}
if( ! SDL_CurrentVideoSurface->hwdata )
{
SDL_CurrentVideoSurface->hwdata = (struct private_hwdata *)SDL_CreateTexture(SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STATIC, SDL_ANDROID_sFakeWindowWidth, SDL_ANDROID_sFakeWindowHeight);
if( !SDL_CurrentVideoSurface->hwdata ) {
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate texture for SDL_CurrentVideoSurface");
SDL_OutOfMemory();
return(-1);
}
// Register main video texture to be recreated when needed
HwSurfaceCount++;
HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) );
HwSurfaceList[HwSurfaceCount-1] = SDL_CurrentVideoSurface;
DEBUGOUT("ANDROID_SetVideoMode() HwSurfaceCount %d HwSurfaceList %p", HwSurfaceCount, HwSurfaceList);
}
row = SDL_stack_alloc(Uint16, SDL_ANDROID_sWindowWidth);
for(y=0; y<fakeH; y++)
{
glReadPixels(0, realH - 1 - (realH * y / fakeH),
realW, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, row);
for(x=0; x<fakeW; x++)
((Uint16 *)SDL_CurrentVideoSurface->pixels)[ fakeW * y + x ] = row[ x * fakeW / realW ];
}
SDL_stack_free(row);
}
if( !surface->hwdata )
return(-1);
@@ -520,7 +561,7 @@ static void ANDROID_UnlockHWSurface(_THIS, SDL_Surface *surface)
if( surface->format->Amask )
hwformat = SDL_PIXELFORMAT_RGBA4444;
if( surface == SDL_CurrentVideoSurface ) // Special case - we're restoring GL video context
if( surface == SDL_CurrentVideoSurface ) // Special case
hwformat = SDL_PIXELFORMAT_RGB565;
/* Allocate the new pixel format for the screen */
@@ -594,6 +635,9 @@ static void ANDROID_UnlockHWSurface(_THIS, SDL_Surface *surface)
rect.w = surface->w;
rect.h = surface->h;
SDL_UpdateTexture((struct SDL_Texture *)surface->hwdata, &rect, converted->pixels, converted->pitch);
if( surface == SDL_CurrentVideoSurface ) // Special case
SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, NULL, NULL);
if( converted != surface )
SDL_FreeSurface(converted);
@@ -691,7 +735,7 @@ static int ANDROID_FlipHWSurface(_THIS, SDL_Surface *surface)
{
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROID_FlipHWSurface()");
if( SDL_CurrentVideoSurface->hwdata && SDL_CurrentVideoSurface->pixels )
if( SDL_CurrentVideoSurface->hwdata && SDL_CurrentVideoSurface->pixels && ! ( SDL_CurrentVideoSurface->flags & SDL_HWSURFACE ) )
{
SDL_Rect rect;
rect.x = 0;

View File

@@ -86,12 +86,11 @@ SDL_FreeSurface(sprite);
// Blit it in HW-accelerated way
SDL_BlitSurface(hwSprite, sourceRect, SDL_GetVideoSurface(), &targetRect);
// Wrong, blitting SW surfaces to screen not supported
// Supported, but VERY slow (slower than blitting in SW mode)
SDL_BlitSurface(sprite, sourceRect, SDL_GetVideoSurface(), &targetRect);
// Wrong, copying from video surface not supported
// Supported, but VERY slow (use in cases where you need to take a screenshot)
SDL_BlitSurface(SDL_GetVideoSurface(), sourceRect, sprite, &targetRect);
// In the future I may add implementation to read screen buffer with glReadPixels(), however it will be slow (okay for screenshots).
To compile your own app, put your app sources into project/jni/application dir (or create symlink to them),
and change symlink "src" to point to your app: