summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2009-09-12 16:42:07 -0400
committerKristian Høgsberg <krh@redhat.com>2009-09-12 16:42:07 -0400
commit4adaf5c6bc3e366739d03b01b809ac8fa1dc431d (patch)
tree495318e6738bf7c71d198ea9ea93fda723d83007
parent5fc96ff6e2e23bc6fab267392ead0594ccf88044 (diff)
downloadwayland-4adaf5c6bc3e366739d03b01b809ac8fa1dc431d.tar.gz
wayland-4adaf5c6bc3e366739d03b01b809ac8fa1dc431d.tar.xz
wayland-4adaf5c6bc3e366739d03b01b809ac8fa1dc431d.zip
Fix surface copy by using FBOs
-rw-r--r--wayland-system-compositor.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c
index aec318c..4ea7bbd 100644
--- a/wayland-system-compositor.c
+++ b/wayland-system-compositor.c
@@ -37,6 +37,7 @@
#define LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE
#include <libudev.h>
+#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <eagle.h>
@@ -166,7 +167,6 @@ struct wlsc_surface {
struct wl_visual *visual;
GLuint texture;
struct wl_map map;
- EGLSurface surface;
int width, height;
struct wl_list link;
struct wlsc_matrix matrix;
@@ -342,7 +342,6 @@ wlsc_surface_init(struct wlsc_surface *surface,
surface->map.y = y;
surface->map.width = width;
surface->map.height = height;
- surface->surface = EGL_NO_SURFACE;
surface->visual = visual;
wlsc_matrix_init(&surface->matrix);
}
@@ -393,8 +392,6 @@ wlsc_surface_destroy(struct wlsc_surface *surface,
wl_list_remove(&surface->link);
glDeleteTextures(1, &surface->texture);
- if (surface->surface != EGL_NO_SURFACE)
- eglDestroySurface(compositor->display, surface->surface);
free(surface);
}
@@ -730,13 +727,9 @@ surface_attach(struct wl_client *client,
struct wlsc_surface *es = (struct wlsc_surface *) surface;
struct wlsc_compositor *ec = es->compositor;
- if (es->surface != EGL_NO_SURFACE)
- eglDestroySurface(ec->display, es->surface);
-
es->width = width;
es->height = height;
- es->surface = eglCreateSurfaceForName(ec->display, ec->config,
- name, width, height, stride, NULL);
+
if (visual == &ec->argb_visual.base)
es->visual = &ec->argb_visual;
else if (visual == &ec->premultiplied_argb_visual.base)
@@ -751,7 +744,9 @@ surface_attach(struct wl_client *client,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- eglBindTexImage(ec->display, es->surface, GL_TEXTURE_2D);
+ glTextureExternalMESA(GL_TEXTURE_2D, GL_RGBA, 4,
+ width, height, stride / 4, name);
+
}
static void
@@ -780,20 +775,35 @@ surface_copy(struct wl_client *client,
int32_t x, int32_t y, int32_t width, int32_t height)
{
struct wlsc_surface *es = (struct wlsc_surface *) surface;
- struct wlsc_compositor *ec = es->compositor;
- EGLSurface src;
-
- src = eglCreateSurfaceForName(ec->display, ec->config,
- name, x + width, y + height, stride, NULL);
-
- eglMakeCurrent(ec->display, es->surface, src, ec->context);
- glDrawBuffer(GL_FRONT);
- glReadBuffer(GL_FRONT);
- glRasterPos2d(0, 0);
- fprintf(stderr, "copypixels\n");
- glCopyPixels(x, y, width, height, GL_COLOR);
-
- eglDestroySurface(ec->display, src);
+ GLuint fbo[2], rb;
+
+ glGenFramebuffers(2, fbo);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, fbo[1]);
+ glGenRenderbuffers(1, &rb);
+ glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb);
+ glRenderbufferExternalMESA(GL_RENDERBUFFER_EXT,
+ GL_RGBA,
+ es->width, es->height,
+ stride / 4, name);
+ glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT,
+ rb);
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo[0]);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, es->texture, 0);
+
+ glBlitFramebuffer(x, y, x + width, y + height,
+ dst_x, dst_y, dst_x+ width, dst_y + height,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
+ glDeleteRenderbuffers(1, &rb);
+ glDeleteFramebuffers(2, fbo);
}
static void