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