diff options
author | Dave Airlie <airlied@redhat.com> | 2013-12-17 16:53:53 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-12-17 16:53:53 +1000 |
commit | 2a048e3664f2f75171b791f43b579befc7156ccb (patch) | |
tree | bc7e12f42f9a0bdb990e6df53ced491469d8c5e9 | |
parent | aa4d78cb508a30dd16758108e232467f0c0049d4 (diff) |
flesh out a bit more protocol
-rw-r--r-- | client.c | 141 | ||||
-rw-r--r-- | common.h | 16 | ||||
-rw-r--r-- | server_egl.c | 41 |
3 files changed, 133 insertions, 65 deletions
@@ -63,7 +63,14 @@ struct x11_display { struct display { struct x11_display x11; }; - + +struct texture { + int rem_id; + GLuint local_id; + EGLImageKHR image; + struct texture *next; +}; + struct client { struct display *d; struct window *w; @@ -72,6 +79,7 @@ struct client { GLuint tex_id; GLuint tex_loc; GLuint attr_pos, attr_tex; + struct texture *texhead; }; static void x11_window_create(struct window *w) @@ -106,6 +114,12 @@ static void x11_window_create(struct window *w) if (!b) error(1, errno, "Cannot activate EGL context"); } + +static void init_fns(void) +{ + +} + static struct window *window_create(struct display *d) { @@ -339,6 +353,58 @@ static void init_shaders(struct client *c) c->tex_loc = glGetUniformLocation(prog, "samp"); } +void add_texture(struct client *client, struct cmd_buf *cbuf, int fd) +{ + struct texture *texture; + EGLint attrs[13]; + + texture = calloc(1, sizeof(*texture)); + if (!texture) + error(1, errno, "failed to create texture storage\n"); + + texture->rem_id = cbuf->u.buf.id; + + attrs[0] = EGL_DMA_BUF_PLANE0_FD_EXT; + attrs[1] = fd; + attrs[2] = EGL_DMA_BUF_PLANE0_PITCH_EXT; + attrs[3] = cbuf->u.buf.stride; + attrs[4] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; + attrs[5] = 0; + attrs[6] = EGL_WIDTH; + attrs[7] = cbuf->u.buf.width; + attrs[8] = EGL_HEIGHT; + attrs[9] = cbuf->u.buf.height; + attrs[10] = EGL_LINUX_DRM_FOURCC_EXT; + attrs[11] = cbuf->u.buf.format; + attrs[12] = EGL_NONE; + texture->image = eglCreateImageKHR(client->d->x11.egl_display, + EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + (EGLClientBuffer)NULL, + attrs); + + if (!texture->image) + error(1, errno, "failed to import image dma-buf"); + + glGenTextures(1, &texture->local_id); + glBindTexture(GL_TEXTURE_2D, texture->local_id); + glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + +// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 480, 0, +// GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)texture->image); + + if (!client->texhead) + client->texhead = texture; + else { + struct texture *iter = client->texhead; + while (iter->next) + iter = iter->next; + iter->next = texture; + } +} + struct client *client_create(int sock_fd) { struct client *client; @@ -352,71 +418,32 @@ struct client *client_create(int sock_fd) client->sock_fd = sock_fd; init_shaders(client); + + glViewport(0, 0, client->w->width, client->w->height); + glClearColor(0.0, 1.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + eglSwapBuffers(client->d->x11.egl_display, client->w->x11.egl_surface); + + glUniform1i(client->tex_loc, 0); sleep(1); for (;;) { - EGLint attrs[13]; - struct bufinfo buf; + + struct cmd_buf buf; int myfd; size = sock_fd_read(client->sock_fd, &buf, sizeof(buf), &myfd); if (size <= 0) break; - printf("read %d: %d %d %dx%d\n", (int)size, buf.id, buf.stride, buf.width, buf.height); - - attrs[0] = EGL_DMA_BUF_PLANE0_FD_EXT; - attrs[1] = myfd; - attrs[2] = EGL_DMA_BUF_PLANE0_PITCH_EXT; - attrs[3] = buf.stride; - attrs[4] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; - attrs[5] = 0; - attrs[6] = EGL_WIDTH; - attrs[7] = buf.width; - attrs[8] = EGL_HEIGHT; - attrs[9] = buf.height; - attrs[10] = EGL_LINUX_DRM_FOURCC_EXT; - attrs[11] = buf.format; - attrs[12] = EGL_NONE; - client->image = eglCreateImageKHR(client->d->x11.egl_display, - EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, - (EGLClientBuffer)NULL, - attrs); - - if (!client->image) - error(1, errno, "failed to import image dma-buf"); - - fprintf(stderr,"client->image is %p\n", client->image); - - glViewport(0, 0, client->w->width, client->w->height); - glClearColor(0.0, 1.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - eglSwapBuffers(client->d->x11.egl_display, client->w->x11.egl_surface); - sleep(1); - glClearColor(0.0, 0.0, 1.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - glGenTextures(1, &client->tex_id); - glBindTexture(GL_TEXTURE_2D, client->tex_id); - glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glUniform1i(client->tex_loc, 0); - if (1) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 480, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)client->image); - } - else { - int i; - static char pix[640*480*4]; - for (i = 0; i < 640*480; i++) { - *((unsigned int *)&pix[i * 4]) = 0x00ffff00; - } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 640, 480, 0, - GL_RGBA, GL_UNSIGNED_BYTE, pix); + if (buf.type == CMD_TYPE_BUF) { + add_texture(client, &buf, myfd); + } else if (buf.type == CMD_TYPE_DIRT) { + draw_screen(client); + + eglSwapBuffers(client->d->x11.egl_display, client->w->x11.egl_surface); } - draw_screen(client); - eglSwapBuffers(client->d->x11.egl_display, client->w->x11.egl_surface); + } return client; } @@ -3,6 +3,12 @@ struct server; +struct update_dirty_rect { + int id; + int x, y; + int width, height; +}; + struct bufinfo { int id; int width, height; @@ -10,6 +16,16 @@ struct bufinfo { int format; }; +#define CMD_TYPE_BUF 1 +#define CMD_TYPE_DIRT 2 +struct cmd_buf { + int type; + union cmds { + struct update_dirty_rect dirty; + struct bufinfo buf; + } u; +}; + struct server *server_create(int sock_fd); void server_destroy(struct server *server); diff --git a/server_egl.c b/server_egl.c index fa0fd1d..d97ed38 100644 --- a/server_egl.c +++ b/server_egl.c @@ -207,6 +207,7 @@ static int server_init_texture(struct server *server) glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); + glFinish(); /* create an EGL image from that texture */ server->image = eglCreateImageKHR(server->d->rnode.egl_display, server->d->rnode.egl_ctx, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(unsigned long)server->tex_id, NULL); @@ -222,7 +223,7 @@ static int server_init_texture(struct server *server) fprintf(stderr,"image exported %d %d %d\n", name, handle, server->stride); - r = drmPrimeHandleToFD(server->d->rnode.fd, handle, 0, &fd); + r = drmPrimeHandleToFD(server->d->rnode.fd, handle, DRM_CLOEXEC, &fd); if (r < 0) error(1, errno, "cannot get prime-fd for handle"); return fd; @@ -244,21 +245,45 @@ struct server *server_create(int sock_fd) server->d = display_create(); server->sock_fd = sock_fd; init_fns(); - + fd = server_init_texture(server); { ssize_t size; int i; - struct bufinfo buf; + struct cmd_buf buf; + + buf.type = CMD_TYPE_BUF; - buf.id = server->tex_id; - buf.stride = server->stride; - buf.width = server->width; - buf.height = server->height; - buf.format = DRM_FORMAT_XRGB8888; + buf.u.buf.id = server->tex_id; + buf.u.buf.stride = server->stride; + buf.u.buf.width = server->width; + buf.u.buf.height = server->height; + buf.u.buf.format = DRM_FORMAT_XRGB8888; size = sock_fd_write(server->sock_fd, &buf, sizeof(buf), fd); + + buf.type = CMD_TYPE_DIRT; + buf.u.dirty.id = server->tex_id; + buf.u.dirty.x = 0; + buf.u.dirty.y = 0; + buf.u.dirty.width = server->width; + buf.u.dirty.height = server->height; + size = sock_fd_write(server->sock_fd, &buf, sizeof(buf), -1); + + sleep(2); + glClearColor(0.0, 0.0, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + glFinish(); + buf.type = CMD_TYPE_DIRT; + buf.u.dirty.id = server->tex_id; + buf.u.dirty.x = 0; + buf.u.dirty.y = 0; + buf.u.dirty.width = server->width; + buf.u.dirty.height = server->height; + size = sock_fd_write(server->sock_fd, &buf, sizeof(buf), -1); } + sleep(10); return server; } |