diff options
Diffstat (limited to 'render/gles2')
-rw-r--r-- | render/gles2/renderer.c | 3 | ||||
-rw-r--r-- | render/gles2/shaders.c | 14 | ||||
-rw-r--r-- | render/gles2/texture.c | 63 |
3 files changed, 73 insertions, 7 deletions
diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index e0a98d29..0324ad64 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -182,7 +182,8 @@ static bool wlr_gles2_render_texture_with_matrix( wlr_texture_bind(texture); GL_CALL(glUniformMatrix3fv(0, 1, GL_FALSE, matrix)); - GL_CALL(glUniform1f(2, alpha)); + GL_CALL(glUniform1i(1, texture->inverted_y)); + GL_CALL(glUniform1f(3, alpha)); draw_quad(); return true; } diff --git a/render/gles2/shaders.c b/render/gles2/shaders.c index 9d3a67c2..a64b941e 100644 --- a/render/gles2/shaders.c +++ b/render/gles2/shaders.c @@ -32,6 +32,7 @@ const GLchar quad_fragment_src[] = "precision mediump float;" "varying vec4 v_color;" "varying vec2 v_texcoord;" +"" "void main() {" " gl_FragColor = v_color;" "}"; @@ -41,6 +42,7 @@ const GLchar ellipse_fragment_src[] = "precision mediump float;" "varying vec4 v_color;" "varying vec2 v_texcoord;" +"" "void main() {" " float l = length(v_texcoord - vec2(0.5, 0.5));" " if (l > 0.5) discard;" @@ -50,6 +52,7 @@ const GLchar ellipse_fragment_src[] = // Textured quads const GLchar vertex_src[] = "uniform mat3 proj;" +"uniform bool invert_y;" "attribute vec2 pos;" "attribute vec2 texcoord;" "varying vec2 v_texcoord;" @@ -67,8 +70,12 @@ const GLchar vertex_src[] = "}" "" "void main() {" -" gl_Position = vec4(transpose(proj) * vec3(pos, 1.0), 1.0);" -" v_texcoord = texcoord;" +" gl_Position = vec4(transpose(proj) * vec3(pos, 1.0), 1.0);" +" if (invert_y) {" +" v_texcoord = vec2(texcoord.s, 1.0 - texcoord.t);" +" } else {" +" v_texcoord = texcoord;" +" }" "}"; const GLchar fragment_src_rgba[] = @@ -76,6 +83,7 @@ const GLchar fragment_src_rgba[] = "varying vec2 v_texcoord;" "uniform sampler2D tex;" "uniform float alpha;" +"" "void main() {" " gl_FragColor = alpha * texture2D(tex, v_texcoord);" "}"; @@ -85,6 +93,7 @@ const GLchar fragment_src_rgbx[] = "varying vec2 v_texcoord;" "uniform sampler2D tex;" "uniform float alpha;" +"" "void main() {" " gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb;" " gl_FragColor.a = alpha;" @@ -95,6 +104,7 @@ const GLchar fragment_src_external[] = "precision mediump float;" "varying vec2 v_texcoord;" "uniform samplerExternalOES texture0;" +"" "void main() {" " vec4 col = texture2D(texture0, v_texcoord);" " gl_FragColor = vec4(col.rgb, col.a);" diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 9ee2a3e3..875affe2 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -164,6 +164,7 @@ static bool gles2_texture_upload_drm(struct wlr_texture *_tex, EGLint inverted_y; wlr_egl_query_buffer(tex->egl, buf, EGL_WAYLAND_Y_INVERTED_WL, &inverted_y); + tex->wlr_texture.inverted_y = !!inverted_y; GLenum target; const struct pixel_format *pf; @@ -226,6 +227,42 @@ static bool gles2_texture_upload_eglimage(struct wlr_texture *wlr_tex, return true; } + +static bool gles2_texture_upload_dmabuf(struct wlr_texture *_tex, + struct wl_resource *dmabuf_resource) { + struct wlr_gles2_texture *tex = (struct wlr_gles2_texture *)_tex; + struct wlr_dmabuf_buffer *dmabuf = wlr_dmabuf_buffer_from_buffer_resource( + dmabuf_resource); + + if (!tex->egl->egl_exts.dmabuf_import) { + wlr_log(L_ERROR, "Want dmabuf but extension not present"); + return false; + } + + tex->wlr_texture.width = dmabuf->attributes.width; + tex->wlr_texture.height = dmabuf->attributes.height; + + if (tex->image) { + wlr_egl_destroy_image(tex->egl, tex->image); + } + + if (wlr_dmabuf_buffer_has_inverted_y(dmabuf)) { + _tex->inverted_y = true; + } + + GLenum target = GL_TEXTURE_2D; + const struct pixel_format *pf = + gl_format_for_wl_format(WL_SHM_FORMAT_ARGB8888); + gles2_texture_ensure_texture(tex); + GL_CALL(glBindTexture(target, tex->tex_id)); + tex->image = wlr_egl_create_image_from_dmabuf(tex->egl, &dmabuf->attributes); + GL_CALL(glActiveTexture(GL_TEXTURE0)); + GL_CALL(glEGLImageTargetTexture2DOES(target, tex->image)); + tex->pixel_format = pf; + tex->wlr_texture.valid = true; + return true; +} + static void gles2_texture_get_matrix(struct wlr_texture *_texture, float mat[static 9], const float projection[static 9], int x, int y) { struct wlr_gles2_texture *texture = (struct wlr_gles2_texture *)_texture; @@ -236,6 +273,21 @@ static void gles2_texture_get_matrix(struct wlr_texture *_texture, wlr_matrix_multiply(mat, projection, mat); } + +static bool gles2_texture_get_dmabuf_size(struct wlr_texture *texture, struct + wl_resource *resource, int *width, int *height) { + if (!wlr_dmabuf_resource_is_buffer(resource)) { + return false; + } + + struct wlr_dmabuf_buffer *dmabuf = wlr_dmabuf_buffer_from_buffer_resource( + resource); + *width = dmabuf->attributes.width; + *height = dmabuf->attributes.height; + return true; +} + + static void gles2_texture_get_buffer_size(struct wlr_texture *texture, struct wl_resource *resource, int *width, int *height) { struct wl_shm_buffer *buffer = wl_shm_buffer_get(resource); @@ -246,10 +298,12 @@ static void gles2_texture_get_buffer_size(struct wlr_texture *texture, struct } if (!wlr_egl_query_buffer(tex->egl, resource, EGL_WIDTH, (EGLint*)width)) { - wlr_log(L_ERROR, "could not get size of the buffer " - "(no buffer found)"); - return; - }; + if (!gles2_texture_get_dmabuf_size(texture, resource, + width, height)) { + wlr_log(L_ERROR, "could not get size of the buffer"); + return; + } + } wlr_egl_query_buffer(tex->egl, resource, EGL_HEIGHT, (EGLint*)height); @@ -288,6 +342,7 @@ static struct wlr_texture_impl wlr_texture_impl = { .upload_shm = gles2_texture_upload_shm, .update_shm = gles2_texture_update_shm, .upload_drm = gles2_texture_upload_drm, + .upload_dmabuf = gles2_texture_upload_dmabuf, .upload_eglimage = gles2_texture_upload_eglimage, .get_matrix = gles2_texture_get_matrix, .get_buffer_size = gles2_texture_get_buffer_size, |