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