Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: unbreak compilation in OpenBSD #1186

Closed
wants to merge 0 commits into from

Conversation

yukiteruamano
Copy link
Contributor

The following changes allow us to build v11, v11.1 and the next branch of picom within OpenBSD.

What happens is that in OpenBSD the glGetQueryObjectui64v symbol is not available in the version of Mesa that is integrated in Xenocara and because of this, the compilation of the new versions (v11 +) fails. For this reason, OpenBSD ports still maintain v10.2.

These changes in PR allow us to compile v11+ using libepoxy (new dependency for the OpenBSD build) so we can use glGetQueryObjectui64v (epoxy_glGetQueryObjectui64v) and compile picom with minimal changes (only preprocessors in the headers, the rest of the code remains the same) without affect the code and its functionality in the rest of the OS.

I also add a preprocessor to condition code for handling real-time scheduling, since in OpenBSD sched_getparam and sched_setparam fail, so we stick with the old code using pthread_getschedparam and pthread_setschedparam.

Changes tested and compiled in OpenBSD --current (picom is my daily default compositor).

Copy link

codecov bot commented Feb 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (0f22b70) 36.62% compared to head (c9b454f) 36.60%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             next    #1186      +/-   ##
==========================================
- Coverage   36.62%   36.60%   -0.02%     
==========================================
  Files          50       50              
  Lines       11555    11555              
==========================================
- Hits         4232     4230       -2     
- Misses       7323     7325       +2     
Files Coverage Δ
src/backend/gl/gl_common.c 26.23% <ø> (ø)
src/picom.c 62.21% <100.00%> (ø)

... and 1 file with indirect coverage changes

@absolutelynothelix
Copy link
Collaborator

thanks for the pull request, we definitely need to figure this out.

have you tried retrieving the glGetQueryObjectui64v function pointer using the glXGetProcAddress or the eglGetProcAddress functions first? see #930 for example. though i'm not sure how to retrieve "general" opengl functions, i.e. not glx or egl ones. i think it should be a single declaration with the same type that just assigned differently by different backends, i.e. the glx backend does glXGetProcAddress and the egl one does eglGetProcAddress but they store the function pointer in the same variable.

also cc @omar-polo as he fixed picom building on openbsd too in the pull request linked above.

@yukiteruamano
Copy link
Contributor Author

Hi @absolutelynothelix

Yes, I have seen Omar's work regarding this problem, in fact, you can follow what we have uploaded to the OpenBSD list here.

The workaround that Omar has uploaded is a bit more "ugly" and not directly applicable to upstream to maintain, since it changes some things in the code base, making redirects to use glEGLGetQueryObjectui64v in several parts of picom's upstream code.

The solution I propose is less invasive in that case, it maintains the original code, makes use of preprocessors that only apply to OpenBSD and that have no impact on the rest of the supported OS (upstream build-tests for Linux and FreeBSD go without errors ).

All this taking advantage of the libepoxy library that comes with Xenocara, which does provide access to glGetQueryObjectui64v. I just recompiled picom with all these changes, I don't use the ports and it works without a problem.

@omar-polo
Copy link
Contributor

Yeah, my attempt was very ugly. I thought it was more or less the same issue, but I couldn't declare a global function pointer like I did in #930 since the prototype would be slightly different. So, my quick workaround was to use a different name. It works, I could ensure that the glx backend is working fine on OpenBSD-CURRENT on amdgpu, but it's so ugly.

I don't know the pros and cons of using libepoxy, I'm afraid.

@yukiteruamano
Copy link
Contributor Author

I don't know the pros and cons of using libepoxy, I'm afraid.

Same here @omar-polo but this fix is a better option than my previous proposal (changing the GLuint64 of the last_render timestamps, to be able to use glGetQueryObjectuiv).

In any case, libepoxy is part of Xenocara and as indicated in their project, the support for managing Mesa OpenGL functions is complete.

https://github.com/anholt/libepoxy

@yshui
Copy link
Owner

yshui commented Feb 8, 2024

thanks for the PR.

I will review it later, but first, can you squash the style fixes into your first commit?

@yshui
Copy link
Owner

