obs-studio icon indicating copy to clipboard operation
obs-studio copied to clipboard

linux-pipewire: Replace swap r/b with opaque draw

Open tytan652 opened this issue 5 months ago • 5 comments

Description

Red and blue swapping was introduced to convert RGBX format to BGRX since the later does not have a matching gs_format.

Use the RGBA format with opaque drawing to ignore the missing alpha channel.

It also enables the complete removal of OpenGL usage in the plugin.

The same method is applied to 10-bit RGBX to ensure that the non-existing alpha channel is ignored.

Made the usage of gs_texture_create_from_dmabuf use the gs_format associated with the DRM format and not BGRX for any format.

Motivation and Context

I really wanted to remove the usage of OpenGL in the plugin.

How Has This Been Tested?

Forced the opaque effect to ensure that cursor was drawn correctly. Otherwise no testing with real RGBX was made.

Types of changes

  • Tweak (non-breaking change to improve existing functionality)

Checklist:

  • [x] My code has been run through clang-format.
  • [x] I have read the contributing document.
  • [x] My code is not on the master branch.
  • [x] The code has been tested.
  • [x] All commit messages are properly formatted and commits squashed where appropriate.
  • [x] I have included updates to all appropriate documentation.

tytan652 avatar Jul 29 '25 11:07 tytan652

This is used to swap the colors not to ignore the alpha channel, so it really does need to be tested with an RGBA and RGBX texture.

kkartaltepe avatar Jul 29 '25 15:07 kkartaltepe

This is used to swap the colors not to ignore the alpha channel

The swap was made to put the RGBX DMA-BUF of the ScreenCast in a BGRX texture due to the lack of support of RGBX in libobs as a gs_format. To avoid the swap putting the DMA-BUF in RGBA with an opaque effect seems right to me.

tytan652 avatar Jul 29 '25 17:07 tytan652

Forgive me for maybe asking stupid question, but maybe someone can clear this up for me:

  • In gl_egl_create_texture_from_eglimage we call gs_texture_create with the GS_GL_DUMMYTEX flag
  • This should effectively mean that the colour format passed to the function (currently BGRX) is irrelevant, as gl_init_face is never called. The colour formats are set on the gs_texture structure, but never passed to OpenGL itself
  • Which makes sense, because from what I read about glEGLImageTargetTexture2DOES, the currently bound texture object is replaced in its entirety with an alias to the shared buffer.

By this point the format properties of gs_texture are unrelated to the actual image format of the OpenGL texture object and I expect the OES texture to have all the properties required for OpenGL to be able to read image data from it correctly.

Are there other instances in our code where the gl_format or gl_internal_format properties of gs_texture are used in relation to PipeWire? In general it might be necessary for that format to be correct when something like glReadPixels is used to copy the image data to a CPU-bound buffer, and then gl_format and gl_type need to represent the actual format of the OES texture.

PatTheMav avatar Aug 07 '25 15:08 PatTheMav

the actual format of the OES texture.

This is not an OES texture, we use TEXTURE_2D with glEGLImageTargetTexture2DOES which its behavior is defined in the OES_EGL_image extension.

https://registry.khronos.org/OpenGL/extensions/OES/OES_EGL_image.txt

tytan652 avatar Aug 07 '25 17:08 tytan652

the actual format of the OES texture.

This is not an OES texture, we use TEXTURE_2D with glEGLImageTargetTexture2DOES which its behavior is defined in the OES_EGL_image extension.

https://registry.khronos.org/OpenGL/extensions/OES/OES_EGL_image.txt

Correct and I'm referencing this part of the document that applies to TEXTURE_2D type variants:

The command

   void EGLImageTargetTexture2DOES(enum target, eglImageOES image);

defines an entire two-dimensional texture array. All properties of the texture images (including width, height, format, border, mipmap levels of detail, and image data) are taken from the specified eglImageOES , rather than from the client or the framebuffer.

Which to me sounds as if it is irrelevant which properties we set (and as I mentioned above, we don't set anything because it's a "dummy" texture), because the format specifically is "taken from the specified eglImageOES".

PatTheMav avatar Aug 07 '25 18:08 PatTheMav