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