yshui commented Feb 8, 2024

since in OpenBSD sched_getparam and sched_setparam fail,

Do you know the reason of this?

symbol is not available in the version of Mesa that is integrated in Xenocara

hmm, is it because it's old? or is there some other reason this symbol is not available?

is it possible to use glXGetProcAddress to get this function pointer?

@absolutelynothelix
Copy link
Collaborator

oh, this gets a bit tricky. let's see what @yshui thinks.

I also add a preprocessor to condition code for handling real-time scheduling, since in OpenBSD sched_getparam and sched_setparam fail, so we stick with the old code using pthread_getschedparam and pthread_setschedparam.

there is the #1169 that will replace the current real-time priority setting logic. however, it's incomplete and still uses the sched_getparam (but not the sched_setparam though). could you please note this there so it'll be addressed before it gets merged? also, it would be good if you try to build and run it to see if anything else doesn't work well within openbsd (i think you'll need to replace the only sched_getparam call with the pthread_getschedparam one manually to be able to successfully build and run it if no other issues pop up).

@yukiteruamano
Copy link
Contributor Author

@yshui rebase done

@yukiteruamano
Copy link
Contributor Author

@yshui in OpenBSD sched.h show this

#if 0   /* not yet */
int sched_setparam(pid_t, const struct sched_param *);
int sched_getparam(pid_t, struct sched_param *);

int sched_setscheduler(pid_t, int, const struct sched_param *);
int sched_getscheduler(pid_t);
#endif

It seems to not be implemented in the same way as in other systems.

hmm, is it because it's old? or is there some other reason this symbol is not available?

Mesa in OpenBSD is

client glx vendor string: Mesa Project and SGI
OpenGL core profile version string: 4.6 (Core Profile) Mesa 23.1.9
OpenGL version string: 4.6 (Compatibility Profile) Mesa 23.1.9
OpenGL ES profile version string: OpenGL ES 3.2 Mesa 23.1.9

I'm using AMDGPU for more info/context.

@yukiteruamano
Copy link
Contributor Author

@absolutelynothelix I know #1169 but I have one question over this implementation

This requires org.freedesktop.RealtimeKit1 native support on dbus implementation for OpenBSD?

Because if so, I haven't seen anything like rtkit on OpenBSD

@absolutelynothelix
Copy link
Collaborator

I haven't seen anything like rtkit on OpenBSD

image

@yukiteruamano
Copy link
Contributor Author

The old code work very well 😊

@yshui
Copy link
Owner

yshui commented Feb 8, 2024

@yukiteruamano the new code fallbacks to sched_setparam when rtkit is not available so that's ok.

can we use eglGetProcAddress/glXGetProcAddress for the function pointer? I don't want to add a whole new dependency, and I think our function pointer usage is still manageable

src/picom.c Outdated
return;
}
log_info("Set real-time scheduling priority to %d", priority);
#else // OpenBSD real-time scheduling support
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are duplicating more code than is necessary. also I think you need to add dependency('threads')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I fix this and dedup code too

@yshui
Copy link
Owner

yshui commented Feb 8, 2024

and please remember to put the gl change and sched change into separate commits, thanks.

@yshui
Copy link
Owner

yshui commented Feb 8, 2024

let me setup an openbsd build machine for CI so this kind of breakage doesn't happen again.

@yukiteruamano
Copy link
Contributor Author

@yshui the dependency is only for OpenBSD, and libepoxy is integrated on Xenocara for default. The use of this new code don't require install new packages in others OS.

I don't test eglGetProcAddress/glXGetProcAddress yet but I can try this approach

@yshui
Copy link
Owner

yshui commented Feb 9, 2024

and libepoxy is integrated on Xenocara

I see. anyway, let's give GetProcAddress a try first. now I thought about it a little more, it is a bit risky to use a (IIUC) completely different symbol loading mechanism just for OpenBSD. mainly because I have no way of testing on OpenBSD, and we have already broken OpenBSD too many times...

@yukiteruamano
Copy link
Contributor Author

@yshui Testing with glXGetProcAddress I obtain this error:

