aboutsummaryrefslogtreecommitdiff
path: root/render/gles2/texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'render/gles2/texture.c')
-rw-r--r--render/gles2/texture.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/render/gles2/texture.c b/render/gles2/texture.c
index d794e436..8b4ce673 100644
--- a/render/gles2/texture.c
+++ b/render/gles2/texture.c
@@ -44,14 +44,24 @@ static bool check_stride(const struct wlr_pixel_format_info *fmt,
return true;
}
-static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
- uint32_t stride, uint32_t width, uint32_t height,
- uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
- const void *data) {
+static bool gles2_texture_update_from_buffer(struct wlr_texture *wlr_texture,
+ struct wlr_buffer *buffer, pixman_region32_t *damage) {
struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
if (texture->target != GL_TEXTURE_2D || texture->image != EGL_NO_IMAGE_KHR) {
- wlr_log(WLR_ERROR, "Cannot write pixels to immutable texture");
+ return false;
+ }
+
+ void *data;
+ uint32_t format;
+ size_t stride;
+ if (!wlr_buffer_begin_data_ptr_access(buffer,
+ WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride)) {
+ return false;
+ }
+
+ if (format != texture->drm_format) {
+ wlr_buffer_end_data_ptr_access(buffer);
return false;
}
@@ -63,7 +73,8 @@ static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
drm_get_pixel_format_info(texture->drm_format);
assert(drm_fmt);
- if (!check_stride(drm_fmt, stride, width)) {
+ if (!check_stride(drm_fmt, stride, buffer->width)) {
+ wlr_buffer_end_data_ptr_access(buffer);
return false;
}
@@ -75,12 +86,21 @@ static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
glBindTexture(GL_TEXTURE_2D, texture->tex);
- glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / (drm_fmt->bpp / 8));
- glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, src_x);
- glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, src_y);
+ int rects_len = 0;
+ pixman_box32_t *rects = pixman_region32_rectangles(damage, &rects_len);
- glTexSubImage2D(GL_TEXTURE_2D, 0, dst_x, dst_y, width, height,
- fmt->gl_format, fmt->gl_type, data);
+ for (int i = 0; i < rects_len; i++) {
+ pixman_box32_t rect = rects[i];
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / (drm_fmt->bpp / 8));
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, rect.x1);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, rect.y1);
+
+ int width = rect.x2 - rect.x1;
+ int height = rect.y2 - rect.y1;
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x1, rect.y1, width, height,
+ fmt->gl_format, fmt->gl_type, data);
+ }
glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0);
@@ -92,6 +112,8 @@ static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
wlr_egl_restore_context(&prev_ctx);
+ wlr_buffer_end_data_ptr_access(buffer);
+
return true;
}
@@ -156,7 +178,7 @@ static void gles2_texture_unref(struct wlr_texture *wlr_texture) {
}
static const struct wlr_texture_impl texture_impl = {
- .write_pixels = gles2_texture_write_pixels,
+ .update_from_buffer = gles2_texture_update_from_buffer,
.destroy = gles2_texture_unref,
};