vout_display_opengl code has separate prepare() and display(), which
might or might not match vout_display's prepare()/display() calls, now
that the opengl swap() is not done by the vout_display_opengl code.
Now that we splitted the vlc_gl_Swap() call from the rendering, there's
no excuse for starting rendering sooner so that the result starts to be
available when executing display() and will almost be ready for
presentation.
is_dirty is there to indicate whether vlc_gl_MakeCurrent failed and thus
the frame could not be rendered, to avoid swapping undefined content.
The display code is better suited to execute Swap() than the
vout_display_opengl object, since:
- It actually knows whether it's an on-screen or off-screen
implementation.
- It could add code to render more things between swapping.
- In particular, it could render, but discard the rendering instead of
swapping depending on the time spent or GPU state/chrono.
Since the vout display work is splitted between prepare() and display(),
the flush is useful to ensure everything has been submitted by the end
of prepare() so that the result can be used in display().
The vlc_gl_t API doesn't require the context to be current to call
vlc_gl_Swap(), but EGL needs it. Allowing vlc_gl_Swap from being called
outside of vlc_gl_MakeCurrent/ReleaseCurrent will allow to remove the
MakeCurrent/ReleaseCurrent mechanism and have the OpenGL provider pull
for a frame rendering instead of the code waiting on draw commands for
OpenGL to be ready to render, which is functionnally the same, but will
allow implementations like macosx.m or caopengllayer.m to be a real
OpenGL implementation instead of dummy provider around a display module.
The existing code was blindly trusting that the provided object name
corresponded to a wl_output object and proxied it. This checks
that the ID corresponds to an already proxied object instead.
wl_output protocol versions 2 and larger involve more than one callback
to describe the outputs. The `done` callback indicates that all
callbacks have been invoked.
For backward compatibility with version 1, the `done` callback is
triggered manually, though I doubt that we can meaningfully support
version 1 going forward.
Rework resizing as a display-only module without windowing.
Since there's no window to resize this component (and it handles resize
internally), we can accept the display size events without changing
the rendering state, and will only react to the internal resize events
from the embedded NSView.
Fix#26846
Refs #25264
The _pendingReshape mechanism was used to avoid redrawing the view if it
has been updated externally, and avoid re-render the view when it's
being drawn already but:
- `drawRect:` won't be called if we didn't change the window, except
the first time which will likely trigger a clear.
- When the window state changes, we were already setting
_pendingReshape to YES.
Overall, we can let the UI system decide when it requires a re-draw and
react to that instead of trying to workaround when to re-draw.
The current vout display module is resizing from its own view and tries
to notify the video view changes to the parent. But it can already
resize, so it doesn't need the core to resize the input picture, and
would already know the size it can render to.
It makes reporting the vout display size from the vout useless, and even
harmful since the display will re-enter itself on resize.
sys->embed was confusing when the NSView could come from either the
drawable variable or the window provider, and the view is now given
through the display configuration in any case, so it doesn't need to be
stored again.
The drawable NSObject is now provided through the window and the code is
the same both for a vout_window-provided NSObject or a libvlc NSObject
drawable so we can simplify here now.
This also prevent the leak of sys happening when the wrong type of
window is used when opening the display, and move the test after the
trivial check for window type.
VLC_CODEC_VAAPI_420_10BPP is equivalent to VLC_FOURCC_P010 and has a
plane description that is like NV12, so it should not be different from
NV12. Only the bits per component, and so texture storage type is
changing for this format.
It was leading to incorrect or green color rendering with vaapi.
Regression from c344522ff2.
Fixes#26883
../../modules/video_output/libplacebo/utils.c: In function ‘vlc_placebo_DoviMetadata’:
../../modules/video_output/libplacebo/utils.c:472:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
472 | for (int c = 0; c < ARRAY_SIZE(dst->comp); c++) {
| ^
../../modules/video_output/libplacebo/utils.c:486:35: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
486 | for (int k = 0; k < ARRAY_SIZE(cdst->poly_coeffs[i]); k++) {
| ^
../../modules/video_output/libplacebo/utils.c:496:39: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
496 | for (int k = 0; k < ARRAY_SIZE(cdst->mmr_coeffs[i][j]); k++)
| ^
This and the previous commit ensure that the new CAOpenGLLayer based
video output is used on macOS 10.14 and higher if the output selection
is set to automatic.
Forward-port from 3.0.x branch.
Cherry-picked from commit bbd1dca5df.
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
The display currently requires an NSObject window which is will be
fetched from a drawable window module in next patch. Fetching the
drawable from the display is not necessary anymore.
DISPLAY_SIZE controls are emitted by the windowing system to control the
display state, but the caopengllayer display module is handling its own
windowing state without window and doesn't need to react to those events.
Instead, store the new size into the internal vout_display_cfg_t and
avoid trying to report the size to itself.
Fixes#26845
Refs #25264
use layoutSublayers instead of resizeWithOldSuperlayerSize: as the
resizeWithOldSuperlayerSize: method is not called when compiled with
10.13 SDK, possibly because then the layer is not in a full layer tree
so has no superlayer eventually. So using layoutSublayers feels more
correct to be called when a layout change occurs.
Fix#24559
Forward-port from 3.0.x branch.
Cherry-picked from commit 11591b11c0.
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
Other views might need the mouse events as well. Do the analog
logic as in the old macosx vout module.
Fixes steering of fullscreen panel.
fixes#24560
Signed-off-by: Marvin Scholz <epirat07@gmail.com>
Forward-port from 3.0.x branch.
Cherry-picked from commit 4d98f418ee.
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
Changing from a retina screen to a non-retina screen changes the
scale of the layer, so from point of view of the OpenGL code, the
size of the surface changes. Therefore we need to signal this change
so that the size is adapted correctly.
This is not a perfect solution as the size event will arrive too late
so for a few frames the wrong size can still be seen before it switches
to the new size. Ideally this would be handled like the live resize
but so far I have not found a good solution for how to do that.
Forward-port from 3.0.x branch.
Cherry-picked from commit 57401f907c.
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
Rewrites most of the layer vout code to have the same features as the
view based vout. Additionally fixes laggy resizing, fixes CGL context
creation bugs, adds support for CI filters and fixes various memory
management errors.
The CAOpenGLLayer based API is special and different from all other APIs
provided on other OSes as it is not a push-model API but a pull one,
where the OS calls a specific method when a new frame should be rendered.
This makes integration into VLC relatively tricky and the code a bit
harder to follow.
While the API is a pull-model, we can kind of trick it by just forcing
a re-display of the layer in the vouts display function. With views this
would be forbidden as views are supposed to be accessed from the main
thread only, but with layers this is possible if some care is taken.
When forcing the layer to render from a different thread, the implicitly
created CATransaction has to be flushed explicitly, as we do not have a
main loop at the end of which it would be flushed.
We do not force rendering all the time though, as doing that would break
resize animations given that VLC can not know the right time when display
refresh will happen, so resizing would look laggy and have glitches, as
during a resize both the OS and VLC would drive the rendering of the
layer, resulting in unexpected result.
To prevent that, when live resizing starts (the user resizing by dragging
a windows corner), the layer is set into asynchronous rendering mode
which makes the OS drive the rendering loop completely not only for
drawing the resize change. While the layer is in asynchronous mode, we
ignore all update requests from the core, as the layer is anyway updated
continuously by the OS and forcing rendering from another thread would
lead to artifacts. Additionally while in live resize, we do not report
the size changes to the core, as the event takes too long to reach the
vout Control() function, resulting in the layer content being displayed
at the wrong (old) size. Instead we take the current viewport size
as the size and display using that.
Another unusual thing compared to other vouts is that the VLC OpenGL
display functions to update the viewport and aspect ratio are not
called in the Control event handling callback, thats because before
the render callback is called, the OS sets the OpenGL viewport to match
the layer backing store size. So setting it in the Control callback
is useless as it does not make any difference.
Forward-port from 3.0.x branch.
Cherry-picked from commit 879ca61f8c.
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
Noticeable changes:
- vlc_object_release has been changed into vlc_object_delete
The CGL context was destroyed too early, so move around the
vout display removal to prevent using the already-gone context.
Forward port from 3.0.x branch.
Cherry-picked from commit 7d1e7f289d.
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
This is anyway not properly supported currently so opting in to it
here does not change anything for the better.
Forward port from 3.0.x branch.
Cherry-picked from commit 4591255d8e.
Signed-off-by: Alexandre Janniaux <ajanni@videolabs.io>
sys->embed was used to store the window created from the display in
pre-3.0 design, but now the display is created after the window and the
window is available in vd->cfg->window.
The sys->embed was storing the same pointer in the normal case, but
ironically, it was undefined in the libvlc embedding case and was
leading to crash.
It is not used in POSIX systems. On other system it probably don't make a
difference anymore, only Windows has actual useful values for
VLC_THREAD_PRIORITY_XXX. The synchronization is more important than having some
threads called more often than others.