Exemplo n.º 1
0
static bool
surface_attach(struct ctx *context, struct wlc_context *bound, struct wlc_surface *surface, struct wlc_buffer *buffer)
{
   assert(context && bound && surface);

   struct wl_resource *wl_buffer;
   if (!buffer || !(wl_buffer = convert_to_wl_resource(buffer, "buffer"))) {
      surface_destroy(context, bound, surface);
      return true;
   }

   EGLint format;
   bool attached = false;

   struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(wl_buffer);
   if (shm_buffer) {
      attached = shm_attach(surface, buffer, shm_buffer);
   } else if (wlc_context_query_buffer(bound, (void*)wl_buffer, EGL_TEXTURE_FORMAT, &format)) {
      attached = egl_attach(context, bound, surface, buffer, format);
   } else {
      /* unknown buffer */
      wlc_log(WLC_LOG_WARN, "Unknown buffer");
   }

   if (attached)
      wlc_dlog(WLC_DBG_RENDER, "-> Attached surface (%" PRIuWLC ") with buffer of size (%ux%u)", convert_to_wlc_resource(surface), buffer->size.w, buffer->size.h);

   return attached;
}
Exemplo n.º 2
0
Arquivo: buffer.c Projeto: hsoft/wlc
void
wlc_buffer_release(struct wlc_buffer *buffer)
{
   struct wlc_surface *surface;
   if ((surface = convert_from_wlc_resource(buffer->surface, "surface"))) {
      if (surface->commit.buffer == convert_to_wlc_resource(buffer))
         surface->commit.buffer = 0;
      if (surface->pending.buffer == convert_to_wlc_resource(buffer))
         surface->pending.buffer = 0;
   }

   struct wl_resource *resource;
   if ((resource = convert_to_wl_resource(buffer, "buffer"))) {
      wlc_resource_invalidate(convert_to_wlc_resource(buffer));
      wl_resource_queue_event(resource, WL_BUFFER_RELEASE);
   }
}
Exemplo n.º 3
0
static bool
egl_attach(struct ctx *context, struct wlc_context *ectx, struct wlc_surface *surface, struct wlc_buffer *buffer, EGLint format)
{
   assert(context && surface && buffer);

   if (!context->api.glEGLImageTargetTexture2DOES) {
      if (!has_extension(context, "GL_OES_EGL_image_external") ||
          !(context->api.glEGLImageTargetTexture2DOES = wlc_context_get_proc_address(ectx, "glEGLImageTargetTexture2DOES"))) {
         wlc_log(WLC_LOG_WARN, "No GL_OES_EGL_image_external available");
         return false;
      }
      assert(context->api.glEGLImageTargetTexture2DOES);
   }

   buffer->legacy_buffer = convert_to_wl_resource(buffer, "buffer");
   wlc_context_query_buffer(ectx, buffer->legacy_buffer, EGL_WIDTH, (EGLint*)&buffer->size.w);
   wlc_context_query_buffer(ectx, buffer->legacy_buffer, EGL_HEIGHT, (EGLint*)&buffer->size.h);
   wlc_context_query_buffer(ectx, buffer->legacy_buffer, EGL_WAYLAND_Y_INVERTED_WL, (EGLint*)&buffer->y_inverted);

   GLuint num_planes;
   GLenum target = GL_TEXTURE_2D;
   switch (format) {
      case EGL_TEXTURE_RGB:
      case EGL_TEXTURE_RGBA:
      default:
         num_planes = 1;
         surface->format = SURFACE_RGBA;
         break;
      case 0x31DA:
         num_planes = 1;
         surface->format = SURFACE_EGL;
         target = GL_TEXTURE_EXTERNAL_OES;
         break;
      case EGL_TEXTURE_Y_UV_WL:
         num_planes = 2;
         surface->format = SURFACE_Y_UV;
         break;
      case EGL_TEXTURE_Y_U_V_WL:
         num_planes = 3;
         surface->format = SURFACE_Y_U_V;
         break;
      case EGL_TEXTURE_Y_XUXV_WL:
         num_planes = 2;
         surface->format = SURFACE_Y_XUXV;
         break;
   }

   struct wlc_view *view;
   if ((view = convert_from_wlc_handle(surface->view, "view")) && view->x11.id)
      surface->format = wlc_x11_window_get_surface_format(&view->x11);

   if (num_planes > 3) {
      wlc_log(WLC_LOG_WARN, "planes > 3 in egl surfaces not supported, nor should be possible");
      return false;
   }

   surface_flush_images(ectx, surface);
   surface_gen_textures(surface, num_planes);

   for (GLuint i = 0; i < num_planes; ++i) {
      EGLint attribs[] = { EGL_WAYLAND_PLANE_WL, i, EGL_NONE };
      if (!(surface->images[i] = wlc_context_create_image(ectx, EGL_WAYLAND_BUFFER_WL, buffer->legacy_buffer, attribs)))
         return false;

      GL_CALL(glActiveTexture(GL_TEXTURE0 + i));
      GL_CALL(glBindTexture(target, surface->textures[i]));
      GL_CALL(context->api.glEGLImageTargetTexture2DOES(target, surface->images[i]));
   }

   return true;
}