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