diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 4f03218c..d13781c7 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -1200,6 +1200,116 @@ ensure_textures(struct gl_surface_state *gs, int num_textures) glBindTexture(gs->target, 0); } +static void +gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer, + struct wl_shm_buffer *shm_buffer) +{ + struct weston_compositor *ec = es->compositor; + struct gl_renderer *gr = get_renderer(ec); + struct gl_surface_state *gs = get_surface_state(es); + + buffer->shm_buffer = shm_buffer; + buffer->width = wl_shm_buffer_get_width(shm_buffer); + buffer->height = wl_shm_buffer_get_height(shm_buffer); + + /* 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 (wl_shm_buffer_get_stride(shm_buffer) / 4 != gs->pitch || + buffer->height != gs->height || + gs->buffer_type != BUFFER_TYPE_SHM) { + gs->pitch = wl_shm_buffer_get_stride(shm_buffer) / 4; + gs->height = buffer->height; + gs->target = GL_TEXTURE_2D; + gs->buffer_type = BUFFER_TYPE_SHM; + gs->needs_full_upload = 1; + + ensure_textures(gs, 1); + glBindTexture(GL_TEXTURE_2D, gs->textures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, + gs->pitch, buffer->height, 0, + GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); + } + + if (wl_shm_buffer_get_format(shm_buffer) == WL_SHM_FORMAT_XRGB8888) + gs->shader = &gr->texture_shader_rgbx; + else + gs->shader = &gr->texture_shader_rgba; +} + +static void +gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer, + uint32_t format) +{ + struct weston_compositor *ec = es->compositor; + struct gl_renderer *gr = get_renderer(ec); + struct gl_surface_state *gs = get_surface_state(es); + EGLint attribs[3]; + int i, num_planes; + + buffer->legacy_buffer = (struct wl_buffer *)buffer->resource; + gr->query_buffer(gr->egl_display, buffer->legacy_buffer, + EGL_WIDTH, &buffer->width); + gr->query_buffer(gr->egl_display, buffer->legacy_buffer, + EGL_HEIGHT, &buffer->height); + + for (i = 0; i < gs->num_images; i++) + gr->destroy_image(gr->egl_display, gs->images[i]); + gs->num_images = 0; + gs->target = GL_TEXTURE_2D; + switch (format) { + case EGL_TEXTURE_RGB: + case EGL_TEXTURE_RGBA: + default: + num_planes = 1; + gs->shader = &gr->texture_shader_rgba; + break; + case EGL_TEXTURE_EXTERNAL_WL: + num_planes = 1; + gs->target = GL_TEXTURE_EXTERNAL_OES; + gs->shader = &gr->texture_shader_egl_external; + break; + case EGL_TEXTURE_Y_UV_WL: + num_planes = 2; + gs->shader = &gr->texture_shader_y_uv; + break; + case EGL_TEXTURE_Y_U_V_WL: + num_planes = 3; + gs->shader = &gr->texture_shader_y_u_v; + break; + case EGL_TEXTURE_Y_XUXV_WL: + num_planes = 2; + gs->shader = &gr->texture_shader_y_xuxv; + break; + } + + ensure_textures(gs, num_planes); + for (i = 0; i < num_planes; i++) { + attribs[0] = EGL_WAYLAND_PLANE_WL; + attribs[1] = i; + attribs[2] = EGL_NONE; + gs->images[i] = gr->create_image(gr->egl_display, + NULL, + EGL_WAYLAND_BUFFER_WL, + buffer->legacy_buffer, + attribs); + 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]); + } + + gs->pitch = buffer->width; + gs->height = buffer->height; + gs->buffer_type = BUFFER_TYPE_EGL; +} + static void gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) { @@ -1207,8 +1317,8 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) struct gl_renderer *gr = get_renderer(ec); struct gl_surface_state *gs = get_surface_state(es); struct wl_shm_buffer *shm_buffer; - EGLint attribs[3], format; - int i, num_planes; + EGLint format; + int i; weston_buffer_reference(&gs->buffer_ref, buffer); @@ -1225,99 +1335,14 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) } shm_buffer = wl_shm_buffer_get(buffer->resource); - if (shm_buffer) { - buffer->shm_buffer = shm_buffer; - buffer->width = wl_shm_buffer_get_width(shm_buffer); - buffer->height = wl_shm_buffer_get_height(shm_buffer); - - /* 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 (wl_shm_buffer_get_stride(shm_buffer) / 4 != gs->pitch || - buffer->height != gs->height || - gs->buffer_type != BUFFER_TYPE_SHM) { - gs->pitch = wl_shm_buffer_get_stride(shm_buffer) / 4; - gs->height = buffer->height; - gs->target = GL_TEXTURE_2D; - gs->buffer_type = BUFFER_TYPE_SHM; - gs->needs_full_upload = 1; - - ensure_textures(gs, 1); - glBindTexture(GL_TEXTURE_2D, gs->textures[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, - gs->pitch, buffer->height, 0, - GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); - } - - if (wl_shm_buffer_get_format(shm_buffer) == WL_SHM_FORMAT_XRGB8888) - gs->shader = &gr->texture_shader_rgbx; - else - gs->shader = &gr->texture_shader_rgba; - } else if (gr->query_buffer(gr->egl_display, - (struct wl_buffer *)buffer->resource, - EGL_TEXTURE_FORMAT, &format)) { - buffer->legacy_buffer = (struct wl_buffer *)buffer->resource; - gr->query_buffer(gr->egl_display, buffer->legacy_buffer, - EGL_WIDTH, &buffer->width); - gr->query_buffer(gr->egl_display, buffer->legacy_buffer, - EGL_HEIGHT, &buffer->height); - - for (i = 0; i < gs->num_images; i++) - gr->destroy_image(gr->egl_display, gs->images[i]); - gs->num_images = 0; - gs->target = GL_TEXTURE_2D; - switch (format) { - case EGL_TEXTURE_RGB: - case EGL_TEXTURE_RGBA: - default: - num_planes = 1; - gs->shader = &gr->texture_shader_rgba; - break; - case EGL_TEXTURE_EXTERNAL_WL: - num_planes = 1; - gs->target = GL_TEXTURE_EXTERNAL_OES; - gs->shader = &gr->texture_shader_egl_external; - break; - case EGL_TEXTURE_Y_UV_WL: - num_planes = 2; - gs->shader = &gr->texture_shader_y_uv; - break; - case EGL_TEXTURE_Y_U_V_WL: - num_planes = 3; - gs->shader = &gr->texture_shader_y_u_v; - break; - case EGL_TEXTURE_Y_XUXV_WL: - num_planes = 2; - gs->shader = &gr->texture_shader_y_xuxv; - break; - } - ensure_textures(gs, num_planes); - for (i = 0; i < num_planes; i++) { - attribs[0] = EGL_WAYLAND_PLANE_WL; - attribs[1] = i; - attribs[2] = EGL_NONE; - gs->images[i] = gr->create_image(gr->egl_display, - NULL, - EGL_WAYLAND_BUFFER_WL, - buffer->legacy_buffer, - attribs); - 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]); - } - - gs->pitch = buffer->width; - gs->height = buffer->height; - gs->buffer_type = BUFFER_TYPE_EGL; - } else { + if (shm_buffer) + gl_renderer_attach_shm(es, buffer, shm_buffer); + else if (gr->query_buffer(gr->egl_display, + (struct wl_buffer *)buffer->resource, + EGL_TEXTURE_FORMAT, &format)) + gl_renderer_attach_egl(es, buffer, format); + else { weston_log("unhandled buffer type!\n"); weston_buffer_reference(&gs->buffer_ref, NULL); gs->buffer_type = BUFFER_TYPE_NULL;