qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

console-gl.c (5225B)


      1 /*
      2  * QEMU graphical console -- opengl helper bits
      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 #include "qemu/osdep.h"
     28 #include "ui/console.h"
     29 #include "ui/shader.h"
     30 
     31 /* ---------------------------------------------------------------------- */
     32 
     33 bool console_gl_check_format(DisplayChangeListener *dcl,
     34                              pixman_format_code_t format)
     35 {
     36     switch (format) {
     37     case PIXMAN_BE_b8g8r8x8:
     38     case PIXMAN_BE_b8g8r8a8:
     39     case PIXMAN_r5g6b5:
     40         return true;
     41     default:
     42         return false;
     43     }
     44 }
     45 
     46 void surface_gl_create_texture(QemuGLShader *gls,
     47                                DisplaySurface *surface)
     48 {
     49     assert(gls);
     50     assert(QEMU_IS_ALIGNED(surface_stride(surface), surface_bytes_per_pixel(surface)));
     51 
     52     if (surface->texture) {
     53         return;
     54     }
     55 
     56     switch (surface->format) {
     57     case PIXMAN_BE_b8g8r8x8:
     58     case PIXMAN_BE_b8g8r8a8:
     59         surface->glformat = GL_BGRA_EXT;
     60         surface->gltype = GL_UNSIGNED_BYTE;
     61         break;
     62     case PIXMAN_BE_x8r8g8b8:
     63     case PIXMAN_BE_a8r8g8b8:
     64         surface->glformat = GL_RGBA;
     65         surface->gltype = GL_UNSIGNED_BYTE;
     66         break;
     67     case PIXMAN_r5g6b5:
     68         surface->glformat = GL_RGB;
     69         surface->gltype = GL_UNSIGNED_SHORT_5_6_5;
     70         break;
     71     default:
     72         g_assert_not_reached();
     73     }
     74 
     75     glGenTextures(1, &surface->texture);
     76     glEnable(GL_TEXTURE_2D);
     77     glBindTexture(GL_TEXTURE_2D, surface->texture);
     78     glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
     79                   surface_stride(surface) / surface_bytes_per_pixel(surface));
     80     if (epoxy_is_desktop_gl()) {
     81         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
     82                      surface_width(surface),
     83                      surface_height(surface),
     84                      0, surface->glformat, surface->gltype,
     85                      surface_data(surface));
     86     } else {
     87         glTexImage2D(GL_TEXTURE_2D, 0, surface->glformat,
     88                      surface_width(surface),
     89                      surface_height(surface),
     90                      0, surface->glformat, surface->gltype,
     91                      surface_data(surface));
     92         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
     93     }
     94 
     95     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     96     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     97 }
     98 
     99 void surface_gl_update_texture(QemuGLShader *gls,
    100                                DisplaySurface *surface,
    101                                int x, int y, int w, int h)
    102 {
    103     uint8_t *data = (void *)surface_data(surface);
    104 
    105     assert(gls);
    106 
    107     if (surface->texture) {
    108         glBindTexture(GL_TEXTURE_2D, surface->texture);
    109         glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
    110                       surface_stride(surface)
    111                       / surface_bytes_per_pixel(surface));
    112         glTexSubImage2D(GL_TEXTURE_2D, 0,
    113                         x, y, w, h,
    114                         surface->glformat, surface->gltype,
    115                         data + surface_stride(surface) * y
    116                         + surface_bytes_per_pixel(surface) * x);
    117     }
    118 }
    119 
    120 void surface_gl_render_texture(QemuGLShader *gls,
    121                                DisplaySurface *surface)
    122 {
    123     assert(gls);
    124 
    125     glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
    126     glClear(GL_COLOR_BUFFER_BIT);
    127 
    128     qemu_gl_run_texture_blit(gls, false);
    129 }
    130 
    131 void surface_gl_destroy_texture(QemuGLShader *gls,
    132                                 DisplaySurface *surface)
    133 {
    134     if (!surface || !surface->texture) {
    135         return;
    136     }
    137     glDeleteTextures(1, &surface->texture);
    138     surface->texture = 0;
    139 }
    140 
    141 void surface_gl_setup_viewport(QemuGLShader *gls,
    142                                DisplaySurface *surface,
    143                                int ww, int wh)
    144 {
    145     int gw, gh, stripe;
    146     float sw, sh;
    147 
    148     assert(gls);
    149 
    150     gw = surface_width(surface);
    151     gh = surface_height(surface);
    152 
    153     sw = (float)ww/gw;
    154     sh = (float)wh/gh;
    155     if (sw < sh) {
    156         stripe = wh - wh*sw/sh;
    157         glViewport(0, stripe / 2, ww, wh - stripe);
    158     } else {
    159         stripe = ww - ww*sh/sw;
    160         glViewport(stripe / 2, 0, ww - stripe, wh);
    161     }
    162 }