diff options
Diffstat (limited to 'libweston/renderer-gl/gl-renderer.c')
-rw-r--r-- | libweston/renderer-gl/gl-renderer.c | 107 |
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: |