|
|
|
@ -14,61 +14,11 @@ |
|
|
|
|
|
|
|
|
|
#include "wayland-client.h" |
|
|
|
|
#include "wayland-glib.h" |
|
|
|
|
#include "cairo-util.h" |
|
|
|
|
|
|
|
|
|
static const char gem_device[] = "/dev/dri/card0"; |
|
|
|
|
static const char socket_name[] = "\0wayland"; |
|
|
|
|
|
|
|
|
|
static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface) |
|
|
|
|
{ |
|
|
|
|
struct drm_i915_gem_create create; |
|
|
|
|
struct drm_gem_flink flink; |
|
|
|
|
struct drm_i915_gem_pwrite pwrite; |
|
|
|
|
int32_t width, height, stride; |
|
|
|
|
void *data; |
|
|
|
|
|
|
|
|
|
width = cairo_image_surface_get_width(surface); |
|
|
|
|
height = cairo_image_surface_get_height(surface); |
|
|
|
|
stride = cairo_image_surface_get_stride(surface); |
|
|
|
|
data = cairo_image_surface_get_data(surface); |
|
|
|
|
|
|
|
|
|
memset(&create, 0, sizeof(create)); |
|
|
|
|
create.size = height * stride; |
|
|
|
|
|
|
|
|
|
if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create) != 0) { |
|
|
|
|
fprintf(stderr, "gem create failed: %m\n"); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pwrite.handle = create.handle; |
|
|
|
|
pwrite.offset = 0; |
|
|
|
|
pwrite.size = height * stride; |
|
|
|
|
pwrite.data_ptr = (uint64_t) (uintptr_t) data; |
|
|
|
|
if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) { |
|
|
|
|
fprintf(stderr, "gem pwrite failed: %m\n"); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
flink.handle = create.handle; |
|
|
|
|
if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) != 0) { |
|
|
|
|
fprintf(stderr, "gem flink failed: %m\n"); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
/* We need to hold on to the handle until the server has received
|
|
|
|
|
* the attach request... we probably need a confirmation event. |
|
|
|
|
* I guess the breadcrumb idea will suffice. */ |
|
|
|
|
struct drm_gem_close close; |
|
|
|
|
close.handle = create.handle; |
|
|
|
|
if (ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) { |
|
|
|
|
fprintf(stderr, "gem close failed: %m\n"); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
return flink.name; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
set_random_color(cairo_t *cr) |
|
|
|
|
{ |
|
|
|
@ -155,12 +105,12 @@ int main(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
struct wl_display *display; |
|
|
|
|
int fd; |
|
|
|
|
uint32_t name; |
|
|
|
|
cairo_surface_t *s; |
|
|
|
|
struct timespec ts; |
|
|
|
|
GMainLoop *loop; |
|
|
|
|
GSource *source; |
|
|
|
|
struct flower flower; |
|
|
|
|
struct buffer *buffer; |
|
|
|
|
|
|
|
|
|
fd = open(gem_device, O_RDWR); |
|
|
|
|
if (fd < 0) { |
|
|
|
@ -190,10 +140,10 @@ int main(int argc, char *argv[]) |
|
|
|
|
flower.i = ts.tv_nsec; |
|
|
|
|
|
|
|
|
|
s = draw_stuff(flower.width, flower.height); |
|
|
|
|
name = name_cairo_surface(fd, s); |
|
|
|
|
buffer = buffer_create_from_cairo_surface(fd, s); |
|
|
|
|
|
|
|
|
|
wl_surface_attach(flower.surface, name, flower.width, flower.height, |
|
|
|
|
cairo_image_surface_get_stride(s)); |
|
|
|
|
wl_surface_attach(flower.surface, buffer->name, flower.width, flower.height, |
|
|
|
|
buffer->stride); |
|
|
|
|
|
|
|
|
|
g_timeout_add(20, move_flower, &flower); |
|
|
|
|
|
|
|
|
|