From 1af7b56349e593b77fd915d6674e6dc63110e741 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 18 Mar 2015 01:39:20 -0700 Subject: [PATCH] SDL: Use pixman for software scaling --- src/platform/sdl/CMakeLists.txt | 9 ++++++- src/platform/sdl/main.h | 9 +++++++ src/platform/sdl/sw-sdl.c | 48 ++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 7d4d58125..63266688d 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -17,6 +17,7 @@ if(SDL_VERSION EQUAL "1.2" OR NOT SDL2_FOUND) find_package(SDL 1.2) set(SDL_VERSION "1.2" PARENT_SCOPE) set(SDL_VERSION_DEBIAN "1.2debian") + set(USE_PIXMAN ON) endif() if (NOT SDL2_FOUND AND NOT SDL_FOUND) @@ -24,10 +25,16 @@ if (NOT SDL2_FOUND AND NOT SDL_FOUND) return() endif() +find_feature(USE_PIXMAN "pixman-1") +if(USE_PIXMAN) + add_definitions(-DUSE_PIXMAN) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libpixman-1.0" PARENT_SCOPE) +endif() + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libsdl${SDL_VERSION_DEBIAN}" PARENT_SCOPE) file(GLOB PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sdl-*.c) -set(PLATFORM_LIBRARY ${SDL_LIBRARY} ${SDLMAIN_LIBRARY}) +set(PLATFORM_LIBRARY ${SDL_LIBRARY} ${SDLMAIN_LIBRARY} ${PIXMAN-1_LIBRARIES}) include_directories(${CMAKE_SOURCE_DIR}/src/platform/sdl ${SDL_INCLUDE_DIR}) set(MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/main.c) diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index c62f3bb28..45bea052b 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -31,6 +31,10 @@ #pragma GCC diagnostic pop #endif +#ifdef USE_PIXMAN +#include +#endif + struct SDLSoftwareRenderer { struct GBAVideoSoftwareRenderer d; struct GBASDLAudio audio; @@ -55,6 +59,11 @@ struct SDLSoftwareRenderer { GLuint tex; #endif +#ifdef USE_PIXMAN + pixman_image_t* pix; + pixman_image_t* screenpix; +#endif + #ifdef BUILD_RASPI EGLDisplay display; EGLSurface surface; diff --git a/src/platform/sdl/sw-sdl.c b/src/platform/sdl/sw-sdl.c index e863a53f0..e147c1651 100644 --- a/src/platform/sdl/sw-sdl.c +++ b/src/platform/sdl/sw-sdl.c @@ -40,14 +40,32 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) { if (renderer->ratio == 1) { renderer->d.outputBuffer = surface->pixels; -#ifdef COLOR_16_BIT - renderer->d.outputBufferStride = surface->pitch / 2; -#else - renderer->d.outputBufferStride = surface->pitch / 4; -#endif + renderer->d.outputBufferStride = surface->pitch / BYTES_PER_PIXEL; } else { - renderer->d.outputBuffer = malloc(240 * 160 * BYTES_PER_PIXEL); - renderer->d.outputBufferStride = 240; +#ifdef USE_PIXMAN + renderer->d.outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); + renderer->d.outputBufferStride = VIDEO_HORIZONTAL_PIXELS; +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + pixman_format_code_t format = PIXMAN_r5g6b5; +#else + pixman_format_code_t format = PIXMAN_x1b5g5r5; +#endif +#else + pixman_format_code_t format = PIXMAN_x8b8g8r8; +#endif + renderer->pix = pixman_image_create_bits(format, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, + renderer->d.outputBuffer, renderer->d.outputBufferStride * BYTES_PER_PIXEL); + renderer->screenpix = pixman_image_create_bits(format, renderer->viewportWidth, renderer->viewportHeight, surface->pixels, surface->pitch); + + pixman_transform_t transform; + pixman_transform_init_identity(&transform); + pixman_transform_scale(0, &transform, pixman_int_to_fixed(renderer->ratio), pixman_int_to_fixed(renderer->ratio)); + pixman_image_set_transform(renderer->pix, &transform); + pixman_image_set_filter(renderer->pix, PIXMAN_FILTER_NEAREST, 0, 0); +#else + return false; +#endif } #endif @@ -72,6 +90,13 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render SDL_RenderPresent(renderer->sdlRenderer); SDL_LockTexture(renderer->tex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride); renderer->d.outputBufferStride /= BYTES_PER_PIXEL; +#else +#ifdef USE_PIXMAN + if (renderer->ratio > 1) { + pixman_image_composite32(PIXMAN_OP_SRC, renderer->pix, 0, renderer->screenpix, + 0, 0, 0, 0, 0, 0, + renderer->viewportWidth, renderer->viewportHeight); + } #else switch (renderer->ratio) { #if defined(__ARM_NEON) && COLOR_16_BIT @@ -87,6 +112,7 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render default: abort(); } +#endif SDL_UnlockSurface(surface); SDL_Flip(surface); SDL_LockSurface(surface); @@ -98,4 +124,12 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) { UNUSED(renderer); +#if !SDL_VERSION_ATLEAST(2, 0, 0) + SDL_Surface* surface = SDL_GetVideoSurface(); + SDL_UnlockSurface(surface); +#ifdef USE_PIXMAN + pixman_image_unref(renderer->pix); + pixman_image_unref(renderer->screenpix); +#endif +#endif }