cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

sdl2-gl.c (7743B)


      1/*
      2 * QEMU SDL display driver -- opengl support
      3 *
      4 * Copyright (c) 2014 Red Hat
      5 *
      6 * Authors:
      7 *     Gerd Hoffmann <kraxel@redhat.com>
      8 *
      9 * Permission is hereby granted, free of charge, to any person obtaining a copy
     10 * of this software and associated documentation files (the "Software"), to deal
     11 * in the Software without restriction, including without limitation the rights
     12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     13 * copies of the Software, and to permit persons to whom the Software is
     14 * furnished to do so, subject to the following conditions:
     15 *
     16 * The above copyright notice and this permission notice shall be included in
     17 * all copies or substantial portions of the Software.
     18 *
     19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     25 * THE SOFTWARE.
     26 */
     27
     28#include "qemu/osdep.h"
     29#include "ui/console.h"
     30#include "ui/input.h"
     31#include "ui/sdl2.h"
     32
     33static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout)
     34{
     35    if (scon->scanout_mode == scanout) {
     36        return;
     37    }
     38
     39    scon->scanout_mode = scanout;
     40    if (!scon->scanout_mode) {
     41        egl_fb_destroy(&scon->guest_fb);
     42        if (scon->surface) {
     43            surface_gl_destroy_texture(scon->gls, scon->surface);
     44            surface_gl_create_texture(scon->gls, scon->surface);
     45        }
     46    }
     47}
     48
     49static void sdl2_gl_render_surface(struct sdl2_console *scon)
     50{
     51    int ww, wh;
     52
     53    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
     54    sdl2_set_scanout_mode(scon, false);
     55
     56    SDL_GetWindowSize(scon->real_window, &ww, &wh);
     57    surface_gl_setup_viewport(scon->gls, scon->surface, ww, wh);
     58
     59    surface_gl_render_texture(scon->gls, scon->surface);
     60    SDL_GL_SwapWindow(scon->real_window);
     61    graphic_hw_gl_flushed(scon->dcl.con);
     62}
     63
     64void sdl2_gl_update(DisplayChangeListener *dcl,
     65                    int x, int y, int w, int h)
     66{
     67    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
     68
     69    assert(scon->opengl);
     70
     71    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
     72    surface_gl_update_texture(scon->gls, scon->surface, x, y, w, h);
     73    scon->updates++;
     74}
     75
     76void sdl2_gl_switch(DisplayChangeListener *dcl,
     77                    DisplaySurface *new_surface)
     78{
     79    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
     80    DisplaySurface *old_surface = scon->surface;
     81
     82    assert(scon->opengl);
     83
     84    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
     85    surface_gl_destroy_texture(scon->gls, scon->surface);
     86
     87    scon->surface = new_surface;
     88
     89    if (is_placeholder(new_surface) && qemu_console_get_index(dcl->con)) {
     90        qemu_gl_fini_shader(scon->gls);
     91        scon->gls = NULL;
     92        sdl2_window_destroy(scon);
     93        return;
     94    }
     95
     96    if (!scon->real_window) {
     97        sdl2_window_create(scon);
     98        scon->gls = qemu_gl_init_shader();
     99    } else if (old_surface &&
    100               ((surface_width(old_surface)  != surface_width(new_surface)) ||
    101                (surface_height(old_surface) != surface_height(new_surface)))) {
    102        sdl2_window_resize(scon);
    103    }
    104
    105    surface_gl_create_texture(scon->gls, scon->surface);
    106}
    107
    108void sdl2_gl_refresh(DisplayChangeListener *dcl)
    109{
    110    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
    111
    112    assert(scon->opengl);
    113
    114    graphic_hw_update(dcl->con);
    115    if (scon->updates && scon->real_window) {
    116        scon->updates = 0;
    117        sdl2_gl_render_surface(scon);
    118    }
    119    sdl2_poll_events(scon);
    120}
    121
    122void sdl2_gl_redraw(struct sdl2_console *scon)
    123{
    124    assert(scon->opengl);
    125
    126    if (scon->scanout_mode) {
    127        /* sdl2_gl_scanout_flush actually only care about
    128         * the first argument. */
    129        return sdl2_gl_scanout_flush(&scon->dcl, 0, 0, 0, 0);
    130    }
    131    if (scon->surface) {
    132        sdl2_gl_render_surface(scon);
    133    }
    134}
    135
    136QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
    137                                     QEMUGLParams *params)
    138{
    139    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
    140    SDL_GLContext ctx;
    141
    142    assert(scon->opengl);
    143
    144    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
    145
    146    SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
    147    if (scon->opts->gl == DISPLAYGL_MODE_ON ||
    148        scon->opts->gl == DISPLAYGL_MODE_CORE) {
    149        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
    150                            SDL_GL_CONTEXT_PROFILE_CORE);
    151    } else if (scon->opts->gl == DISPLAYGL_MODE_ES) {
    152        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
    153                            SDL_GL_CONTEXT_PROFILE_ES);
    154    }
    155    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, params->major_ver);
    156    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, params->minor_ver);
    157
    158    ctx = SDL_GL_CreateContext(scon->real_window);
    159
    160    /* If SDL fail to create a GL context and we use the "on" flag,
    161     * then try to fallback to GLES.
    162     */
    163    if (!ctx && scon->opts->gl == DISPLAYGL_MODE_ON) {
    164        SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
    165                            SDL_GL_CONTEXT_PROFILE_ES);
    166        ctx = SDL_GL_CreateContext(scon->real_window);
    167    }
    168    return (QEMUGLContext)ctx;
    169}
    170
    171void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
    172{
    173    SDL_GLContext sdlctx = (SDL_GLContext)ctx;
    174
    175    SDL_GL_DeleteContext(sdlctx);
    176}
    177
    178int sdl2_gl_make_context_current(DisplayChangeListener *dcl,
    179                                 QEMUGLContext ctx)
    180{
    181    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
    182    SDL_GLContext sdlctx = (SDL_GLContext)ctx;
    183
    184    assert(scon->opengl);
    185
    186    return SDL_GL_MakeCurrent(scon->real_window, sdlctx);
    187}
    188
    189void sdl2_gl_scanout_disable(DisplayChangeListener *dcl)
    190{
    191    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
    192
    193    assert(scon->opengl);
    194    scon->w = 0;
    195    scon->h = 0;
    196    sdl2_set_scanout_mode(scon, false);
    197}
    198
    199void sdl2_gl_scanout_texture(DisplayChangeListener *dcl,
    200                             uint32_t backing_id,
    201                             bool backing_y_0_top,
    202                             uint32_t backing_width,
    203                             uint32_t backing_height,
    204                             uint32_t x, uint32_t y,
    205                             uint32_t w, uint32_t h)
    206{
    207    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
    208
    209    assert(scon->opengl);
    210    scon->x = x;
    211    scon->y = y;
    212    scon->w = w;
    213    scon->h = h;
    214    scon->y0_top = backing_y_0_top;
    215
    216    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
    217
    218    sdl2_set_scanout_mode(scon, true);
    219    egl_fb_setup_for_tex(&scon->guest_fb, backing_width, backing_height,
    220                         backing_id, false);
    221}
    222
    223void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
    224                           uint32_t x, uint32_t y, uint32_t w, uint32_t h)
    225{
    226    struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
    227    int ww, wh;
    228
    229    assert(scon->opengl);
    230    if (!scon->scanout_mode) {
    231        return;
    232    }
    233    if (!scon->guest_fb.framebuffer) {
    234        return;
    235    }
    236
    237    SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
    238
    239    SDL_GetWindowSize(scon->real_window, &ww, &wh);
    240    egl_fb_setup_default(&scon->win_fb, ww, wh);
    241    egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top);
    242
    243    SDL_GL_SwapWindow(scon->real_window);
    244    graphic_hw_gl_flushed(dcl->con);
    245}