src/video/mir/SDL_mirframebuffer.c
changeset 8153 3e43c73ac79b
child 8154 ea6b25de67b6
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/mir/SDL_mirframebuffer.c	Sun Feb 02 23:41:46 2014 -0500
     1.3 @@ -0,0 +1,146 @@
     1.4 +/*
     1.5 +  Simple DirectMedia Layer
     1.6 +  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     1.7 +
     1.8 +  This software is provided 'as-is', without any express or implied
     1.9 +  warranty.  In no event will the authors be held liable for any damages
    1.10 +  arising from the use of this software.
    1.11 +
    1.12 +  Permission is granted to anyone to use this software for any purpose,
    1.13 +  including commercial applications, and to alter it and redistribute it
    1.14 +  freely, subject to the following restrictions:
    1.15 +
    1.16 +  1. The origin of this software must not be misrepresented; you must not
    1.17 +     claim that you wrote the original software. If you use this software
    1.18 +     in a product, an acknowledgment in the product documentation would be
    1.19 +     appreciated but is not required.
    1.20 +  2. Altered source versions must be plainly marked as such, and must not be
    1.21 +     misrepresented as being the original software.
    1.22 +  3. This notice may not be removed or altered from any source distribution.
    1.23 +*/
    1.24 +
    1.25 +/*
    1.26 +  Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
    1.27 +*/
    1.28 +
    1.29 +#include "SDL_config.h"
    1.30 +#include "SDL_mirevents.h"
    1.31 +#include "SDL_mirframebuffer.h"
    1.32 +#include "SDL_mirwindow.h"
    1.33 +
    1.34 +static const Uint32 mir_pixel_format_to_sdl_format[] = {
    1.35 +    SDL_PIXELFORMAT_UNKNOWN,  /* mir_pixel_format_invalid   */
    1.36 +    SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */
    1.37 +    SDL_PIXELFORMAT_BGR888,   /* mir_pixel_format_xbgr_8888 */
    1.38 +    SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
    1.39 +    SDL_PIXELFORMAT_RGB888,   /* mir_pixel_format_xrgb_8888 */
    1.40 +    SDL_PIXELFORMAT_BGR24     /* mir_pixel_format_bgr_888   */
    1.41 +};
    1.42 +
    1.43 +Uint32
    1.44 +MIR_GetSDLPixelFormat(MirPixelFormat format)
    1.45 +{
    1.46 +    return mir_pixel_format_to_sdl_format[format];
    1.47 +}
    1.48 +
    1.49 +int
    1.50 +MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format,
    1.51 +                            void** pixels, int* pitch)
    1.52 +{
    1.53 +    MIR_Data* mir_data = _this->driverdata;
    1.54 +    MIR_Window* mir_window;
    1.55 +    MirSurfaceParameters surfaceparm;
    1.56 +
    1.57 +    if (MIR_CreateWindow(_this, window) < 0)
    1.58 +        return SDL_SetError("Failed to created a mir window.");
    1.59 +
    1.60 +    mir_window = window->driverdata;
    1.61 +
    1.62 +    mir_surface_get_parameters(mir_window->surface, &surfaceparm);
    1.63 +
    1.64 +    *format = MIR_GetSDLPixelFormat(surfaceparm.pixel_format);
    1.65 +    if (*format == SDL_PIXELFORMAT_UNKNOWN)
    1.66 +        return SDL_SetError("Unknown pixel format");
    1.67 +
    1.68 +    *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
    1.69 +
    1.70 +    *pixels = SDL_malloc(window->h*(*pitch));
    1.71 +    if (*pixels == NULL)
    1.72 +        return SDL_OutOfMemory();
    1.73 +
    1.74 +    mir_window->surface = mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
    1.75 +    if (!mir_surface_is_valid(mir_window->surface)) {
    1.76 +        const char* error = mir_surface_get_error_message(mir_window->surface);
    1.77 +        return SDL_SetError("Failed to created a mir surface: %s", error);
    1.78 +    }
    1.79 +
    1.80 +    return 0;
    1.81 +}
    1.82 +
    1.83 +int
    1.84 +MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window,
    1.85 +                            const SDL_Rect* rects, int numrects)
    1.86 +{
    1.87 +    MIR_Window* mir_window = window->driverdata;
    1.88 +
    1.89 +    MirGraphicsRegion region;
    1.90 +    int i, j, x, y, w, h, start;
    1.91 +    int bytes_per_pixel, bytes_per_row, s_stride, d_stride;
    1.92 +
    1.93 +    mir_surface_get_graphics_region(mir_window->surface, &region);
    1.94 +
    1.95 +    char* s_dest = region.vaddr;
    1.96 +    char* pixels = (char*)window->surface->pixels;
    1.97 +
    1.98 +    s_stride = window->surface->pitch;
    1.99 +    d_stride = region.stride;
   1.100 +    bytes_per_pixel = window->surface->format->BytesPerPixel;
   1.101 +
   1.102 +    for (i = 0; i < numrects; i++) {
   1.103 +        s_dest = region.vaddr;
   1.104 +        pixels = (char*)window->surface->pixels;
   1.105 +
   1.106 +        x = rects[i].x;
   1.107 +        y = rects[i].y;
   1.108 +        w = rects[i].w;
   1.109 +        h = rects[i].h;
   1.110 +
   1.111 +        if (w <= 0 || h <= 0 || (x + w) <= 0 || (y + h) <= 0)
   1.112 +            continue;
   1.113 +
   1.114 +        if (x < 0) {
   1.115 +            x += w;
   1.116 +            w += rects[i].x;
   1.117 +        }
   1.118 +
   1.119 +        if (y < 0) {
   1.120 +            y += h;
   1.121 +            h += rects[i].y;
   1.122 +        }
   1.123 +
   1.124 +        if (x + w > window->w)
   1.125 +            w = window->w - x;
   1.126 +        if (y + h > window->h)
   1.127 +            h = window->h - y;
   1.128 +
   1.129 +        start = y * s_stride + x;
   1.130 +        pixels += start;
   1.131 +        s_dest += start;
   1.132 +
   1.133 +        bytes_per_row =  bytes_per_pixel * w;
   1.134 +        for (j = 0; j < h; j++) {
   1.135 +            memcpy(s_dest, pixels, bytes_per_row);
   1.136 +            pixels += s_stride;
   1.137 +            s_dest += d_stride;
   1.138 +        }
   1.139 +    }
   1.140 +
   1.141 +    mir_surface_swap_buffers_sync(mir_window->surface);
   1.142 +
   1.143 +    return 0;
   1.144 +}
   1.145 +
   1.146 +void
   1.147 +MIR_DestroyWindowFramebuffer(_THIS, SDL_Window* window)
   1.148 +{
   1.149 +}