-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Various DRM Atomic improvements #5714
Conversation
video/out/opengl/context_drm_egl.c
Outdated
p->osd_size.width = p->kms->mode.hdisplay; | ||
p->osd_size.height = p->kms->mode.vdisplay; | ||
} else { | ||
if (!p->kms->atomic_context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On both of these ifs, remove the !
, and switch the if/else bodies.
video/out/opengl/libmpv_gl.c
Outdated
ra_add_native_resource(ctx->ra, "drm_params", drm_params); | ||
void *drm_osd_size = p->gl->MPGetNativeDisplay("drm_osd_size"); | ||
if (drm_osd_size) | ||
ra_add_native_resource(ctx->ra, "drm_osd_size", drm_osd_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just compatibility code. It should not be needed since there are no API users which use the legacy opengl-cb API and the new DRM stuff. And a new API user can't use this at all, unless he's using the opengl-cb legacy pseudo GL extension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you meaning that I should have added a param on the new API for both structs ?
If so that would come in a next step I guess. If not can you please gimme some more details :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not sure if I agree that the compat stuff should stay here, since the new API has proper support for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand what you mean, but unless i missed something, there is no other way to have access to this from the hwdec ... the params array is not passed there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The quoted code is explicitly for the legacy opengl-cb code, which uses glMPGetNativeDisplay. That doesn't exist in the new render API and is not used there.
@@ -47,12 +47,18 @@ const struct m_sub_options drm_conf = { | |||
OPT_STRING_VALIDATE("drm-connector", drm_connector_spec, | |||
0, drm_validate_connector_opt), | |||
OPT_INT("drm-mode", drm_mode_id, 0), | |||
OPT_INT("drm-overlay", drm_overlay_id, 0), | |||
OPT_INT("drm-osd-plane-id", drm_osd_plane_id, 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we not document these options as well? If we do we probably also need to clarify when what plane is used. That only when using drmprime hwdec is the video actually rendered to the video plane, and the "overlay plane" is the normal plane &c.
I guess we could consider it internal/primarily for API use due to the confusing nature...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All options must be documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, I thought I had done it, but will add it.
cda4db6
to
1562411
Compare
Fixed the comments above, thanks to lemme know if you have any further comments :) |
DOCS/man/vo.rst
Outdated
Index is zero based, and related to crtc. | ||
(default: first overlay plane) | ||
|
||
``--drm-video-plane-id=<number>`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the nitpicking, but we should probably mention that this is only really the case when we use drmprime hwdec with --vo=gpu --gpu-context=drm, and that otherwise (this includes --vo=drm) the video plane is unused with the osd plane instead being used for both video and OSD.
I know it's a bit late, but I've been thinking that maybe different naming for the planes could be used here to make the matter less confusing. Maybe something like "drm-render-plane-id" (for what is now "drm-osd-plane-id") and "drm-hwdec-video-plane-id" (for what is now "drm-video-plane-id"), for example. (Although this particular naming would of course not be forward-compatible if we decide to use separate planes for video/OSD in the software decoded case in the future.)
What do you think (and if anyone has better naming ideas please say)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you're saying. Although we have to consider that options should have a not too much technical name. hwdec probably don't mean anything for most users typically :)
But as you say, in some cases both video & osd are on the same plane (in which case btw you probably don't want any of those options, primary plane will be used then).
Maybe mentioning that those options should be used in the case you mentioned would be enough to clarify that case ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mentioning that the options should primarily be used together with drmprime hwdec, and that in other cases (--vo=drm, --gpu-context=drm swdec) everything will be rendered to the "osd plane" should be fairly sufficient, should we keep the current names.
Re: the names: yeah, my names were just examples. I think maybe better ones than that could be thought of.
1562411
to
6c30576
Compare
Adjusted documentation description :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some small grammar gripes.
DOCS/man/vo.rst
Outdated
Select the DRM planed index to use for video layer. | ||
Index is zero based, and related to crtc. | ||
This option is only valid when using the drm_prime renderer which supports | ||
several layers and with ``vo=gpu`` and ``gpu-context=drm``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use commas or parentheses around "which supports several layers".
"and with" -> "together with"
also perhaps "only valid" -> "only has an effect", since it is technically valid (i.e. mpv won't complain), it just won't do anything useful.
DOCS/man/vo.rst
Outdated
Select the DRM planed index to use for OSD (or OSD and video). | ||
Index is zero based, and related to crtc. | ||
When using this option with drm_prime renderer, it will only affect | ||
the OSD contents. Otherwise will set OSD & video plane. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Otherwise will set..." -> "Otherwise it will set..."
6c30576
to
b5932dd
Compare
grammar gripes processed :) |
So I finally got around to testing it on an intel with more than one connector, and I saw some regressions (Sandybridge, linux 4.16.0, mesa-18.0.0). I think it's related to the new atomic modesetting primarily, although I haven't looked too much into it yet so I can't entirely rule out the new connector handling (will do later). It might also be simply that atomic modesetting is not yet implemented for these old GPU:s, in which case we will need to have a fallback (still use atomic commits, but do the modesetting as before), however I think I've been able to run a kmscube implementation that uses atomic modesetting fine (will test later) on sandybridge. On to the tests I did: It works but with a warning on the internal LVDS panel, but probably only because it only supports one resolution, and it will work without modesetting: On the HDMI-A-1 connector it fails hard: If I first use the HDMI-A-1 panel using -vo drm, or just an mpv without this PR the fbcon on this VT seems to to change a bit and the LVDS screen gets deactivated (multi-screen setups is something which could use some improvement, but that is another problem for another day. both deinit and in particular VT switching are a bit flakey) and the HDMI-A-1 screen takes on a "main" role. Now I can actually do some of the lower resolutions (with warning messages) on the HDMI, but not above 1024x768 or so (I guess because of the resolution the fbcon picked for HDMI-A-1 after mpv closed). I also tried some VT switching now, to see if I would get more error messages: I guess this latter case is similar to the first with LVDS though, that we simply got lucky because the fbcon was already setup somehow. |
@xantoz : any more investigations ? Would you have any suggestions regarding this PR ? |
@wm4 : by the way, anymore comments from your side ? :) |
libmpv/render_gl.h
Outdated
} mpv_opengl_drm_params; | ||
|
||
typedef struct mpv_opengl_drm_osd_size { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird newline.
libmpv/render.h
Outdated
* Valid for mpv_render_context_create(). | ||
* Type : struct mpv_opengl_drm_osd_size* | ||
*/ | ||
MPV_RENDER_PARAM_DRM_OSD_SIZE = 11, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently your code expects that the pointers the user passes are valid for the life time of the context, which I'd find surprising. I think the structs really should be copied (and then use pointers for fields which somehow need to be changed per frame or something). That would require changes in libmpv_gpu.c (init() function). I guess native_resource_map needs to be changed into an array of structs, so a struct size to copy can be specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The drmModeAtomicRequest pointer which is what you're referring to as changing every frame is in that struct and already passed as a pointer to the pointer address. So copying this should still be possible.
But yes you are right on the fact that I have been assuming that the struct keeps being alive during the whole playback. If some change is made to the native_resource_map, we can probably use a copy to overcome this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added such a change here: 0bfdb00
You'd simply set the .size field to the struct sizes, and it'd copy them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's part of #5716 btw., which somehow turned into a PR for general changes.
@LongChair I'm still working on it, but I can already tell you I get problems already with commit 540fec5 (can't use --drm-format=xrgb2101010 with -vo gpu. when it does work I get black bars through it. next commit fixes this though, but introduces the modesetting errors. have yet to test with a multi-screen setup) so it is probably not solely atomic modesetting related. |
video/out/drm_atomic.c
Outdated
struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, | ||
int crtc_id, int overlay_id) | ||
struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, int crtc_id, | ||
int connector_id, int osd_plane_id, int video_plane_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not use tabs for indentation
video/out/drm_atomic.c
Outdated
} | ||
else if (value == DRM_PLANE_TYPE_PRIMARY) { | ||
ctx->primary_plane = plane; | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trailing whitespace
Select the DRM overlay index to use. | ||
Overlay index is zero based, and related to crtc. | ||
(default: 0) | ||
``--drm-osd-plane-id=<number>`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the documentation of these options (--drm-osd-plane-id, --drm-video-plane-id) from this commit, to commit 540fec5 when they are introduced in the code.
Like now the documentation will have been introduced before the options.
video/out/opengl/context_drm_egl.c
Outdated
|
||
ra_add_native_resource(ctx->ra, "drm_params", &p->drm_params); | ||
ra_add_native_resource(ctx->ra, "drm_osd_size", &p->osd_size); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trailing whitespace
On 540fec5, selecting --drm-osd-plane-id=0 fixes the problem with not being able to use XRGB2101010, so there might be something related to the plane ID:s. I think maybe the way we select ID:s in drm_atomic_create_context needs to be rethought. |
video/out/drm_atomic.c
Outdated
if (!ctx->primary_plane) { | ||
mp_err(log, "Failed to find primary plane\n"); | ||
goto fail; | ||
// default OSD plane to overlay if unspecified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swap this around? OSD plane defaults to primary plane if unspecified. Then behavior would be like before, especially w.r.t. to software decoding, and --drm-format=xrgb2101010 would still work on intel without specifying the primary plane with --drm-osd-plane-id
An idea to make this nicer to use would be to add the options --drm-osd-plane-id=(primary|overlay) and --drm-video-plane-id=(primary|overlay), which will pick any matching overlay/primary plane instead of a specific numbered one. (Although I would still argue that --drm-osd-plane-id should default to primary, and --drm-video-plane-id default to overlay in this case, but even if it didn't I could just put drm-osd-plane-id=primary in my config file and it would Just Work (TM))
video/out/drm_atomic.c
Outdated
if (!ctx->overlay_plane) { | ||
mp_err(log, "Failed to find overlay plane with id=%d\n", overlay_id); | ||
goto fail; | ||
// default video plane to primary if unspecified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default video plane to overlay
You've missed to change "primary plane" to "OSD plane" (or whatever we're going to end up calling it) in a few log messages and comments in context_drm_egl.c |
I have made a pull request on LongChair:s atomic-additions branch with the changes needed to get this PR working for me (LongChair#1) Now waiting for LongChair to test that these changes are compatible with his use-case. |
That new API was introduced and allows to have several native resources. Thisuses that mechanisma for drm resources rather than the deprecated opengl-cb structs. This patch therefore add two structs that can be used with the drm atomic interop. - mpv_opengl_drm_params : which will hold all the drm handles - mpv_opengl_drm_osd_size : which will hold osd layer size This commit adds a drm-osd-size=WxH parameter to commandline which allows to define the OSD plane dimension. OSD can be upscaled to screen resolution when having OSD at video resolution is too heavy. This is especially useful for UHD modes on embedded devices where the GPU cannot handle UHD modes at a decent framerate.
This patch adds - DRM connector object to atomic context. - fd property to the drm atomic object as well as a method to read blob type properties. This allows to ensure that the proper connector is picked up, especially when specifying it from the commandline, and also allows to make sure we're using the right one when embedding with interop into an application.
b5932dd
to
ff58919
Compare
Updated this PR according to comments. |
We are currently using primary / overlay planes drm objects, assuming that primary plane is osd and overlay plane is video. This commit is doing two things : - replace the primary / overlay planes members with osd and video planes member without the assumption - Add two more options to determine which one of the primary / overlay is associated to osd / video. - It will default osd to overlay and video to primary if unspecified
This commit allows to add atomic modesetting when using the atomic renderer. This is actually needed when using and osd with a smaller size than screen resolution. It will also make the drm atomic path more consistent
This patch will make sure that the video plane is hidden when unused. When using high resolution modes, typically UHD, and embedding mpv, having the video plane sitting in the back when you don't play any video is eating a lot of memory bandwidth for compositing. That patch makes sure that the video layer is just disabled before and after playback.
Add some properties which where forgotten in crtc_setup_atomic. In both change to not use DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK flags. This should make it more similar to the drmSetCrtc which it aims to replace (take effect directly, and blocking call). This also saves us the trouble of having to set up a poll to wait for pageflip, which would've been neccesary with DRM_MODE_PAGE_FLIP_EVENT, in both crtc_setup_atomic and crtc_release_atomic.
… updated since the plane rename commit
Inspired by kmscube, first try to pick the Encoder and CRTC already associated with the selected Connector, if any. Otherwise try to find the first matching encoder & CRTC like before. The previous behavior had problems when using atomic modesetting (crtc_setup_atomic) when we picked an Encoder & CRTC that was currently being used by the fbcon together with another Encoder. drmModeSetCrtc was able to "steal" the CRTC in this case, but using atomic modesetting we do not seem to get this behavior automatically. This should also improve behavior somewhat when run on a multi screen setup with regards to deinit and VT switching (still sometimes you end up with a blank screen where you previously had a cloned display of your fbcon)
ff58919
to
56d4541
Compare
Looks generally good to me. I'd like to improve the options a little bit (So that we can specify --drm-osd-plane-id=primary or --drm-osd-plane-id=overlay, for getting a generic plane for instance, since using the indexes like now is hard. Maybe also adding a help option?), but I will do that in a later PR which I create, so I think we should merge this first. |
@wm4 : any further comments from your side ? :) |
No. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM. Will push a minor typo fixup commit after merging that fixes some planed
s in vo.rst :)
Have tested that it compiles, and that generally the code seems to look OK and documentation is added for new options. @LongChair is pretty much the DRM maintainer and this PR touches almost fully just it. |
Here are a few commits that intend to improve drm atomic support.
The main topic there are taking care of are :
cc @wm4 @xantoz
I agree that my changes can be relicensed to LGPL 2.1 or later.