Use select on x11 display instead of sleeping and use xdamage again
This commit is contained in:
		
							parent
							
								
									e80bab33ca
								
							
						
					
					
						commit
						008f119f4c
					
				| @ -18,7 +18,7 @@ libavformat = ">=58" | |||||||
| libavutil = ">=56.2" | libavutil = ">=56.2" | ||||||
| x11 = ">=1" | x11 = ">=1" | ||||||
| xcomposite = ">=0.2" | xcomposite = ">=0.2" | ||||||
| #xdamage = "1" | xdamage = "1" | ||||||
| 
 | 
 | ||||||
| # TODO: Remove this dependency, this is needed right now for glfwMakeContextCurrent | # TODO: Remove this dependency, this is needed right now for glfwMakeContextCurrent | ||||||
| glfw3 = "3" | glfw3 = "3" | ||||||
|  | |||||||
							
								
								
									
										58
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/main.cpp
									
									
									
									
									
								
							| @ -37,6 +37,7 @@ | |||||||
| #include <GLFW/glfw3.h> | #include <GLFW/glfw3.h> | ||||||
| 
 | 
 | ||||||
| #include <X11/extensions/Xcomposite.h> | #include <X11/extensions/Xcomposite.h> | ||||||
|  | #include <X11/extensions/Xdamage.h> | ||||||
| 
 | 
 | ||||||
| extern "C" { | extern "C" { | ||||||
| #include <libavcodec/avcodec.h> | #include <libavcodec/avcodec.h> | ||||||
| @ -839,6 +840,16 @@ int main(int argc, char **argv) { | |||||||
| 
 | 
 | ||||||
|     XSelectInput(dpy, src_window_id, StructureNotifyMask); |     XSelectInput(dpy, src_window_id, StructureNotifyMask); | ||||||
| 
 | 
 | ||||||
|  |     int damage_event; | ||||||
|  |     int damage_error; | ||||||
|  |     if (!XDamageQueryExtension(dpy, &damage_event, &damage_error)) { | ||||||
|  |         fprintf(stderr, "Error: XDamage is not supported by your X11 server\n"); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Damage damage = XDamageCreate(dpy, src_window_id, XDamageReportNonEmpty); | ||||||
|  |     XDamageSubtract(dpy, damage,None,None); | ||||||
|  | 
 | ||||||
|     int frame_count = 0; |     int frame_count = 0; | ||||||
| 
 | 
 | ||||||
|     CUresult res; |     CUresult res; | ||||||
| @ -975,15 +986,34 @@ int main(int argc, char **argv) { | |||||||
|         }, av_format_context, audio_stream, audio_frame_buf, &sound_device, audio_frame, &write_output_mutex); |         }, av_format_context, audio_stream, audio_frame_buf, &sound_device, audio_frame, &write_output_mutex); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     int x11_fd = ConnectionNumber(dpy); | ||||||
|  |     fd_set in_fds; | ||||||
|  |     struct timeval tv; | ||||||
|  | 
 | ||||||
|     bool redraw = true; |     bool redraw = true; | ||||||
|     XEvent e; |     XEvent e; | ||||||
|     while (running) { |     while (running) { | ||||||
|         double frame_start = glfwGetTime(); |  | ||||||
| 
 |  | ||||||
|         /*glClear(GL_COLOR_BUFFER_BIT);*/ |  | ||||||
|         glfwPollEvents(); |         glfwPollEvents(); | ||||||
| 
 | 
 | ||||||
|         if (XCheckTypedWindowEvent(dpy, src_window_id, ConfigureNotify, &e) && e.xconfigure.window == src_window_id) { |         FD_ZERO(&in_fds); | ||||||
|  |         FD_SET(x11_fd, &in_fds); | ||||||
|  | 
 | ||||||
|  |         /* Wake up thread every frame even if no events are received */ | ||||||
|  |         tv.tv_usec = 1000 * (1000.0 / (double)fps); | ||||||
|  |         tv.tv_sec = 0; | ||||||
|  | 
 | ||||||
|  |         int num_ready_fds = select(x11_fd + 1, &in_fds, NULL, NULL, &tv); | ||||||
|  |         if (num_ready_fds < 0) { | ||||||
|  |             //fprintf(stderr, "Window manager error: select failed on display file descriptor!\n");
 | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /*glClear(GL_COLOR_BUFFER_BIT);*/ | ||||||
|  | 
 | ||||||
|  |         while(num_ready_fds > 0 && XPending(dpy)) { | ||||||
|  |             XNextEvent(dpy, &e); | ||||||
|  | 
 | ||||||
|  |             if (e.type == ConfigureNotify && e.xconfigure.window == src_window_id) { | ||||||
|                 // Window resize
 |                 // Window resize
 | ||||||
|                 if(e.xconfigure.width != window_width || e.xconfigure.height != window_height) { |                 if(e.xconfigure.width != window_width || e.xconfigure.height != window_height) { | ||||||
|                     window_width = e.xconfigure.width; |                     window_width = e.xconfigure.width; | ||||||
| @ -993,7 +1023,19 @@ int main(int argc, char **argv) { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             if (e.type == damage_event + XDamageNotify) { | ||||||
|  |                 // fprintf(stderr, "Redraw!\n");
 | ||||||
|  |                 XDamageNotifyEvent *de = (XDamageNotifyEvent *)&e; | ||||||
|  |                 // de->drawable is the window ID of the damaged window
 | ||||||
|  |                 XserverRegion region = XFixesCreateRegion(dpy, nullptr, 0); | ||||||
|  |                 // Subtract all the damage, repairing the window
 | ||||||
|  |                 XDamageSubtract(dpy, de->damage, None, region); | ||||||
|  |                 XFixesDestroyRegion(dpy, region); | ||||||
|  | 
 | ||||||
|  |                 ++fps_counter; | ||||||
|                 redraw = true; |                 redraw = true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         const double window_resize_timeout = 1.0; // 1 second
 |         const double window_resize_timeout = 1.0; // 1 second
 | ||||||
|         if(window_resized && glfwGetTime() - window_resize_timer >= window_resize_timeout) { |         if(window_resized && glfwGetTime() - window_resize_timer >= window_resize_timeout) { | ||||||
| @ -1030,8 +1072,6 @@ int main(int argc, char **argv) { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         ++fps_counter; |  | ||||||
| 
 |  | ||||||
|         double time_now = glfwGetTime(); |         double time_now = glfwGetTime(); | ||||||
|         double frame_timer_elapsed = time_now - frame_timer_start; |         double frame_timer_elapsed = time_now - frame_timer_start; | ||||||
|         double elapsed = time_now - start_time; |         double elapsed = time_now - start_time; | ||||||
| @ -1087,12 +1127,6 @@ int main(int argc, char **argv) { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // av_frame_free(&frame);
 |         // av_frame_free(&frame);
 | ||||||
| 
 |  | ||||||
|         double frame_end = glfwGetTime(); |  | ||||||
|         double frame_sleep_fps = 1.0 / 250.0; |  | ||||||
|         double sleep_time = frame_sleep_fps - (frame_end - frame_start); |  | ||||||
|         if(sleep_time > 0.0) |  | ||||||
|             usleep(sleep_time * 1000.0 * 1000.0); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	running = 0; | 	running = 0; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 dec05eba
						dec05eba