2 * Copyright © 2010 Kristian Høgsberg
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "compositor.h"
26 drm_authenticate(struct wl_client *client,
27 struct wl_drm *drm_base, uint32_t id)
29 struct wlsc_drm *drm = (struct wlsc_drm *) drm_base;
30 struct wlsc_compositor *compositor =
31 container_of(drm, struct wlsc_compositor, drm);
33 if (compositor->authenticate(compositor, id) < 0)
34 wl_client_post_event(client,
35 (struct wl_object *) compositor->wl_display,
36 WL_DISPLAY_INVALID_OBJECT, 0);
38 wl_client_post_event(client, &drm->object,
39 WL_DRM_AUTHENTICATED);
43 destroy_buffer(struct wl_resource *resource, struct wl_client *client)
45 struct wlsc_drm_buffer *buffer =
46 container_of(resource, struct wlsc_drm_buffer, buffer.resource);
47 struct wlsc_compositor *compositor =
48 (struct wlsc_compositor *) buffer->buffer.compositor;
50 eglDestroyImageKHR(compositor->display, buffer->image);
55 buffer_destroy(struct wl_client *client, struct wl_buffer *buffer)
57 wl_resource_destroy(&buffer->resource, client);
60 const static struct wl_buffer_interface buffer_interface = {
65 drm_buffer_attach(struct wl_buffer *buffer_base, struct wl_surface *surface)
67 struct wlsc_surface *es = (struct wlsc_surface *) surface;
68 struct wlsc_drm_buffer *buffer =
69 (struct wlsc_drm_buffer *) buffer_base;
71 glBindTexture(GL_TEXTURE_2D, es->texture);
72 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image);
73 es->visual = buffer->buffer.visual;
77 drm_buffer_damage(struct wl_buffer *buffer,
78 struct wl_surface *surface,
79 int32_t x, int32_t y, int32_t width, int32_t height)
83 static struct wlsc_drm_buffer *
84 wlsc_drm_buffer_create_for_image(struct wlsc_compositor *compositor,
86 int32_t width, int32_t height,
87 struct wl_visual *visual)
89 struct wlsc_drm_buffer *buffer;
91 buffer = malloc(sizeof *buffer);
95 buffer->buffer.compositor = &compositor->compositor;
96 buffer->buffer.width = width;
97 buffer->buffer.height = height;
98 buffer->buffer.visual = visual;
99 buffer->buffer.attach = drm_buffer_attach;
100 buffer->buffer.damage = drm_buffer_damage;
101 buffer->image = image;
107 drm_create_buffer(struct wl_client *client, struct wl_drm *drm_base,
108 uint32_t id, uint32_t name, int32_t width, int32_t height,
109 uint32_t stride, struct wl_visual *visual)
111 struct wlsc_drm *drm = (struct wlsc_drm *) drm_base;
112 struct wlsc_compositor *compositor =
113 container_of(drm, struct wlsc_compositor, drm);
114 struct wlsc_drm_buffer *buffer;
119 EGL_DRM_BUFFER_STRIDE_MESA, 0,
120 EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
124 if (visual->object.interface != &wl_visual_interface) {
125 /* FIXME: Define a real exception event instead of
126 * abusing this one */
127 wl_client_post_event(client,
128 (struct wl_object *) compositor->wl_display,
129 WL_DISPLAY_INVALID_OBJECT, 0);
130 fprintf(stderr, "invalid visual in create_buffer\n");
136 attribs[5] = stride / 4;
137 image = eglCreateImageKHR(compositor->display,
140 (EGLClientBuffer) name, attribs);
142 /* FIXME: Define a real exception event instead of
143 * abusing this one */
144 wl_client_post_event(client,
145 (struct wl_object *) compositor->wl_display,
146 WL_DISPLAY_INVALID_OBJECT, 0);
147 fprintf(stderr, "failed to create image for name %d\n", name);
151 buffer = wlsc_drm_buffer_create_for_image(compositor, image,
152 width, height, visual);
153 if (buffer == NULL) {
154 eglDestroyImageKHR(compositor->display, image);
155 wl_client_post_no_memory(client);
159 buffer->buffer.resource.object.id = id;
160 buffer->buffer.resource.object.interface = &wl_buffer_interface;
161 buffer->buffer.resource.object.implementation = (void (**)(void))
164 buffer->buffer.resource.destroy = destroy_buffer;
166 wl_client_add_resource(client, &buffer->buffer.resource);
169 const static struct wl_drm_interface drm_interface = {
175 post_drm_device(struct wl_client *client, struct wl_object *global)
177 struct wlsc_drm *drm = container_of(global, struct wlsc_drm, object);
179 wl_client_post_event(client, global, WL_DRM_DEVICE, drm->filename);
183 wlsc_drm_init(struct wlsc_compositor *ec, int fd, const char *filename)
185 struct wlsc_drm *drm = &ec->drm;
188 drm->filename = strdup(filename);
189 if (drm->filename == NULL)
192 drm->object.interface = &wl_drm_interface;
193 drm->object.implementation = (void (**)(void)) &drm_interface;
194 wl_display_add_object(ec->wl_display, &drm->object);
195 wl_display_add_global(ec->wl_display, &drm->object, post_drm_device);
200 struct wlsc_drm_buffer *
201 wlsc_drm_buffer_create(struct wlsc_compositor *ec,
202 int width, int height, struct wl_visual *visual)
204 struct wlsc_drm_buffer *buffer;
207 EGLint image_attribs[] = {
210 EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
211 EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
215 image_attribs[1] = width;
216 image_attribs[3] = height;
218 image = eglCreateDRMImageMESA(ec->display, image_attribs);
222 buffer = wlsc_drm_buffer_create_for_image(ec, image,
223 width, height, visual);