[PATCH] implement weston local texture using weston_buffer without wl_resourse

Benoit Gschwind gschwind at gnu-log.net
Sun Mar 8 01:33:25 PST 2015


This patch allow desktop-shell and other components of weston to create
local texture as surface and show them. This patch support only the
gl-renderer.
---
 Makefile.am                |  2 ++
 src/compositor-drm.c       |  3 ++
 src/compositor.c           | 51 +++++++++++++++++++++++++++---
 src/compositor.h           |  9 ++++++
 src/gl-renderer.c          | 77 +++++++++++++++++++++++++++++++++++++++++++---
 src/weston-local-texture.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
 src/weston-local-texture.h | 56 +++++++++++++++++++++++++++++++++
 7 files changed, 264 insertions(+), 9 deletions(-)
 create mode 100644 src/weston-local-texture.c
 create mode 100644 src/weston-local-texture.h

diff --git a/Makefile.am b/Makefile.am
index c509f6e..ab074b0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -66,6 +66,8 @@ weston_SOURCES =					\
 	src/bindings.c					\
 	src/animation.c					\
 	src/noop-renderer.c				\
+	src/weston-local-texture.c			\
+	src/weston-local-texture.h			\
 	src/pixman-renderer.c				\
 	src/pixman-renderer.h				\
 	src/timeline.c					\
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index ed4eabf..d0a7355 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -875,6 +875,9 @@ drm_output_prepare_overlay_view(struct drm_output *output,
 	if (ev->alpha != 1.0f)
 		return NULL;
 
+	if (ev->surface->buffer_ref.buffer->resource == NULL)
+		return NULL;
+
 	if (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource))
 		return NULL;
 
diff --git a/src/compositor.c b/src/compositor.c
index 45e8f5c..01357c4 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1885,6 +1885,35 @@ weston_buffer_from_resource(struct wl_resource *resource)
 	return buffer;
 }
 
+WL_EXPORT struct weston_buffer *
+weston_buffer_create_local_texture(uint32_t format, int width, int height)
+{
+	struct weston_buffer *buffer;
+	struct wl_listener *listener;
+
+	buffer = zalloc(sizeof *buffer);
+	if (buffer == NULL)
+		return NULL;
+
+	buffer->resource = NULL;
+	wl_signal_init(&buffer->destroy_signal);
+	buffer->y_inverted = 1;
+
+	struct weston_local_texture * tex;
+	tex = weston_local_texture_create(format, width, height);
+	if(!tex) {
+		free(buffer);
+		return NULL;
+	}
+
+	buffer->local_tex = tex;
+	buffer->width = tex->width;
+	buffer->height = tex->height;
+
+	return buffer;
+}
+
+
 static void
 weston_buffer_reference_handle_destroy(struct wl_listener *listener,
 				       void *data)
