[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