2 #include "yagl_gles_framebuffer.h"
3 #include "yagl_gles_renderbuffer.h"
4 #include "yagl_gles_texture.h"
5 #include "yagl_gles_driver.h"
6 #include "yagl_gles_validate.h"
8 static void yagl_gles_framebuffer_destroy(struct yagl_ref *ref)
10 struct yagl_gles_framebuffer *fb = (struct yagl_gles_framebuffer*)ref;
12 if (!fb->base.nodelete) {
13 fb->driver_ps->DeleteFramebuffers(fb->driver_ps, 1, &fb->global_name);
16 qemu_mutex_destroy(&fb->mutex);
18 yagl_object_cleanup(&fb->base);
23 struct yagl_gles_framebuffer
24 *yagl_gles_framebuffer_create(struct yagl_gles_driver_ps *driver_ps)
26 GLuint global_name = 0;
27 struct yagl_gles_framebuffer *fb;
30 driver_ps->GenFramebuffers(driver_ps, 1, &global_name);
32 fb = g_malloc0(sizeof(*fb));
34 yagl_object_init(&fb->base, &yagl_gles_framebuffer_destroy);
36 fb->driver_ps = driver_ps;
37 fb->global_name = global_name;
39 qemu_mutex_init(&fb->mutex);
41 for (i = 0; i < YAGL_NUM_GLES_FRAMEBUFFER_ATTACHMENTS; ++i) {
42 fb->attachment_states[i].type = GL_NONE;
48 void yagl_gles_framebuffer_acquire(struct yagl_gles_framebuffer *fb)
51 yagl_object_acquire(&fb->base);
55 void yagl_gles_framebuffer_release(struct yagl_gles_framebuffer *fb)
58 yagl_object_release(&fb->base);
62 bool yagl_gles_framebuffer_renderbuffer(struct yagl_gles_framebuffer *fb,
65 GLenum renderbuffer_target,
66 struct yagl_gles_renderbuffer *rb,
67 yagl_object_name rb_local_name)
69 yagl_gles_framebuffer_attachment framebuffer_attachment;
71 if (!yagl_gles_validate_framebuffer_attachment(attachment,
72 &framebuffer_attachment)) {
76 if (rb && (renderbuffer_target != GL_RENDERBUFFER)) {
80 qemu_mutex_lock(&fb->mutex);
83 fb->attachment_states[framebuffer_attachment].type = GL_RENDERBUFFER;
84 fb->attachment_states[framebuffer_attachment].local_name = rb_local_name;
86 fb->attachment_states[framebuffer_attachment].type = GL_NONE;
87 fb->attachment_states[framebuffer_attachment].local_name = 0;
91 * Standalone stencil attachments are not supported on modern
92 * desktop graphics cards, so we just drop it here. Currently this
93 * doesn't do us any harm, but apps in target system that use
94 * framebuffers with stencil buffers might not be displayed correctly.
95 * If this ever happens we'll have to work around here by create some
96 * dummy texture with both color and stencil buffers and copying stencil
97 * data from that texture to texture/renderbuffer being attached here.
99 if (attachment != GL_STENCIL_ATTACHMENT) {
100 fb->driver_ps->FramebufferRenderbuffer(fb->driver_ps,
104 (rb ? rb->global_name : 0));
107 qemu_mutex_unlock(&fb->mutex);
112 bool yagl_gles_framebuffer_texture2d(struct yagl_gles_framebuffer *fb,
117 struct yagl_gles_texture *texture,
118 yagl_object_name texture_local_name)
120 yagl_gles_framebuffer_attachment framebuffer_attachment;
121 GLenum squashed_textarget;
123 if (!yagl_gles_validate_framebuffer_attachment(attachment,
124 &framebuffer_attachment)) {
128 if (texture && (level != 0)) {
132 if (!yagl_gles_validate_texture_target_squash(textarget,
133 &squashed_textarget)) {
137 if (texture && (yagl_gles_texture_get_target(texture) != squashed_textarget)) {
141 qemu_mutex_lock(&fb->mutex);
144 fb->attachment_states[framebuffer_attachment].type = GL_TEXTURE;
145 fb->attachment_states[framebuffer_attachment].local_name = texture_local_name;
147 fb->attachment_states[framebuffer_attachment].type = GL_NONE;
148 fb->attachment_states[framebuffer_attachment].local_name = 0;
151 if (attachment != GL_STENCIL_ATTACHMENT) {
152 fb->driver_ps->FramebufferTexture2D(fb->driver_ps,
156 (texture ? texture->global_name : 0),
160 qemu_mutex_unlock(&fb->mutex);
165 bool yagl_gles_framebuffer_get_attachment_parameter(struct yagl_gles_framebuffer *fb,
170 yagl_gles_framebuffer_attachment framebuffer_attachment;
172 if (!yagl_gles_validate_framebuffer_attachment(attachment,
173 &framebuffer_attachment)) {
177 qemu_mutex_lock(&fb->mutex);
180 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
181 *value = fb->attachment_states[framebuffer_attachment].type;
183 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
184 *value = fb->attachment_states[framebuffer_attachment].local_name;
186 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
187 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
188 fb->driver_ps->GetFramebufferAttachmentParameteriv(fb->driver_ps,
195 qemu_mutex_unlock(&fb->mutex);
199 qemu_mutex_unlock(&fb->mutex);
204 void yagl_gles_framebuffer_set_bound(struct yagl_gles_framebuffer *fb)
206 qemu_mutex_lock(&fb->mutex);
208 fb->was_bound = true;
210 qemu_mutex_unlock(&fb->mutex);
213 bool yagl_gles_framebuffer_was_bound(struct yagl_gles_framebuffer *fb)
217 qemu_mutex_lock(&fb->mutex);
221 qemu_mutex_unlock(&fb->mutex);