summaryrefslogtreecommitdiff
path: root/libweston/renderer-gl/gl-renderer.c
diff options
context:
space:
mode:
Diffstat (limited to 'libweston/renderer-gl/gl-renderer.c')
-rw-r--r--libweston/renderer-gl/gl-renderer.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c
index 6c435507..967827e6 100644
--- a/libweston/renderer-gl/gl-renderer.c
+++ b/libweston/renderer-gl/gl-renderer.c
@@ -58,6 +58,11 @@
#include "shared/timespec-util.h"
#include "shared/weston-egl-ext.h"
+#ifdef HAVE_TBM
+#include <tbm_bufmgr.h>
+#include <wayland-tbm-server.h>
+#endif
+
#define GR_GL_VERSION(major, minor) \
(((uint32_t)(major) << 16) | (uint32_t)(minor))
@@ -2430,6 +2435,83 @@ dmabuf_is_opaque(struct linux_dmabuf_buffer *dmabuf)
return pixel_format_is_opaque(info);
}
+#ifdef HAVE_TBM
+static bool
+tbm_surface_is_opaque(tbm_surface_h tsurface)
+{
+ const struct pixel_format_info *info;
+
+ /* format of tbm surface use fourcc */
+ info = pixel_format_get_info(tbm_surface_get_format(tsurface) &
+ ~DRM_FORMAT_BIG_ENDIAN);
+ if (!info)
+ return false;
+
+ return pixel_format_is_opaque(info);
+}
+
+static void
+gl_renderer_attach_tbm_surface(struct weston_surface *surface,
+ struct weston_buffer *buffer,
+ tbm_surface_h tsurface)
+{
+ struct gl_renderer *gr = get_renderer(surface->compositor);
+ struct gl_surface_state *gs = get_surface_state(surface);
+ tbm_format format;
+ int num_planes = 1;
+ int i;
+
+ buffer->width = tbm_surface_get_width(tsurface);
+ buffer->height = tbm_surface_get_height(tsurface);
+ /* how to know it? */
+ buffer->y_inverted = true;
+
+ for (i = 0; i < gs->num_images; i++)
+ egl_image_unref(gs->images[i]);
+ gs->num_images = 0;
+
+ gs->target = GL_TEXTURE_2D;
+ gs->pitch = buffer->width;
+ gs->height = buffer->height;
+ gs->buffer_type = BUFFER_TYPE_EGL;
+ gs->y_inverted = buffer->y_inverted;
+ surface->is_opaque = tbm_surface_is_opaque(tsurface);
+
+ format = tbm_surface_get_format(tsurface);
+ switch(format) {
+ case TBM_FORMAT_ARGB8888:
+ case TBM_FORMAT_XRGB8888:
+ gs->shader = &gr->texture_shader_rgba;
+ break;
+ default:
+ gs->shader = &gr->texture_shader_egl_external;
+ break;
+ }
+
+#ifndef EGL_NATIVE_SURFACE_TIZEN
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+#endif
+
+ ensure_textures(gs, num_planes);
+ for (i = 0; i < num_planes; i++) {
+ gs->images[i] = egl_image_create(gr,
+ EGL_NATIVE_SURFACE_TIZEN,
+ (void *)tsurface,
+ NULL);
+ if (!gs->images[i]) {
+ weston_log("failed to create img for plane %d\n", i);
+ continue;
+ }
+ gs->num_images++;
+
+ glActiveTexture(GL_TEXTURE0 + i);
+ glBindTexture(gs->target, gs->textures[i]);
+ gr->image_target_texture_2d(gs->target,
+ gs->images[i]->image);
+ }
+}
+#endif
+
static void
gl_renderer_attach_dmabuf(struct weston_surface *surface,
struct weston_buffer *buffer,
@@ -2520,6 +2602,9 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
struct linux_dmabuf_buffer *dmabuf;
EGLint format;
int i;
+#ifdef HAVE_TBM
+ tbm_surface_h tsurface;
+#endif
weston_buffer_reference(&gs->buffer_ref, buffer);
weston_buffer_release_reference(&gs->buffer_release_ref,
@@ -2544,6 +2629,10 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
if (shm_buffer)
gl_renderer_attach_shm(es, buffer, shm_buffer);
+#ifdef HAVE_TBM
+ else if ((tsurface = wayland_tbm_server_get_surface(gr->wl_tbm_server, buffer->resource)))
+ gl_renderer_attach_tbm_surface(es, buffer, tsurface);
+#endif
else if (gr->has_bind_display &&
gr->query_buffer(gr->egl_display, (void *)buffer->resource,
EGL_TEXTURE_FORMAT, &format))
@@ -3584,6 +3673,24 @@ gl_renderer_display_create(struct weston_compositor *ec,
goto fail_with_error;
}
+#ifdef HAVE_TBM
+ tbm_bufmgr bufmgr;
+
+ gr->wl_tbm_server = wayland_tbm_server_init(ec->wl_display, NULL, -1, -1);
+ if (!gr->wl_tbm_server) {
+ weston_log("Fail to init wayland_tbm_server\n");
+ goto fail_with_error;
+ }
+
+ bufmgr = wayland_tbm_server_get_bufmgr(gr->wl_tbm_server);
+ if (!bufmgr) {
+ weston_log("Fail to get bufmgr\n");
+ wayland_tbm_server_deinit(gr->wl_tbm_server);
+ goto fail_with_error;
+ }
+
+ tbm_bufmgr_bind_native_display(bufmgr, (void *)ec->wl_display);
+#endif
return 0;
fail_with_error: