diff options
Diffstat (limited to 'render/gles2')
-rw-r--r-- | render/gles2/renderer.c | 3 | ||||
-rw-r--r-- | render/gles2/shaders.c | 60 | ||||
-rw-r--r-- | render/gles2/texture.c | 63 |
3 files changed, 93 insertions, 33 deletions
diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index ad739cf8..ba03f599 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -179,7 +179,8 @@ static bool wlr_gles2_render_texture(struct wlr_renderer *wlr_renderer, wlr_texture_bind(texture); GL_CALL(glUniformMatrix4fv(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 46a10248..c8ba2ae6 100644 --- a/render/gles2/shaders.c +++ b/render/gles2/shaders.c @@ -10,17 +10,17 @@ const GLchar quad_vertex_src[] = "varying vec4 v_color;" "varying vec2 v_texcoord;" "mat4 transpose(in mat4 inMatrix) {" -" vec4 i0 = inMatrix[0];" -" vec4 i1 = inMatrix[1];" -" vec4 i2 = inMatrix[2];" -" vec4 i3 = inMatrix[3];" -" mat4 outMatrix = mat4(" -" vec4(i0.x, i1.x, i2.x, i3.x)," -" vec4(i0.y, i1.y, i2.y, i3.y)," -" vec4(i0.z, i1.z, i2.z, i3.z)," -" vec4(i0.w, i1.w, i2.w, i3.w)" -" );" -" return outMatrix;" +" vec4 i0 = inMatrix[0];" +" vec4 i1 = inMatrix[1];" +" vec4 i2 = inMatrix[2];" +" vec4 i3 = inMatrix[3];" +" mat4 outMatrix = mat4(" +" vec4(i0.x, i1.x, i2.x, i3.x)," +" vec4(i0.y, i1.y, i2.y, i3.y)," +" vec4(i0.z, i1.z, i2.z, i3.z)," +" vec4(i0.w, i1.w, i2.w, i3.w)" +" );" +" return outMatrix;" "}" "void main() {" " gl_Position = transpose(proj) * vec4(pos, 0.0, 1.0);" @@ -50,26 +50,30 @@ const GLchar ellipse_fragment_src[] = // Textured quads const GLchar vertex_src[] = "uniform mat4 proj;" +"uniform bool invert_y;" "attribute vec2 pos;" "attribute vec2 texcoord;" "varying vec2 v_texcoord;" "mat4 transpose(in mat4 inMatrix) {" -" vec4 i0 = inMatrix[0];" -" vec4 i1 = inMatrix[1];" -" vec4 i2 = inMatrix[2];" -" vec4 i3 = inMatrix[3];" -" mat4 outMatrix = mat4(" -" vec4(i0.x, i1.x, i2.x, i3.x)," -" vec4(i0.y, i1.y, i2.y, i3.y)," -" vec4(i0.z, i1.z, i2.z, i3.z)," -" vec4(i0.w, i1.w, i2.w, i3.w)" -" );" -"" -" return outMatrix;" +" vec4 i0 = inMatrix[0];" +" vec4 i1 = inMatrix[1];" +" vec4 i2 = inMatrix[2];" +" vec4 i3 = inMatrix[3];" +" mat4 outMatrix = mat4(" +" vec4(i0.x, i1.x, i2.x, i3.x)," +" vec4(i0.y, i1.y, i2.y, i3.y)," +" vec4(i0.z, i1.z, i2.z, i3.z)," +" vec4(i0.w, i1.w, i2.w, i3.w)" +" );" +" return outMatrix;" "}" "void main() {" -" gl_Position = transpose(proj) * vec4(pos, 0.0, 1.0);" -" v_texcoord = texcoord;" +" gl_Position = transpose(proj) * vec4(pos, 0.0, 1.0);" +" if (invert_y) {" +" v_texcoord = vec2(texcoord.s, 1.0 - texcoord.t);" +" } else {" +" v_texcoord = texcoord;" +" }" "}"; const GLchar fragment_src_rgba[] = @@ -78,7 +82,7 @@ const GLchar fragment_src_rgba[] = "uniform sampler2D tex;" "uniform float alpha;" "void main() {" -" gl_FragColor = alpha * texture2D(tex, v_texcoord);" +" gl_FragColor = alpha * texture2D(tex, v_texcoord);" "}"; const GLchar fragment_src_rgbx[] = @@ -87,8 +91,8 @@ const GLchar fragment_src_rgbx[] = "uniform sampler2D tex;" "uniform float alpha;" "void main() {" -" gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb;" -" gl_FragColor.a = alpha;" +" gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb;" +" gl_FragColor.a = alpha;" "}"; const GLchar fragment_src_external[] = diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 241b94a8..5e84890f 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 (*matrix)[16], const float (*projection)[16], int x, int y) { struct wlr_gles2_texture *texture = (struct wlr_gles2_texture *)_texture; @@ -239,6 +276,21 @@ static void gles2_texture_get_matrix(struct wlr_texture *_texture, wlr_matrix_mul(projection, matrix, matrix); } + +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); @@ -249,10 +301,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); @@ -291,6 +345,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, |