@@ -1904,11 +1933,19 @@ weston_buffer_reference(struct weston_buffer_reference *ref,
 	if (ref->buffer && buffer != ref->buffer) {
 		ref->buffer->busy_count--;
 		if (ref->buffer->busy_count == 0) {
-			assert(wl_resource_get_client(ref->buffer->resource));
-			wl_resource_queue_event(ref->buffer->resource,
-						WL_BUFFER_RELEASE);
+			if(ref->buffer->resource) {
+				assert(wl_resource_get_client(ref->buffer->resource));
+				wl_resource_queue_event(ref->buffer->resource,
+							WL_BUFFER_RELEASE);
+			} else {
+				/** destroy current local texture as needed **/
+				free(ref->buffer->local_tex);
+				free(ref->buffer);
+			}
+		}
+		if(ref->buffer->resource) {
+			wl_list_remove(&ref->destroy_listener.link);
 		}
-		wl_list_remove(&ref->destroy_listener.link);
 	}
 
 	if (buffer && buffer != ref->buffer) {
@@ -1921,7 +1958,7 @@ weston_buffer_reference(struct weston_buffer_reference *ref,
 	ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
 }
 
-static void
+WL_EXPORT void
 weston_surface_attach(struct weston_surface *surface,
 		      struct weston_buffer *buffer)
 {
@@ -1962,6 +1999,10 @@ static void
 surface_flush_damage(struct weston_surface *surface)
 {
 	if (surface->buffer_ref.buffer &&
+			surface->buffer_ref.buffer->resource == NULL)
+		surface->compositor->renderer->flush_damage(surface);
+
+	if (surface->buffer_ref.buffer &&
 	    wl_shm_buffer_get(surface->buffer_ref.buffer->resource))
 		surface->compositor->renderer->flush_damage(surface);
 
diff --git a/src/compositor.h b/src/compositor.h
index f4ba7a5..5381621 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -41,6 +41,7 @@ extern "C" {
 #include "config-parser.h"
 #include "zalloc.h"
 #include "timeline-object.h"
+#include "weston-local-texture.h"
 
 #ifndef MIN
 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
@@ -696,6 +697,7 @@ struct weston_buffer {
 	union {
 		struct wl_shm_buffer *shm_buffer;
 		void *legacy_buffer;
+		struct weston_local_texture * local_tex;
 	};
 	int32_t width, height;
 	uint32_t busy_count;
@@ -1316,6 +1318,9 @@ weston_surface_copy_content(struct weston_surface *surface,
 struct weston_buffer *
 weston_buffer_from_resource(struct wl_resource *resource);
 
+struct weston_buffer *
+weston_buffer_create_local_texture(uint32_t format, int width, int height);
+
 void
 weston_buffer_reference(struct weston_buffer_reference *ref,
 			struct weston_buffer *buffer);
@@ -1500,6 +1505,10 @@ weston_surface_set_color(struct weston_surface *surface,
 			 float red, float green, float blue, float alpha);
 
 void
+weston_surface_attach(struct weston_surface *surface,
+		      struct weston_buffer *buffer);
+
+void
 weston_surface_destroy(struct weston_surface *surface);
 
 int
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index e8b27b9..b9e730b 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -82,7 +82,8 @@ enum buffer_type {
 	BUFFER_TYPE_NULL,
 	BUFFER_TYPE_SOLID, /* internal solid color surfaces without a buffer */
 	BUFFER_TYPE_SHM,
-	BUFFER_TYPE_EGL
+	BUFFER_TYPE_EGL,
+	BUFFER_TYPE_LOCAL /* internal texture, buffer without resources */
 };
 
 struct gl_surface_state {
@@ -1089,6 +1090,15 @@ gl_renderer_flush_damage(struct weston_surface *surface)
 	pixman_region32_union(&gs->texture_damage,
 			      &gs->texture_damage, &surface->damage);
 
+	if(buffer->resource == NULL) {
+		glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
+		glTexImage2D(GL_TEXTURE_2D, 0, gs->gl_format,
+			     gs->pitch, buffer->height, 0,
+			     gs->gl_format, gs->gl_pixel_type,
+			     weston_local_texture_get_data(buffer->local_tex));
+		goto done;
+	}
+
 	if (!buffer)
 		return;
 
@@ -1322,6 +1332,62 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer,
 }
 
 static void
+gl_renderer_attach_local(struct weston_surface *es, struct weston_buffer *buffer, struct weston_local_texture * tex)
+{
+	printf("call gl_renderer_attach_local\n");
+	struct weston_compositor *ec = es->compositor;
+	struct gl_renderer *gr = get_renderer(ec);
+	struct gl_surface_state *gs = get_surface_state(es);
+	struct wl_shm_buffer *shm_buffer;
+	EGLint format;
+	int i;
+
+	GLenum gl_format, gl_pixel_type;
+	int pitch;
+
+	switch (tex->format) {
+	case WL_SHM_FORMAT_XRGB8888:
+		gs->shader = &gr->texture_shader_rgbx;
+		pitch = tex->stride / 4;
+		gl_format = GL_BGRA_EXT;
+		gl_pixel_type = GL_UNSIGNED_BYTE;
+		break;
+	case WL_SHM_FORMAT_ARGB8888:
+		gs->shader = &gr->texture_shader_rgba;
+		pitch = tex->stride / 4;
+		gl_format = GL_BGRA_EXT;
+		gl_pixel_type = GL_UNSIGNED_BYTE;
+		break;
+	default:
+		weston_log("warning: unknown shm buffer format: %08x\n",
+				tex->format);
+		return;
+	}
+
+	/* Only allocate a texture if it doesn't match existing one.
+	 * If a switch from DRM allocated buffer to a SHM buffer is
+	 * happening, we need to allocate a new texture buffer. */
+	if (pitch != gs->pitch ||
+			tex->height != gs->height ||
+	    gl_format != gs->gl_format ||
+	    gl_pixel_type != gs->gl_pixel_type ||
+	    gs->buffer_type != BUFFER_TYPE_LOCAL) {
+		gs->pitch = pitch;
+		gs->height = tex->height;
+		gs->target = GL_TEXTURE_2D;
+		gs->gl_format = gl_format;
+		gs->gl_pixel_type = gl_pixel_type;
+		gs->buffer_type = BUFFER_TYPE_LOCAL;
+		gs->needs_full_upload = 1;
+		gs->y_inverted = 1;
+
+		gs->surface = es;
+
+		ensure_textures(gs, 1);
+	}
+}
+
+static void
 gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
 {
 	struct weston_compositor *ec = es->compositor;
@@ -1346,9 +1412,10 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
 		return;
 	}
 
-	shm_buffer = wl_shm_buffer_get(buffer->resource);
-
-	if (shm_buffer)
+	/** local texture found **/
+	if(!buffer->resource)
+		gl_renderer_attach_local(es, buffer, buffer->local_tex);
+	else if (shm_buffer = wl_shm_buffer_get(buffer->resource))
 		gl_renderer_attach_shm(es, buffer, shm_buffer);
 	else if (gr->query_buffer(gr->egl_display, (void *) buffer->resource,
 				  EGL_TEXTURE_FORMAT, &format))
@@ -1460,6 +1527,8 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
 		/* fall through */
 	case BUFFER_TYPE_EGL:
 		break;
+	case BUFFER_TYPE_LOCAL:
+		gl_renderer_flush_damage(surface);
 	}
 
 	glGenTextures(1, &tex);
diff --git a/src/weston-local-texture.c b/src/weston-local-texture.c
new file mode 100644
index 0000000..4962ecd
--- /dev/null
+++ b/src/weston-local-texture.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2015 Benoit Gschwind
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "weston-local-texture.h"
+
+#include "wayland-server-protocol.h"
+
+#include <stdlib.h>
+
+WL_EXPORT int
+weston_local_texture_stride_for(uint32_t format, int32_t width, int32_t height) {
+	switch (format) {
+	case WL_SHM_FORMAT_ARGB8888:
+	case WL_SHM_FORMAT_XRGB8888:
+		return 4 * width;
+	default:
+		/** unsupported format **/
+		return -1;
+	}
+}
+
+/**
+ * @input format: Wayland surface format, currently only WL_SHM_FORMAT_ARGB8888 and WL_SHM_FORMAT_ARGB8888 are suported.
+ * @input width, height: desired texture width and height.
+ */
+WL_EXPORT struct weston_local_texture *
+weston_local_texture_create(uint32_t format, int32_t width, int32_t height) {
+
+	struct weston_local_texture * tex;
+
+	int stride = weston_local_texture_stride_for(format, width, height);
+	if (stride < 0)
+		return NULL;
+
+	tex = malloc(sizeof *tex + stride * height);
+	if (tex == NULL)
+		return NULL;
+
+	tex->width = width;
+	tex->height = height;
+	tex->stride = stride;
+	tex->format = format;
+
+	return tex;
+
+}
+
+/**
+ *
+ **/
+WL_EXPORT void *
+weston_local_texture_get_data(struct weston_local_texture * tex) {
+
+	return tex + 1;
+}
+
diff --git a/src/weston-local-texture.h b/src/weston-local-texture.h
new file mode 100644
index 0000000..2af74b5
--- /dev/null
+++ b/src/weston-local-texture.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2015 Benoit Gschwind
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _WAYLAND_SYSTEM_WESTON_LOCAL_TEXTURE_H_
+#define _WAYLAND_SYSTEM_WESTON_LOCAL_TEXTURE_H_
+
+#include <stdint.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+struct weston_local_texture {
+	int32_t width, height;
+	int32_t stride;
+	uint32_t format;
+	/** data are appended here **/
+};
+
+int
+weston_local_texture_stride_for(uint32_t format, int32_t width, int32_t height);
+
+/**
+ * @input format: Wayland surface format, currently only WL_SHM_FORMAT_ARGB8888 and WL_SHM_FORMAT_ARGB8888 are suported.
+ * @input width, height: desired texture width and height.
+ */
+struct weston_local_texture *
+weston_local_texture_create(uint32_t format, int32_t width, int32_t height);
+
+void *
+weston_local_texture_get_data(struct weston_local_texture * tex);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* SRC_WESTON_LOCAL_TEXTURE_H_ */
-- 
2.0.5



More information about the wayland-devel mailing list