Branch data Line data Source code
1 : : /*
2 : : * This file is part of libplacebo.
3 : : *
4 : : * libplacebo is free software; you can redistribute it and/or
5 : : * modify it under the terms of the GNU Lesser General Public
6 : : * License as published by the Free Software Foundation; either
7 : : * version 2.1 of the License, or (at your option) any later version.
8 : : *
9 : : * libplacebo is distributed in the hope that it will be useful,
10 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : : * GNU Lesser General Public License for more details.
13 : : *
14 : : * You should have received a copy of the GNU Lesser General Public
15 : : * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
16 : : */
17 : :
18 : : #ifndef LIBPLACEBO_RENDERER_H_
19 : : #define LIBPLACEBO_RENDERER_H_
20 : :
21 : : #include <libplacebo/config.h>
22 : : #include <libplacebo/colorspace.h>
23 : : #include <libplacebo/filters.h>
24 : : #include <libplacebo/gpu.h>
25 : : #include <libplacebo/shaders/colorspace.h>
26 : : #include <libplacebo/shaders/deinterlacing.h>
27 : : #include <libplacebo/shaders/dithering.h>
28 : : #include <libplacebo/shaders/film_grain.h>
29 : : #include <libplacebo/shaders/icc.h>
30 : : #include <libplacebo/shaders/lut.h>
31 : : #include <libplacebo/shaders/sampling.h>
32 : : #include <libplacebo/shaders/custom.h>
33 : : #include <libplacebo/swapchain.h>
34 : :
35 : : PL_API_BEGIN
36 : :
37 : : // Thread-safety: Unsafe
38 : : typedef struct pl_renderer_t *pl_renderer;
39 : :
40 : : // Enum values used in pl_renderer_errors_t as a bit positions for error flags
41 : : enum pl_render_error {
42 : : PL_RENDER_ERR_NONE = 0,
43 : : PL_RENDER_ERR_FBO = 1 << 0,
44 : : PL_RENDER_ERR_SAMPLING = 1 << 1,
45 : : PL_RENDER_ERR_DEBANDING = 1 << 2,
46 : : PL_RENDER_ERR_BLENDING = 1 << 3,
47 : : PL_RENDER_ERR_OVERLAY = 1 << 4,
48 : : PL_RENDER_ERR_PEAK_DETECT = 1 << 5,
49 : : PL_RENDER_ERR_FILM_GRAIN = 1 << 6,
50 : : PL_RENDER_ERR_FRAME_MIXING = 1 << 7,
51 : : PL_RENDER_ERR_DEINTERLACING = 1 << 8,
52 : : PL_RENDER_ERR_ERROR_DIFFUSION = 1 << 9,
53 : : PL_RENDER_ERR_HOOKS = 1 << 10,
54 : : PL_RENDER_ERR_CONTRAST_RECOVERY = 1 << 11,
55 : : };
56 : :
57 : : // Struct describing current renderer state, including internal processing errors,
58 : : // as well as list of signatures of disabled hooks.
59 : : struct pl_render_errors {
60 : : enum pl_render_error errors;
61 : : // List containing signatures of disabled hooks
62 : : const uint64_t *disabled_hooks;
63 : : int num_disabled_hooks;
64 : : };
65 : :
66 : : // Creates a new renderer object, which is backed by a GPU context. This is a
67 : : // high-level object that takes care of the rendering chain as a whole, from
68 : : // the source textures to the finished frame.
69 : : PL_API pl_renderer pl_renderer_create(pl_log log, pl_gpu gpu);
70 : : PL_API void pl_renderer_destroy(pl_renderer *rr);
71 : :
72 : : // Returns current renderer state, see pl_render_errors.
73 : : PL_API struct pl_render_errors pl_renderer_get_errors(pl_renderer rr);
74 : :
75 : : // Clears errors state of renderer. If `errors` is NULL, all render errors will
76 : : // be cleared. Otherwise only selected errors/hooks will be cleared.
77 : : // If `PL_RENDER_ERR_HOOKS` is set and `num_disabled_hooks` is 0, clear all hooks.
78 : : // Otherwise only selected hooks will be cleard based on `disabled_hooks` array.
79 : : PL_API void pl_renderer_reset_errors(pl_renderer rr,
80 : : const struct pl_render_errors *errors);
81 : :
82 : : enum pl_lut_type {
83 : : PL_LUT_UNKNOWN = 0,
84 : : PL_LUT_NATIVE, // applied to raw image contents (after fixing bit depth)
85 : : PL_LUT_NORMALIZED, // applied to normalized (HDR) RGB values
86 : : PL_LUT_CONVERSION, // LUT fully replaces color conversion
87 : :
88 : : // Note: When using a PL_LUT_CONVERSION to replace the YUV->RGB conversion,
89 : : // `pl_render_params.color_adjustment` is no longer applied. Similarly,
90 : : // when using a PL_LUT_CONVERSION to replace the image->target color space
91 : : // conversion, `pl_render_params.color_map_params` are ignored.
92 : : //
93 : : // Note: For LUTs attached to the output frame, PL_LUT_CONVERSION should
94 : : // instead perform the inverse (RGB->native) conversion.
95 : : //
96 : : // Note: PL_LUT_UNKNOWN tries inferring the meaning of the LUT from the
97 : : // LUT's tagged metadata, and otherwise falls back to PL_LUT_NATIVE.
98 : : };
99 : :
100 : : enum pl_clear_mode {
101 : : PL_CLEAR_COLOR = 0, // set texture to a solid color
102 : : PL_CLEAR_TILES, // set texture to a tiled pattern
103 : : PL_CLEAR_SKIP, // skip the clearing pass (no-op)
104 : : PL_CLEAR_MODE_COUNT,
105 : : };
106 : :
107 : : enum pl_render_stage {
108 : : PL_RENDER_STAGE_FRAME, // full frame redraws, for fresh/uncached frames
109 : : PL_RENDER_STAGE_BLEND, // the output blend pass (only for pl_render_image_mix)
110 : : PL_RENDER_STAGE_COUNT,
111 : : };
112 : :
113 : : struct pl_render_info {
114 : : const struct pl_dispatch_info *pass; // information about the shader
115 : : enum pl_render_stage stage; // the associated render stage
116 : :
117 : : // This specifies the chronological index of this pass within the frame and
118 : : // stage (starting at `index == 0`).
119 : : int index;
120 : :
121 : : // For PL_RENDER_STAGE_BLEND, this specifies the number of frames
122 : : // being blended (since that results in a different shader).
123 : : int count;
124 : : };
125 : :
126 : : // Represents the options used for rendering. These affect the quality of
127 : : // the result.
128 : : struct pl_render_params {
129 : : // Configures the algorithms used for upscaling and downscaling,
130 : : // respectively. If left as NULL, then libplacebo will only use inexpensive
131 : : // sampling (bilinear or nearest neighbour depending on the capabilities
132 : : // of the hardware / texture).
133 : : //
134 : : // Note: Setting `downscaler` to NULL also implies `skip_anti_aliasing`,
135 : : // since the built-in GPU sampling algorithms can't anti-alias.
136 : : //
137 : : // Note: If set to the same address as the built-in `pl_filter_bicubic`,
138 : : // `pl_filter_nearest` etc.; libplacebo will also use the more efficient
139 : : // direct sampling algorithm where possible without quality loss.
140 : : const struct pl_filter_config *upscaler;
141 : : const struct pl_filter_config *downscaler;
142 : :
143 : : // If set, this overrides the value of `upscaler`/`downscaling` for
144 : : // subsampled (chroma) planes. These scalers are used whenever the size of
145 : : // multiple different `pl_plane`s in a single `pl_frame` differ, requiring
146 : : // adaptation when converting to/from RGB. Note that a value of NULL simply
147 : : // means "no override". To force built-in scaling explicitly, set this to
148 : : // `&pl_filter_bilinear`.
149 : : const struct pl_filter_config *plane_upscaler;
150 : : const struct pl_filter_config *plane_downscaler;
151 : :
152 : : // The anti-ringing strength to apply to filters. See the equivalent option
153 : : // in `pl_sample_filter_params` for more information.
154 : : float antiringing_strength;
155 : :
156 : : // Configures the algorithm used for frame mixing (when using
157 : : // `pl_render_image_mix`). Ignored otherwise. As a special requirement,
158 : : // this must be a filter config with `polar` set to false, since it's only
159 : : // used for 1D mixing and thus only 1D filters are compatible.
160 : : //
161 : : // If set to NULL, frame mixing is disabled, in which case
162 : : // `pl_render_image_mix` will use nearest-neighbour semantics. (Note that
163 : : // this still goes through the redraw cache, unless you also enable
164 : : // `skip_caching_single_frame`)
165 : : const struct pl_filter_config *frame_mixer;
166 : :
167 : : // Configures the settings used to deband source textures. Leaving this as
168 : : // NULL disables debanding.
169 : : //
170 : : // Note: The `deband_params.grain` setting is automatically adjusted to
171 : : // prevent blowing up on HDR sources. The user need not account for this.
172 : : const struct pl_deband_params *deband_params;
173 : :
174 : : // Configures the settings used to sigmoidize the image before upscaling.
175 : : // This is not always used. If NULL, disables sigmoidization.
176 : : const struct pl_sigmoid_params *sigmoid_params;
177 : :
178 : : // Configures the color adjustment parameters used to decode the color.
179 : : // This can be used to apply additional artistic settings such as
180 : : // desaturation, etc. If NULL, defaults to &pl_color_adjustment_neutral.
181 : : const struct pl_color_adjustment *color_adjustment;
182 : :
183 : : // Configures the settings used to detect the peak of the source content,
184 : : // for HDR sources. Has no effect on SDR content. If NULL, peak detection
185 : : // is disabled.
186 : : const struct pl_peak_detect_params *peak_detect_params;
187 : :
188 : : // Configures the settings used to tone map from HDR to SDR, or from higher
189 : : // gamut to standard gamut content. If NULL, defaults to
190 : : // `&pl_color_map_default_params`.
191 : : const struct pl_color_map_params *color_map_params;
192 : :
193 : : // Configures the settings used to dither to the output depth. Leaving this
194 : : // as NULL disables dithering.
195 : : const struct pl_dither_params *dither_params;
196 : :
197 : : // Configures the error diffusion kernel to use for error diffusion
198 : : // dithering. If set, this will be used instead of `dither_params` whenever
199 : : // possible. Leaving this as NULL disables error diffusion.
200 : : const struct pl_error_diffusion_kernel *error_diffusion;
201 : :
202 : : // Configures the settings used to simulate color blindness, if desired.
203 : : // If NULL, this feature is disabled.
204 : : const struct pl_cone_params *cone_params;
205 : :
206 : : // Configures output blending. When rendering to the final target, the
207 : : // framebuffer contents will be blended using this blend mode. Requires
208 : : // that the target format has PL_FMT_CAP_BLENDABLE. NULL disables blending.
209 : : const struct pl_blend_params *blend_params;
210 : :
211 : : // Configures the settings used to deinterlace frames (see
212 : : // `pl_frame.field`), if required.. If NULL, deinterlacing is "disabled",
213 : : // meaning interlaced frames are rendered as weaved frames instead.
214 : : //
215 : : // Note: As a consequence of how `pl_frame` represents individual fields,
216 : : // and especially when using the `pl_queue`, this will still result in
217 : : // frames being redundantly rendered twice. As such, it's highly
218 : : // recommended to, instead, fully disable deinterlacing by not marking
219 : : // source frames as interlaced in the first place.
220 : : const struct pl_deinterlace_params *deinterlace_params;
221 : :
222 : : // If set, applies an extra distortion matrix to the image, after
223 : : // scaling and before presenting it to the screen. Can be used for e.g.
224 : : // fractional rotation.
225 : : //
226 : : // Note: The distortion canvas will be set to the size of `target->crop`,
227 : : // so this cannot effectively draw outside the specified target area,
228 : : // nor change the aspect ratio of the image.
229 : : const struct pl_distort_params *distort_params;
230 : :
231 : : // List of custom user shaders / hooks.
232 : : // See <libplacebo/shaders/custom.h> for more information.
233 : : const struct pl_hook * const *hooks;
234 : : int num_hooks;
235 : :
236 : : // Color mapping LUT. If present, this will be applied as part of the
237 : : // image being rendered, in normalized RGB space.
238 : : //
239 : : // Note: In this context, PL_LUT_NATIVE means "gamma light" and
240 : : // PL_LUT_NORMALIZED means "linear light". For HDR signals, normalized LUTs
241 : : // are scaled so 1.0 corresponds to the `pl_color_transfer_nominal_peak`.
242 : : //
243 : : // Note: A PL_LUT_CONVERSION fully replaces the color adaptation from
244 : : // `image` to `target`, including any tone-mapping (if necessary) and ICC
245 : : // profiles. It has the same representation as PL_LUT_NATIVE, so in this
246 : : // case the input and output are (respectively) non-linear light RGB.
247 : : const struct pl_custom_lut *lut;
248 : : enum pl_lut_type lut_type;
249 : :
250 : : // Controls how the image background is drawn for transparent images.
251 : : enum pl_clear_mode background;
252 : :
253 : : // Controls how the remaining empty space in the target is filled up, when
254 : : // the image does not span the entire framebuffer.
255 : : enum pl_clear_mode border;
256 : :
257 : : // The color to use for PL_CLEAR_COLOR.
258 : : //
259 : : // Note: Despite the name, this also affects `border = PL_CLEAR_COLOR`.
260 : : float background_color[3];
261 : : float background_transparency; // 0.0 for opaque, 1.0 for fully transparent
262 : :
263 : : // The color and size to use for PL_CLEAR_TILES
264 : : float tile_colors[2][3];
265 : : int tile_size;
266 : :
267 : : // If set to a value above 0.0, the output will be rendered with rounded
268 : : // corners, as if an alpha transparency mask had been applied. The value
269 : : // indicates the relative fraction of the side length to round - a value
270 : : // of 1.0 rounds the corners as much as possible.
271 : : float corner_rounding;
272 : :
273 : : // --- Performance / quality trade-off options:
274 : : // These should generally be left off where quality is desired, as they can
275 : : // degrade the result quite noticeably; but may be useful for older or
276 : : // slower hardware. Note that libplacebo will automatically disable
277 : : // advanced features on hardware where they are unsupported, regardless of
278 : : // these settings. So only enable them if you need a performance bump.
279 : :
280 : : // Disables anti-aliasing on downscaling. This will result in moiré
281 : : // artifacts and nasty, jagged pixels when downscaling, except for some
282 : : // very limited special cases (e.g. bilinear downsampling to exactly 0.5x).
283 : : //
284 : : // Significantly speeds up downscaling with high downscaling ratios.
285 : : bool skip_anti_aliasing;
286 : :
287 : : // Normally, when the size of the `target` used with `pl_render_image_mix`
288 : : // changes, or the render parameters are updated, the internal cache of
289 : : // mixed frames must be discarded in order to re-render all required
290 : : // frames. Setting this option to `true` will skip the cache invalidation
291 : : // and instead re-use the existing frames (with bilinear scaling to the new
292 : : // size if necessary), which comes at a quality loss shortly after a
293 : : // resize, but should make it much more smooth.
294 : : bool preserve_mixing_cache;
295 : :
296 : : // --- Performance tuning / debugging options
297 : : // These may affect performance or may make debugging problems easier,
298 : : // but shouldn't have any effect on the quality.
299 : :
300 : : // Normally, `pl_render_image_mix` will also push single frames through the
301 : : // mixer cache, in order to speed up re-draws. Enabling this option
302 : : // disables that logic, causing single frames to bypass the cache. (Though
303 : : // it will still read from, if they happen to already be cached)
304 : : bool skip_caching_single_frame;
305 : :
306 : : // Disables linearization / sigmoidization before scaling. This might be
307 : : // useful when tracking down unexpected image artifacts or excessing
308 : : // ringing, but it shouldn't normally be necessary.
309 : : bool disable_linear_scaling;
310 : :
311 : : // Forces the use of the "general" scaling algorithms even when using the
312 : : // special-cased built-in presets like `pl_filter_bicubic`. Basically, this
313 : : // disables the more efficient implementations in favor of the slower,
314 : : // general-purpose ones.
315 : : bool disable_builtin_scalers;
316 : :
317 : : // Forces correction of subpixel offsets (using the configured `upscaler`).
318 : : bool correct_subpixel_offsets;
319 : :
320 : : // Forces the use of dithering, even when rendering to 16-bit FBOs. This is
321 : : // generally pretty pointless because most 16-bit FBOs have high enough
322 : : // depth that rounding errors are below the human perception threshold,
323 : : // but this can be used to test the dither code.
324 : : bool force_dither;
325 : :
326 : : // Disables the gamma-correct dithering logic which normally applies when
327 : : // dithering to low bit depths. No real use, outside of testing.
328 : : bool disable_dither_gamma_correction;
329 : :
330 : : // Completely overrides the use of FBOs, as if there were no renderable
331 : : // texture format available. This disables most features.
332 : : bool disable_fbos;
333 : :
334 : : // Use only low-bit-depth FBOs (8 bits). Note that this also implies
335 : : // disabling linear scaling and sigmoidization.
336 : : bool force_low_bit_depth_fbos;
337 : :
338 : : // If this is true, all shaders will be generated as "dynamic" shaders,
339 : : // with any compile-time constants being replaced by runtime-adjustable
340 : : // values. This is generally a performance loss, but has the advantage of
341 : : // being able to freely change parameters without triggering shader
342 : : // recompilations.
343 : : //
344 : : // It's a good idea to enable while presenting configurable settings to the
345 : : // user, but it should be set to false once those values are "dialed in".
346 : : bool dynamic_constants;
347 : :
348 : : // This callback is invoked for every pass successfully executed in the
349 : : // process of rendering a frame. Optional.
350 : : //
351 : : // Note: `info` is only valid until this function returns.
352 : : void (*info_callback)(void *priv, const struct pl_render_info *info);
353 : : void *info_priv;
354 : :
355 : : // --- Deprecated/removed fields
356 : : PL_DEPRECATED_IN(v6.254) bool allow_delayed_peak_detect; // moved to pl_peak_detect_params
357 : : PL_DEPRECATED_IN(v6.327) const struct pl_icc_params *icc_params; // use pl_frame.icc
358 : : PL_DEPRECATED_IN(v6.328) bool ignore_icc_profiles; // non-functional, just set pl_frame.icc to NULL
359 : : PL_DEPRECATED_IN(v6.335) int lut_entries; // hard-coded as 256
360 : : PL_DEPRECATED_IN(v6.335) float polar_cutoff; // hard-coded as 1e-3
361 : : PL_DEPRECATED_IN(v7.346) bool skip_target_clearing; // `border = PL_CLEAR_SKIP`
362 : : PL_DEPRECATED_IN(v7.346) bool blend_against_tiles; // `background = PL_CLEAR_TILES`
363 : : };
364 : :
365 : : // Bare minimum parameters, with no features enabled. This is the fastest
366 : : // possible configuration, and should therefore be fine on any system.
367 : : #define PL_RENDER_DEFAULTS \
368 : : .color_map_params = &pl_color_map_default_params, \
369 : : .color_adjustment = &pl_color_adjustment_neutral, \
370 : : .tile_colors = {{0.93, 0.93, 0.93}, \
371 : : {0.87, 0.87, 0.87}}, \
372 : : .tile_size = 32,
373 : :
374 : : #define pl_render_params(...) (&(struct pl_render_params) { PL_RENDER_DEFAULTS __VA_ARGS__ })
375 : : PL_API extern const struct pl_render_params pl_render_fast_params;
376 : :
377 : : // This contains the default/recommended options for reasonable image quality,
378 : : // while also not being too terribly slow. All of the *_params structs are
379 : : // defaulted to the corresponding *_default_params, except for deband_params,
380 : : // which is disabled by default.
381 : : //
382 : : // This should be fine on most integrated GPUs, but if it's too slow,
383 : : // consider using `pl_render_fast_params` instead.
384 : : PL_API extern const struct pl_render_params pl_render_default_params;
385 : :
386 : : // This contains a higher quality preset for better image quality at the cost
387 : : // of quite a bit of performance. In addition to the settings implied by
388 : : // `pl_render_default_params`, it enables debanding, sets the upscaler to
389 : : // `pl_filter_ewa_lanczossharp`, and uses pl_*_high_quality_params structs where
390 : : // available. This should only really be used with a discrete GPU and where
391 : : // maximum image quality is desired.
392 : : PL_API extern const struct pl_render_params pl_render_high_quality_params;
393 : :
394 : : #define PL_MAX_PLANES 4
395 : :
396 : : // High level description of a single slice of an image. This basically
397 : : // represents a single 2D plane, with any number of components
398 : : struct pl_plane {
399 : : // The texture underlying this plane. The texture must be 2D, and must
400 : : // have specific parameters set depending on what the plane is being used
401 : : // for (see `pl_render_image`).
402 : : pl_tex texture;
403 : :
404 : : // The preferred behaviour when sampling outside of this texture. Optional,
405 : : // since the default (PL_TEX_ADDRESS_CLAMP) is very reasonable.
406 : : enum pl_tex_address_mode address_mode;
407 : :
408 : : // Controls whether or not the `texture` will be considered flipped
409 : : // vertically with respect to the overall image dimensions. It's generally
410 : : // preferable to flip planes using this setting instead of the crop in
411 : : // cases where the flipping is the result of e.g. negative plane strides or
412 : : // flipped framebuffers (OpenGL).
413 : : //
414 : : // Note that any planar padding (due to e.g. size mismatch or misalignment
415 : : // of subsampled planes) is always at the physical end of the texture
416 : : // (highest y coordinate) - even if this bool is true. However, any
417 : : // subsampling shift (`shift_y`) is applied with respect to the flipped
418 : : // direction. This ensures the correct interpretation when e.g. vertically
419 : : // flipping 4:2:0 sources by flipping all planes.
420 : : bool flipped;
421 : :
422 : : // Describes the number and interpretation of the components in this plane.
423 : : // This defines the mapping from component index to the canonical component
424 : : // order (RGBA, YCbCrA or XYZA). It's worth pointing out that this is
425 : : // completely separate from `texture->format.sample_order`. The latter is
426 : : // essentially irrelevant/transparent for the API user, since it just
427 : : // determines which order the texture data shows up as inside the GLSL
428 : : // shader; whereas this field controls the actual meaning of the component.
429 : : //
430 : : // Example; if the user has a plane with just {Y} and a plane with just
431 : : // {Cb Cr}, and a GPU that only supports bgra formats, you would still
432 : : // specify the component mapping as {0} and {1 2} respectively, even though
433 : : // the GPU is sampling the data in the order BGRA. Use -1 for "ignored"
434 : : // components.
435 : : int components; // number of relevant components
436 : : int component_mapping[4]; // semantic index of each component
437 : :
438 : : // Controls the sample offset, relative to the "reference" dimensions. For
439 : : // an example of what to set here, see `pl_chroma_location_offset`. Note
440 : : // that this is given in unit of reference pixels. For a graphical example,
441 : : // imagine you have a 2x2 image with a 1x1 (subsampled) plane. Without any
442 : : // shift (0.0), the situation looks like this:
443 : : //
444 : : // X-------X X = reference pixel
445 : : // | | P = plane pixel
446 : : // | P |
447 : : // | |
448 : : // X-------X
449 : : //
450 : : // For 4:2:0 subsampling, this corresponds to PL_CHROMA_CENTER. If the
451 : : // shift_x was instead set to -0.5, the `P` pixel would be offset to the
452 : : // left by half the separation between the reference (`X` pixels), resulting
453 : : // in the following:
454 : : //
455 : : // X-------X X = reference pixel
456 : : // | | P = plane pixel
457 : : // P |
458 : : // | |
459 : : // X-------X
460 : : //
461 : : // For 4:2:0 subsampling, this corresponds to PL_CHROMA_LEFT.
462 : : //
463 : : // Note: It's recommended to fill this using `pl_chroma_location_offset` on
464 : : // the chroma planes.
465 : : float shift_x, shift_y;
466 : : };
467 : :
468 : : enum pl_overlay_mode {
469 : : PL_OVERLAY_NORMAL = 0, // treat the texture as a normal, full-color texture
470 : : PL_OVERLAY_MONOCHROME, // treat the texture as a single-component alpha map
471 : : PL_OVERLAY_MODE_COUNT,
472 : : };
473 : :
474 : : enum pl_overlay_coords {
475 : : PL_OVERLAY_COORDS_AUTO = 0, // equal to SRC/DST_FRAME, respectively
476 : : PL_OVERLAY_COORDS_SRC_FRAME, // relative to the raw src frame
477 : : PL_OVERLAY_COORDS_SRC_CROP, // relative to the src frame crop
478 : : PL_OVERLAY_COORDS_DST_FRAME, // relative to the raw dst frame
479 : : PL_OVERLAY_COORDS_DST_CROP, // relative to the dst frame crop
480 : : PL_OVERLAY_COORDS_COUNT,
481 : :
482 : : // Note on rotations: If there is an end-to-end rotation between `src` and
483 : : // `dst`, then any overlays relative to SRC_FRAME or SRC_CROP will be
484 : : // rotated alongside the image, while overlays relative to DST_FRAME or
485 : : // DST_CROP will not.
486 : : };
487 : :
488 : : struct pl_overlay_part {
489 : : pl_rect2df src; // source coordinate with respect to `pl_overlay.tex`
490 : : pl_rect2df dst; // target coordinates with respect to `pl_overlay.coords`
491 : :
492 : : // If `mode` is PL_OVERLAY_MONOCHROME, then this specifies the color of
493 : : // this overlay part. The color is multiplied into the sampled texture's
494 : : // first channel.
495 : : float color[4];
496 : : };
497 : :
498 : : // A struct representing an image overlay (e.g. for subtitles or on-screen
499 : : // status messages, controls, ...)
500 : : struct pl_overlay {
501 : : // The texture containing the backing data for overlay parts. Must have
502 : : // `params.sampleable` set.
503 : : pl_tex tex;
504 : :
505 : : // This controls the coloring mode of this overlay.
506 : : enum pl_overlay_mode mode;
507 : :
508 : : // Controls which coordinates this overlay is addressed relative to.
509 : : enum pl_overlay_coords coords;
510 : :
511 : : // This controls the colorspace information for this overlay. The contents
512 : : // of the texture / the value of `color` are interpreted according to this.
513 : : struct pl_color_repr repr;
514 : : struct pl_color_space color;
515 : :
516 : : // The number of parts for this overlay.
517 : : const struct pl_overlay_part *parts;
518 : : int num_parts;
519 : : };
520 : :
521 : : // High-level description of a complete frame, including metadata and planes
522 : : struct pl_frame {
523 : : // Each frame is split up into some number of planes, each of which may
524 : : // carry several components and be of any size / offset.
525 : : int num_planes;
526 : : struct pl_plane planes[PL_MAX_PLANES];
527 : :
528 : : // For interlaced frames. If set, this `pl_frame` corresponds to a single
529 : : // field of the underlying source textures. `first_field` indicates which
530 : : // of these fields is ordered first in time. `prev` and `next` should point
531 : : // to the previous/next frames in the file, or NULL if there are none.
532 : : //
533 : : // Note: Setting these fields on the render target has no meaning and will
534 : : // be ignored.
535 : : enum pl_field field;
536 : : enum pl_field first_field;
537 : : const struct pl_frame *prev, *next;
538 : :
539 : : // If set, will be called immediately before GPU access to this frame. This
540 : : // function *may* be used to, for example, perform synchronization with
541 : : // external APIs (e.g. `pl_vulkan_hold/release`). If your mapping requires
542 : : // a memcpy of some sort (e.g. pl_tex_transfer), users *should* instead do
543 : : // the memcpy up-front and avoid the use of these callbacks - because they
544 : : // might be called multiple times on the same frame.
545 : : //
546 : : // This function *may* arbitrarily mutate the `pl_frame`, but it *should*
547 : : // ideally only update `planes` - in particular, color metadata and so
548 : : // forth should be provided up-front as best as possible. Note that changes
549 : : // here will not be reflected back to the structs provided in the original
550 : : // `pl_render_*` call (e.g. via `pl_frame_mix`).
551 : : //
552 : : // Note: Unless dealing with interlaced frames, only one frame will ever be
553 : : // acquired at a time per `pl_render_*` call. So users *can* safely use
554 : : // this with, for example, hwdec mappers that can only map a single frame
555 : : // at a time. When using this with, for example, `pl_render_image_mix`,
556 : : // each frame to be blended is acquired and release in succession, before
557 : : // moving on to the next frame. For interlaced frames, the previous and
558 : : // next frames must also be acquired simultaneously.
559 : : bool (*acquire)(pl_gpu gpu, struct pl_frame *frame);
560 : :
561 : : // If set, will be called after a plane is done being used by the GPU,
562 : : // *including* after any errors (e.g. `acquire` returning false).
563 : : void (*release)(pl_gpu gpu, struct pl_frame *frame);
564 : :
565 : : // Color representation / encoding / semantics of this frame.
566 : : struct pl_color_repr repr;
567 : : struct pl_color_space color;
568 : :
569 : : // Optional ICC profile associated with this frame.
570 : : pl_icc_object icc;
571 : :
572 : : // Alternative to `icc`, this can be used in cases where allocating and
573 : : // tracking an pl_icc_object externally may be inconvenient. The resulting
574 : : // profile will be managed internally by the pl_renderer.
575 : : struct pl_icc_profile profile;
576 : :
577 : : // Optional LUT associated with this frame.
578 : : const struct pl_custom_lut *lut;
579 : : enum pl_lut_type lut_type;
580 : :
581 : : // The logical crop / rectangle containing the valid information, relative
582 : : // to the reference plane's dimensions (e.g. luma). Pixels outside of this
583 : : // rectangle will ostensibly be ignored, but note that this is not a hard
584 : : // guarantee. In particular, scaler filters may end up sampling outside of
585 : : // this crop. This rect may be flipped, and may be partially or wholly
586 : : // outside the bounds of the underlying textures. (Optional)
587 : : //
588 : : // Note that `pl_render_image` will map the input crop directly to the
589 : : // output crop, stretching and scaling as needed. If you wish to preserve
590 : : // the aspect ratio, use a dedicated function like pl_rect2df_aspect_copy.
591 : : pl_rect2df crop;
592 : :
593 : : // Logical rotation of the image, with respect to the underlying planes.
594 : : // For example, if this is PL_ROTATION_90, then the image will be rotated
595 : : // to the right by 90° when mapping to `crop`. The actual position on-screen
596 : : // is unaffected, so users should ensure that the (rotated) aspect ratio
597 : : // matches the source. (Or use a helper like `pl_rect2df_aspect_set_rot`)
598 : : //
599 : : // Note: For `target` frames, this corresponds to a rotation of the
600 : : // display, for `image` frames, this corresponds to a rotation of the
601 : : // camera.
602 : : //
603 : : // So, as an example, target->rotation = PL_ROTATE_90 means the end user
604 : : // has rotated the display to the right by 90° (meaning rendering will be
605 : : // rotated 90° to the *left* to compensate), and image->rotation =
606 : : // PL_ROTATE_90 means the video provider has rotated the camera to the
607 : : // right by 90° (so rendering will be rotated 90° to the *right* to
608 : : // compensate).
609 : : pl_rotation rotation;
610 : :
611 : : // A list of additional overlays associated with this frame. Note that will
612 : : // be rendered directly onto intermediate/cache frames, so changing any of
613 : : // these overlays may require flushing the renderer cache.
614 : : const struct pl_overlay *overlays;
615 : : int num_overlays;
616 : :
617 : : // Note on subsampling and plane correspondence: All planes belonging to
618 : : // the same frame will only be stretched by an integer multiple (or inverse
619 : : // thereof) in order to match the reference dimensions of this image. For
620 : : // example, suppose you have an 8x4 image. A valid plane scaling would be
621 : : // 4x2 -> 8x4 or 4x4 -> 4x4, but not 6x4 -> 8x4. So if a 6x4 plane is
622 : : // given, then it would be treated like a cropped 8x4 plane (since 1.0 is
623 : : // the closest scaling ratio to the actual ratio of 1.3).
624 : : //
625 : : // For an explanation of why this makes sense, consider the relatively
626 : : // common example of a subsampled, oddly sized (e.g. jpeg) image. In such
627 : : // cases, for example a 35x23 image, the 4:2:0 subsampled chroma plane
628 : : // would have to end up as 17.5x11.5, which gets rounded up to 18x12 by
629 : : // implementations. So in this example, the 18x12 chroma plane would get
630 : : // treated by libplacebo as an oversized chroma plane - i.e. the plane
631 : : // would get sampled as if it was 17.5 pixels wide and 11.5 pixels large.
632 : :
633 : : // Associated film grain data (see <libplacebo/shaders/film_grain.h>).
634 : : //
635 : : // Note: This is ignored for the `target` of `pl_render_image`, since
636 : : // un-applying grain makes little sense.
637 : : struct pl_film_grain_data film_grain;
638 : :
639 : : // Ignored by libplacebo. May be useful for users.
640 : : void *user_data;
641 : : };
642 : :
643 : : // Helper function to infer the chroma location offset for each plane in a
644 : : // frame. This is equivalent to calling `pl_chroma_location_offset` on all
645 : : // subsampled planes' shift_x/shift_y variables.
646 : : PL_API void pl_frame_set_chroma_location(struct pl_frame *frame,
647 : : enum pl_chroma_location chroma_loc);
648 : :
649 : : // Fills in a `pl_frame` based on a swapchain frame's FBO and metadata.
650 : : PL_API void pl_frame_from_swapchain(struct pl_frame *out_frame,
651 : : const struct pl_swapchain_frame *frame);
652 : :
653 : : // Helper function to determine if a frame is logically cropped or not. In
654 : : // particular, this is useful in determining whether or not an output frame
655 : : // needs to be cleared before rendering or not.
656 : : PL_API bool pl_frame_is_cropped(const struct pl_frame *frame);
657 : :
658 : : // Helper function to reset a frame to a given RGB color. If the frame's
659 : : // color representation is something other than RGB, the clear color will
660 : : // be adjusted accordingly. `clear_color` should be non-premultiplied.
661 : : PL_API void pl_frame_clear_rgba(pl_gpu gpu, const struct pl_frame *frame,
662 : : const float clear_color[4]);
663 : :
664 : : // Like `pl_frame_clear_rgba` but without an alpha channel.
665 : : static inline void pl_frame_clear(pl_gpu gpu, const struct pl_frame *frame,
666 : : const float clear_color[3])
667 : : {
668 : : const float clear_color_rgba[4] = { clear_color[0], clear_color[1], clear_color[2], 1.0 };
669 : : pl_frame_clear_rgba(gpu, frame, clear_color_rgba);
670 : : }
671 : :
672 : : // Helper function to clear a frame to a fully tiled background.
673 : : PL_API void pl_frame_clear_tiles(pl_gpu gpu, const struct pl_frame *frame,
674 : : const float tile_colors[2][3], int tile_size);
675 : :
676 : : // Helper functions to return the fixed/inferred pl_frame parameters used
677 : : // for rendering internally. Mutates `image` and `target` in-place to hold
678 : : // the modified values, which are what will actually be used for rendering.
679 : : //
680 : : // This currently includes:
681 : : // - Defaulting all missing pl_color_space/repr parameters
682 : : // - Coalescing all rotation to the target
683 : : // - Rounding and clamping the target crop to pixel boundaries and adjusting the
684 : : // image crop correspondingly
685 : : //
686 : : // Note: This is idempotent and does not generally alter the effects of a
687 : : // subsequent `pl_render_image` on the same pl_frame pair. (But see the
688 : : // following warning)
689 : : //
690 : : // Warning: This does *not* call pl_frame.acquire/release, and so the returned
691 : : // metadata *may* be incorrect if the acquire callback mutates the pl_frame in
692 : : // nontrivial ways, in particular the crop and color space fields.
693 : : PL_API void pl_frames_infer(pl_renderer rr, struct pl_frame *image,
694 : : struct pl_frame *target);
695 : :
696 : :
697 : : // Render a single image to a target using the given parameters. This is
698 : : // fully dynamic, i.e. the params can change at any time. libplacebo will
699 : : // internally detect and flush whatever caches are invalidated as a result of
700 : : // changing colorspace, size etc.
701 : : //
702 : : // Required plane capabilities:
703 : : // - Planes in `image` must be `sampleable`
704 : : // - Planes in `target` must be `renderable`
705 : : //
706 : : // Recommended plane capabilities: (Optional, but good for performance)
707 : : // - Planes in `image` should have `sample_mode` PL_TEX_SAMPLE_LINEAR
708 : : // - Planes in `target` should be `storable`
709 : : // - Planes in `target` should have `blit_dst`
710 : : //
711 : : // Note on lifetime: Once this call returns, the passed structures may be
712 : : // freely overwritten or discarded by the caller, even the referenced
713 : : // `pl_tex` objects may be freely reused.
714 : : //
715 : : // Note: `image` may be NULL, in which case `target.overlays` will still be
716 : : // rendered, but nothing else.
717 : : PL_API bool pl_render_image(pl_renderer rr, const struct pl_frame *image,
718 : : const struct pl_frame *target,
719 : : const struct pl_render_params *params);
720 : :
721 : : // Flushes the internal state of this renderer. This is normally not needed,
722 : : // even if the image parameters, colorspace or target configuration change,
723 : : // since libplacebo will internally detect such circumstances and recreate
724 : : // outdated resources automatically. Doing this explicitly *may* be useful to
725 : : // purge some state related to things like HDR peak detection or frame mixing,
726 : : // so calling it is a good idea if the content source is expected to change
727 : : // dramatically (e.g. when switching to a different file).
728 : : PL_API void pl_renderer_flush_cache(pl_renderer rr);
729 : :
730 : : // Mirrors `pl_get_detected_hdr_metadata`, giving you the current internal peak
731 : : // detection HDR metadata (when peak detection is active). Returns false if no
732 : : // information is available (e.g. not HDR source, peak detection disabled).
733 : : PL_API bool pl_renderer_get_hdr_metadata(pl_renderer rr,
734 : : struct pl_hdr_metadata *metadata);
735 : :
736 : : // Represents a mixture of input frames, distributed temporally.
737 : : //
738 : : // NOTE: Frames must be sorted by timestamp, i.e. `timestamps` must be
739 : : // monotonically increasing.
740 : : struct pl_frame_mix {
741 : : // The number of frames in this mixture. The number of frames should be
742 : : // sufficient to meet the needs of the configured frame mixer. See the
743 : : // section below for more information.
744 : : //
745 : : // If the number of frames is 0, this call will be equivalent to
746 : : // `pl_render_image` with `image == NULL`.
747 : : int num_frames;
748 : :
749 : : // A list of the frames themselves. The frames can have different
750 : : // colorspaces, configurations of planes, or even sizes.
751 : : //
752 : : // Note: This is a list of pointers, to avoid users having to copy
753 : : // around `pl_frame` structs when re-organizing this array.
754 : : const struct pl_frame **frames;
755 : :
756 : : // A list of unique signatures, one for each frame. These are used to
757 : : // identify frames across calls to this function, so it's crucial that they
758 : : // be both unique per-frame but also stable across invocations of
759 : : // `pl_render_frame_mix`.
760 : : const uint64_t *signatures;
761 : :
762 : : // A list of relative timestamps for each frame. These are relative to the
763 : : // time of the vsync being drawn, i.e. this function will render the frame
764 : : // that will be made visible at timestamp 0.0. The values are expected to
765 : : // be normalized such that a separation of 1.0 corresponds to roughly one
766 : : // nominal source frame duration. So a constant framerate video file will
767 : : // always have timestamps like e.g. {-2.3, -1.3, -0.3, 0.7, 1.7, 2.7},
768 : : // using an example radius of 3.
769 : : //
770 : : // In cases where the framerate is variable (e.g. VFR video), the choice of
771 : : // what to scale to use can be difficult to answer. A typical choice would
772 : : // be either to use the canonical (container-tagged) framerate, or the
773 : : // highest momentary framerate, as a reference. If all else fails, you
774 : : // could also use the display's framerate.
775 : : //
776 : : // Note: This function assumes zero-order-hold semantics, i.e. the frame at
777 : : // timestamp 0.7 is intended to remain visible until timestamp 1.7, when
778 : : // the next frame replaces it.
779 : : const float *timestamps;
780 : :
781 : : // The duration for which the vsync being drawn will be held, using the
782 : : // same scale as `timestamps`. If the display has an unknown or variable
783 : : // frame-rate (e.g. Adaptive Sync), then you're probably better off not
784 : : // using this function and instead just painting the frames directly using
785 : : // `pl_render_frame` at the correct PTS.
786 : : //
787 : : // As an example, if `vsync_duration` is 0.4, then it's assumed that the
788 : : // vsync being painted is visible for the period [0.0, 0.4].
789 : : float vsync_duration;
790 : :
791 : : // Explanation of the frame mixing radius: The algorithm chosen in
792 : : // `pl_render_params.frame_mixer` has a canonical radius equal to
793 : : // `pl_filter_config.kernel->radius`. This means that the frame mixing
794 : : // algorithm will (only) need to consult all of the frames that have a
795 : : // distance within the interval [-radius, radius]. As such, the user should
796 : : // include all such frames in `frames`, but may prune or omit frames that
797 : : // lie outside it.
798 : : //
799 : : // The built-in frame mixing (`pl_render_params.frame_mixer == NULL`) has
800 : : // no concept of radius, it just always needs access to the "current" and
801 : : // "next" frames.
802 : : };
803 : :
804 : : // Helper function to calculate the base frame mixing radius.
805 : : //
806 : : // Note: When the source FPS exceeds the display FPS, this radius must be
807 : : // increased by the corresponding ratio.
808 : : static inline float pl_frame_mix_radius(const struct pl_render_params *params)
809 : : {
810 : : // For backwards compatibility, allow !frame_mixer->kernel
811 [ + - + - ]: 8 : if (!params->frame_mixer || !params->frame_mixer->kernel)
812 : : return 0.0;
813 : :
814 : 8 : return params->frame_mixer->kernel->radius;
815 : : }
816 : :
817 : : // Find closest frame to current PTS by zero-order hold semantics, or NULL.
818 : : PL_API const struct pl_frame *pl_frame_mix_current(const struct pl_frame_mix *mix);
819 : :
820 : : // Find closest frame to current PTS by nearest neighbour semantics, or NULL.
821 : : PL_API const struct pl_frame *pl_frame_mix_nearest(const struct pl_frame_mix *mix);
822 : :
823 : : // Render a mixture of images to the target using the given parameters. This
824 : : // functions much like a generalization of `pl_render_image`, for when the API
825 : : // user has more control over the frame queue / vsync loop, and can provide a
826 : : // few frames from the past and future + timestamp information.
827 : : //
828 : : // This allows libplacebo to perform rudimentary frame mixing / interpolation,
829 : : // in order to eliminate judder artifacts typically associated with
830 : : // source/display frame rate mismatch.
831 : : PL_API bool pl_render_image_mix(pl_renderer rr, const struct pl_frame_mix *images,
832 : : const struct pl_frame *target,
833 : : const struct pl_render_params *params);
834 : :
835 : : // Analog of `pl_frame_infer` corresponding to `pl_render_image_mix`. This
836 : : // function will *not* mutate the frames contained in `mix`, and instead
837 : : // return an adjusted copy of the "reference" frame for that image mix in
838 : : // `out_refimage`, or {0} if the mix is empty.
839 : : PL_API void pl_frames_infer_mix(pl_renderer rr, const struct pl_frame_mix *mix,
840 : : struct pl_frame *target, struct pl_frame *out_ref);
841 : :
842 : : // Backwards compatibility with old filters API, may be deprecated.
843 : : // Redundant with pl_filter_configs and masking `allowed` for
844 : : // PL_FILTER_SCALING and PL_FILTER_FRAME_MIXING respectively.
845 : :
846 : : // A list of recommended frame mixer presets, terminated by {0}
847 : : PL_API extern const struct pl_filter_preset pl_frame_mixers[];
848 : : PL_API extern const int pl_num_frame_mixers; // excluding trailing {0}
849 : :
850 : : // A list of recommended scaler presets, terminated by {0}. This is almost
851 : : // equivalent to `pl_filter_presets` with the exception of including extra
852 : : // built-in filters that don't map to the `pl_filter` architecture.
853 : : PL_API extern const struct pl_filter_preset pl_scale_filters[];
854 : : PL_API extern const int pl_num_scale_filters; // excluding trailing {0}
855 : :
856 : : // Deprecated in favor of `pl_cache_save/pl_cache_load` on the `pl_cache`
857 : : // associated with the `pl_gpu` this renderer is using.
858 : : PL_DEPRECATED_IN(v6.323) PL_API size_t pl_renderer_save(pl_renderer rr, uint8_t *out_cache);
859 : : PL_DEPRECATED_IN(v6.323) PL_API void pl_renderer_load(pl_renderer rr, const uint8_t *cache);
860 : :
861 : : PL_API_END
862 : :
863 : : #endif // LIBPLACEBO_RENDERER_H_
|