Code Monkey home page Code Monkey logo

Comments (9)

nyorain avatar nyorain commented on September 2, 2024

It does not crash for me but simply not show anything.
Read the glTexSubImage2D spec it can only be the third reason for invalid value.
I guess this occurs since we use update_shm too often. If e.g. the buffer size changes we must use upload_shm instead.
I could come up with this small fix that makes gnome-calculator appear for me.
But this is rather a hack at the moment and there may be other related issues not fixed by this.
We should carefully check whether we can really use update_shm. Maybe such a check should take place in the texture implementation instead?

diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index 9b13d9c..f076516 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -38,6 +38,7 @@ struct wlr_surface {
 
 	float buffer_to_surface_matrix[16];
 	float surface_to_buffer_matrix[16];
+	bool reupload_buffer;
 
 	struct {
 		struct wl_signal commit;
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 50de2e4..43f8f65 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -206,8 +206,13 @@ static void surface_commit(struct wl_client *client,
 		surface->current.buffer = surface->pending.buffer;
 	}
 	if ((surface->pending.invalid & WLR_SURFACE_INVALID_SURFACE_DAMAGE)) {
+		int32_t oldw = surface->current.buffer_width;
+		int32_t oldh = surface->current.buffer_height;
 		wlr_surface_update_size(surface);
 
+		surface->reupload_buffer = oldw != surface->current.buffer_width ||
+			oldh != surface->current.buffer_height;
+
 		pixman_region32_union(&surface->current.surface_damage,
 			&surface->current.surface_damage,
 			&surface->pending.surface_damage);
@@ -257,29 +262,36 @@ void wlr_surface_flush_damage(struct wlr_surface *surface) {
 			return;
 		}
 	}
-	pixman_region32_t damage = surface->current.buffer_damage;
-	if (!pixman_region32_not_empty(&damage)) {
-		goto release;
-	}
-	int n;
-	pixman_box32_t *rects = pixman_region32_rectangles(&damage, &n);
+
 	uint32_t format = wl_shm_buffer_get_format(buffer);
-	for (int i = 0; i < n; ++i) {
-		pixman_box32_t rect = rects[i];
-		if (!wlr_texture_update_shm(surface->texture, format,
-				rect.x1, rect.y1,
-				rect.x2 - rect.x1,
-				rect.y2 - rect.y1,
-				buffer)) {
-			break;
+	if (surface->reupload_buffer) {
+		wlr_texture_upload_shm(surface->texture, format, buffer);
+	} else {
+		pixman_region32_t damage = surface->current.buffer_damage;
+		if (!pixman_region32_not_empty(&damage)) {
+			goto release;
+		}
+		int n;
+		pixman_box32_t *rects = pixman_region32_rectangles(&damage, &n);
+		for (int i = 0; i < n; ++i) {
+			pixman_box32_t rect = rects[i];
+			if (!wlr_texture_update_shm(surface->texture, format,
+					rect.x1, rect.y1,
+					rect.x2 - rect.x1,
+					rect.y2 - rect.y1,
+					buffer)) {
+				break;
+			}
 		}
 	}
+
+release:
 	pixman_region32_fini(&surface->current.surface_damage);
 	pixman_region32_init(&surface->current.surface_damage);
 
 	pixman_region32_fini(&surface->current.buffer_damage);
 	pixman_region32_init(&surface->current.buffer_damage);
-release:
+
 	wl_resource_queue_event(surface->current.buffer, WL_BUFFER_RELEASE);
 }

from wlroots.

ddevault avatar ddevault commented on September 2, 2024

We should probably have wlr_surface take care of it. We can probably do it without that bool though, right?

from wlroots.

nyorain avatar nyorain commented on September 2, 2024

We could check if the region to be updated exceeds the current dimension of the texture

from wlroots.

ddevault avatar ddevault commented on September 2, 2024

Nah, what if the buffer is made smaller? IMO wlr_surface should handle this. I can see why the bool is necessary, though. I'd merge a PR like this.

from wlroots.

nyorain avatar nyorain commented on September 2, 2024

I would rather not merge this at the moment. It can probably be done without an extra bool.
The wlr_surface implementation currently calls wlr_surface_update_size in surface_commit which is weird since at this moment the new buffer was not yet attached to the texture.
Maybe we should move the whole damage handling from commit to flush_damage?

from wlroots.

ddevault avatar ddevault commented on September 2, 2024

This is @acrisci's domain, there was some discussion on that point in #83. IIUC our implementation is to the letter of the spec, and reading it looks right to me.

The wlr_surface implementation currently calls wlr_surface_update_size in surface_commit which is weird since at this moment the new buffer was not yet attached to the texture.

It uses wlr_texture_get_buffer_size, which is a bit confusing. It takes a wlr_texture so it has access to the EGL context, but returns the size of the buffer you passed in, even if it's not attached to the texture. It's confusing but there's not an obvious better way.

from wlroots.

nyorain avatar nyorain commented on September 2, 2024

Right, oversaw this (am a bit behind with the wlr_surface implementation).
Then the approach from above is ok for now, will start a pr.

from wlroots.

acrisci avatar acrisci commented on September 2, 2024

I'm working on this today.

I recommend testing with this:

#include <gtk/gtk.h>

int main(int argc, char *argv[]) {
    gtk_init (&argc, &argv);
    GtkWidget *widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    g_signal_connect (G_OBJECT (widget), "destroy", G_CALLBACK (gtk_main_quit), NULL);  

    gtk_widget_show(widget);
    gtk_main();
}

Compile:

gcc -Wall $(pkg-config --cflags gtk+-3.0) gtk-test.c $(pkg-config --libs gtk+-3.0) -o gtk-test

Run:

./gtk-test --display=wayland-1 --debug=all

from wlroots.

acrisci avatar acrisci commented on September 2, 2024

fixed by #106

from wlroots.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.