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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to