/src/backend/gl/gl_common.c:1205:7: error: called object type 'void *' is not a function or function pointer

Testing eglGetProcAddress, give me same error.

Searching symbol name glGetQueryObjectui64v (the cause of break compilation) in Mesa, don't appear. Only appear libepoxy related:

nm /usr/X11R6/lib/*.so.* | grep glGetQueryObjectui64v                                                                                                                                                                                                                                                                   

00126e58 D epoxy_glGetQueryObjectui64v
00126e60 D epoxy_glGetQueryObjectui64vEXT
000d8330 t epoxy_glGetQueryObjectui64vEXT_global_rewrite_ptr
0007dd50 r epoxy_glGetQueryObjectui64vEXT_resolver.entrypoints
0007dd40 r epoxy_glGetQueryObjectui64vEXT_resolver.providers
000d82c0 t epoxy_glGetQueryObjectui64v_global_rewrite_ptr
0007dd30 r epoxy_glGetQueryObjectui64v_resolver.entrypoints
0007dd1c r epoxy_glGetQueryObjectui64v_resolver.providers

mainly because I have no way of testing on OpenBSD, and we have already broken OpenBSD too many times...

Yeah, I understand this, in fact, it was what led me to see the port, because I saw that it was 11.1 but OpenBSD was still using 10.2. And shortly after I saw @omar-polo work (he did a different workaround) and I had already put in a different fix (quite ugly the truth) but this PR shows me a better solution (although it depends on libepoxy in OpenBSD).

@yshui
Copy link
Owner

yshui commented Feb 9, 2024

@yukiteruamano

I obtain this error:

can you post the changes you made?

@yukiteruamano
Copy link
Contributor Author

@yshui changes marked with +

bool gl_last_render_time(backend_t *base, struct timespec *ts) {
	auto gd = (struct gl_data *)base;
	GLint available = 0;
	glGetQueryObjectiv(gd->frame_timing[gd->current_frame_timing ^ 1],
	                   GL_QUERY_RESULT_AVAILABLE, &available);
	if (!available) {
		return false;
	}

	GLuint64 time;
	+ void *ptr = glXGetProcAddress("glGetQueryObjectui64v");
	+ *ptr(gd->frame_timing[gd->current_frame_timing ^ 1],
	                      GL_QUERY_RESULT, &time);
	ts->tv_sec = (long)(time / 1000000000);
	ts->tv_nsec = (long)(time % 1000000000);
	gl_check_err();
	return true;
}

@yukiteruamano
Copy link
Contributor Author

@yshui OK, I made a forward:

Using this code (based in get_proc used in egl.c):

static PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)eglGetProcAddress(glGetQueryObjectui64v);

Or this:

static PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glXGetProcAddress(glGetQueryObjectui64v);

I made the code compile. But, using my picom config, the progam break in core dump:

./build/src/picom --config /home/yukiteru/.config/picom/config --log-level info                                                                                                                                                                                                                                       

[ 02/09/24 00:45:15.136 set_rr_scheduling INFO ] Set real-time scheduling priority to 0
[ 02/09/24 00:45:15.237 glx_has_extension INFO ] Found GLX extension GLX_SGI_video_sync.
[ 02/09/24 00:45:15.237 glx_has_extension INFO ] Found GLX extension GLX_SGI_swap_control.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_OML_sync_control.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_MESA_swap_control.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_EXT_swap_control.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_EXT_texture_from_pixmap.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_ARB_create_context.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_EXT_buffer_age.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_ARB_create_context_robustness.
[ 02/09/24 00:45:15.238 glx_has_extension INFO ] Found GLX extension GLX_MESA_query_renderer.
[ 02/09/24 00:45:15.267 glGetUniformLocationChecked INFO ] Failed to get location of uniform 'time'. This is normal when using custom shaders.
[ 02/09/24 00:45:15.268 gl_init INFO ] Using back buffer format 0x8051
[ 02/09/24 00:45:15.269 gl_has_extension INFO ] Missing GL extension GL_GREMEDY_string_marker.
[ 02/09/24 00:45:15.270 redirect_start INFO ] Using vblank scheduler: present.
[1]    61084 segmentation fault (core dumped)  ./build/src/picom --config /home/yukiteru/.config/picom/config --log-level

I suspect this is because glGetQueryObjectui64v is not found as a symbol within libgl for Mesa on OpenBSD.

The other possible solution (without use libepoxy in OpenBSD) is this change:

GLuint time;
glGetQueryObjectuiv(gd->frame_timing[gd->current_frame_timing ^ 1],
    GL_QUERY_RESULT, &time);

In one occasion, I compiled and used picom with this change (aprox: 2 days using this changes), in my case without failures. But I'm afraid it may cause problems with other configurations (i.e: high vsync, vrr, multiple monitors) due to the lower resolution in the timestamp (from GLuint64 to GLuint)

@absolutelynothelix
Copy link
Collaborator

@yukiteruamano, the glXGetProcAddress function accept function name as a string.

@yukiteruamano
Copy link
Contributor Author

@absolutelynothelix same problem, compile but core dump in exec using my actual config

picom-build.mp4

@yukiteruamano
Copy link
Contributor Author

yukiteruamano commented Feb 9, 2024

@yshui with

static PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glXGetProcAddress("glGetQueryObjectui64v");

Work, compile and go with my actual config. @absolutelynothelix, you're right with the "" missing in the code.

EDIT: I have done more tests. I deleted the build folder, rebuilt the project with Meson (removing the libepoxy dependency) and compiled again. It does not work.

This code only works if during configuration with Meson I put the libepoxy dependency, otherwise it doesn't compile.

@yukiteruamano
Copy link
Contributor Author

Upload video with the test.

First of all, I use the same code

static PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)glXGetProcAddress("glGetQueryObjectui64v");

The first build in the video is done by reconfiguring the project with Meson, so that it does not use the libepoxy dependency in OpenBSD. I have removed the libexpoy headers as well (in gl_common.c). When building under these options, the compilation fails, the code indicated above does not work.

Second build, I reconfigure the project with Meson, but this time with the libepoxy dependency. I do not put the libexpoy headers, I leave them as is the original picom code, and I only add the code indicated above.

The project compiles and runs correctly, an ldd shows that libepoxy is part of the libraries used by the newly built picom.

It is clear that the version of Mesa in Xenocara depends on libepoxy to be able to access certain OpenGL functions, and `` is not the only one that is under the same issue.

picom-build-test-v2.mp4

@yshui
Copy link
Owner

yshui commented Feb 9, 2024

@yukiteruamano can you post just text logs of the error? should be easier for you, and for me.

@yukiteruamano
Copy link
Contributor Author

yukiteruamano commented Feb 9, 2024

@yshui

Finally, I managed to compile everything with the new code and get it to work. I needed to remove another modification I had made to the code that I had forgotten.

 ./build/src/picom --config /home/yukiteru/.config/picom/config --log-level info                                                                                                                                                                                                                                       

[ 02/09/24 12:46:27.896 set_rr_scheduling INFO ] Set real-time scheduling priority to 0
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_SGI_video_sync.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_SGI_swap_control.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_OML_sync_control.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_MESA_swap_control.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_EXT_swap_control.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_EXT_texture_from_pixmap.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_ARB_create_context.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_EXT_buffer_age.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_ARB_create_context_robustness.
[ 02/09/24 12:46:27.997 glx_has_extension INFO ] Found GLX extension GLX_MESA_query_renderer.
[ 02/09/24 12:46:28.029 glGetUniformLocationChecked INFO ] Failed to get location of uniform 'time'. This is normal when using custom shaders.
[ 02/09/24 12:46:28.030 gl_init INFO ] Using back buffer format 0x8051
[ 02/09/24 12:46:28.030 gl_has_extension INFO ] Missing GL extension GL_GREMEDY_string_marker.
[ 02/09/24 12:46:28.032 redirect_start INFO ] Using vblank scheduler: present.

ldd ./build/src/picom
./build/src/picom:
        Start            End              Type  Open Ref GrpRef Name
        00000d9985407000 00000d998547a000 exe   2    0   0      ./build/src/picom
        00000d9c61882000 00000d9c618b4000 rlib  0    6   0      /usr/lib/libm.so.10.1
        00000d9b9ad6f000 00000d9b9ad81000 rlib  0    1   0      /usr/local/lib/libev.so.3.1
        00000d9c7cf5a000 00000d9c7d031000 rlib  0    1   0      /usr/X11R6/lib/libpixman-1.so.40.0
        00000d9c5935c000 00000d9c594b6000 rlib  0    5   0      /usr/X11R6/lib/libX11.so.18.0
        00000d9b91c01000 00000d9b91c05000 rlib  0    3   0      /usr/X11R6/lib/libX11-xcb.so.2.0
        00000d9c0886f000 00000d9c088a0000 rlib  0    23   0      /usr/X11R6/lib/libxcb.so.4.1
        00000d9c294ff000 00000d9c29506000 rlib  0    1   0      /usr/X11R6/lib/libxcb-image.so.2.0
        00000d9bca5e5000 00000d9bca5ec000 rlib  0    1   0      /usr/X11R6/lib/libxcb-render-util.so.2.0
        00000d9bb7c35000 00000d9bb7c47000 rlib  0    2   0      /usr/X11R6/lib/libxcb-render.so.1.1
        00000d9c5f9b6000 00000d9c5f9bc000 rlib  0    1   0      /usr/X11R6/lib/libxcb-composite.so.1.0
        00000d9c4cfd4000 00000d9c4cfd9000 rlib  0    1   0      /usr/X11R6/lib/libxcb-damage.so.1.0
        00000d9baa7b6000 00000d9baa7bb000 rlib  0    1   0      /usr/X11R6/lib/libxcb-dpms.so.1.0
        00000d9bd5674000 00000d9bd5695000 rlib  0    2   0      /usr/X11R6/lib/libxcb-glx.so.1.1
        00000d9c1fc0c000 00000d9c1fc12000 rlib  0    3   0      /usr/X11R6/lib/libxcb-present.so.0.1
        00000d9c3a05a000 00000d9c3a06f000 rlib  0    4   0      /usr/X11R6/lib/libxcb-randr.so.2.3
        00000d9c45300000 00000d9c45306000 rlib  0    1   0      /usr/X11R6/lib/libxcb-shape.so.1.1
        00000d9bc1eab000 00000d9bc1eb5000 rlib  0    3   0      /usr/X11R6/lib/libxcb-sync.so.1.2
        00000d9bd25d6000 00000d9bd25e1000 rlib  0    3   0      /usr/X11R6/lib/libxcb-xfixes.so.2.0
        00000d9bf91dd000 00000d9bf91f0000 rlib  0    1   0      /usr/local/lib/libconfig.so.12.0
        00000d9c185e6000 00000d9c18640000 rlib  0    1   0      /usr/local/lib/libpcre2-8.so.0.6
        00000d9bff915000 00000d9bff9d6000 rlib  0    1   0      /usr/X11R6/lib/libGL.so.19.0
        00000d9c5ff3c000 00000d9c5ff9d000 rlib  0    1   0      /usr/X11R6/lib/libEGL.so.2.0
        00000d9be553e000 00000d9be55a4000 rlib  0    1   0      /usr/local/lib/libdbus-1.so.11.3
        00000d9c214e9000 00000d9c214f6000 rlib  0    7   0      /usr/lib/libpthread.so.27.1
        00000d9b9d2b4000 00000d9b9d3ab000 rlib  0    1   0      /usr/lib/libc.so.98.0
        00000d9bfd01c000 00000d9bfd022000 rlib  0    2   0      /usr/X11R6/lib/libXau.so.10.0
        00000d9c2d3cb000 00000d9c2d3d4000 rlib  0    2   0      /usr/X11R6/lib/libXdmcp.so.11.0
        00000d9c133f1000 00000d9c133f7000 rlib  0    2   0      /usr/X11R6/lib/libxcb-shm.so.1.1
        00000d9c44005000 00000d9c4400c000 rlib  0    1   0      /usr/X11R6/lib/libxcb-util.so.0.0
        

Thanks for your help and feedback :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants