forked from libretro/RetroArch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvideo_driver.h
1509 lines (1195 loc) · 45.3 KB
/
video_driver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2021 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RARCH_VIDEO_DRIVER_H__
#define RARCH_VIDEO_DRIVER_H__
#include <stddef.h>
#include <libretro.h>
#include <retro_common_api.h>
#include <boolean.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#ifdef HAVE_THREADS
#include <rthreads/rthreads.h>
#endif
#include <gfx/scaler/pixconv.h>
#include <gfx/scaler/scaler.h>
#include "../configuration.h"
#include "../input/input_driver.h"
#include "../input/input_types.h"
#include "video_defines.h"
#ifdef HAVE_VIDEO_LAYOUT
#include "video_layout.h"
#endif
#ifdef HAVE_CRTSWITCHRES
#include "video_crt_switch.h"
#endif
#include "video_coord_array.h"
#include "video_shader_parse.h"
#include "video_filter.h"
#define RARCH_SCALE_BASE 256
#define MEASURE_FRAME_TIME_SAMPLES_COUNT (2 * 1024)
#define VIDEO_SHADER_STOCK_BLEND (GFX_MAX_SHADERS - 1)
#define VIDEO_SHADER_MENU (GFX_MAX_SHADERS - 2)
#define VIDEO_SHADER_MENU_2 (GFX_MAX_SHADERS - 3)
#define VIDEO_SHADER_MENU_3 (GFX_MAX_SHADERS - 4)
#define VIDEO_SHADER_MENU_4 (GFX_MAX_SHADERS - 5)
#define VIDEO_SHADER_MENU_5 (GFX_MAX_SHADERS - 6)
#define VIDEO_SHADER_MENU_6 (GFX_MAX_SHADERS - 7)
#define VIDEO_SHADER_STOCK_HDR (GFX_MAX_SHADERS - 8)
#define VIDEO_HDR_MAX_CONTRAST 10.0f
#if defined(_XBOX360)
#define DEFAULT_SHADER_TYPE RARCH_SHADER_HLSL
#elif defined(__PSL1GHT__) || defined(HAVE_OPENGLES2) || defined(HAVE_GLSL)
#define DEFAULT_SHADER_TYPE RARCH_SHADER_GLSL
#elif defined(HAVE_CG)
#define DEFAULT_SHADER_TYPE RARCH_SHADER_CG
#else
#define DEFAULT_SHADER_TYPE RARCH_SHADER_NONE
#endif
#ifndef MAX_EGLIMAGE_TEXTURES
#define MAX_EGLIMAGE_TEXTURES 32
#endif
#define MAX_VARIABLES 64
#ifdef HAVE_THREADS
#define VIDEO_DRIVER_IS_THREADED_INTERNAL(video_st) ((!video_driver_is_hw_context() && video_st->threaded) ? true : false)
#define VIDEO_DRIVER_LOCK(video_st) \
if (video_st->display_lock) \
slock_lock(video_st->display_lock)
#define VIDEO_DRIVER_UNLOCK(video_st) \
if (video_st->display_lock) \
slock_unlock(video_st->display_lock)
#define VIDEO_DRIVER_CONTEXT_LOCK(video_st) \
if (video_st->context_lock) \
slock_lock(video_st->context_lock)
#define VIDEO_DRIVER_CONTEXT_UNLOCK(video_st) \
if (video_st->context_lock) \
slock_unlock(video_st->context_lock)
#define VIDEO_DRIVER_LOCK_FREE(video_st) \
slock_free(video_st->display_lock); \
slock_free(video_st->context_lock); \
video_st->display_lock = NULL; \
video_st->context_lock = NULL
#define VIDEO_DRIVER_THREADED_LOCK(video_st, is_threaded) \
if (is_threaded) \
VIDEO_DRIVER_LOCK(video_st)
#define VIDEO_DRIVER_THREADED_UNLOCK(video_st, is_threaded) \
if (is_threaded) \
VIDEO_DRIVER_UNLOCK(video_st)
#define VIDEO_DRIVER_GET_PTR_INTERNAL(video_st) ((VIDEO_DRIVER_IS_THREADED_INTERNAL(video_st)) ? video_thread_get_ptr(video_st) : video_st->data)
#else
#define VIDEO_DRIVER_IS_THREADED_INTERNAL(video_st) (false)
#define VIDEO_DRIVER_LOCK(video_st) ((void)0)
#define VIDEO_DRIVER_UNLOCK(video_st) ((void)0)
#define VIDEO_DRIVER_LOCK_FREE(video_st) ((void)0)
#define VIDEO_DRIVER_THREADED_LOCK(video_st, is_threaded) ((void)0)
#define VIDEO_DRIVER_THREADED_UNLOCK(video_st, is_threaded) ((void)0)
#define VIDEO_DRIVER_CONTEXT_LOCK(video_st) ((void)0)
#define VIDEO_DRIVER_CONTEXT_UNLOCK(video_st) ((void)0)
#define VIDEO_DRIVER_GET_PTR_INTERNAL(video_st) (video_st->data)
#endif
#define VIDEO_DRIVER_GET_HW_CONTEXT_INTERNAL(video_st) (&video_st->hw_render)
#define VIDEO_HAS_FOCUS(video_st) (video_st->current_video->focus ? (video_st->current_video->focus(video_st->data)) : true)
RETRO_BEGIN_DECLS
struct LinkInfo
{
struct video_shader_pass *pass;
unsigned tex_w, tex_h;
};
struct shader_program_info
{
void *data;
const char *vertex;
const char *fragment;
const char *combined;
unsigned idx;
bool is_file;
};
struct uniform_info
{
bool enabled;
int32_t location;
int32_t count;
unsigned type; /* shader uniform type */
struct
{
enum shader_program_type type;
const char *ident;
uint32_t idx;
bool add_prefix;
bool enable;
} lookup;
struct
{
float *floatv;
intptr_t *integerv;
uintptr_t *unsigned_integerv;
struct
{
intptr_t v0;
intptr_t v1;
intptr_t v2;
intptr_t v3;
} integer;
struct
{
uintptr_t v0;
uintptr_t v1;
uintptr_t v2;
uintptr_t v3;
} unsigned_integer;
struct
{
float v0;
float v1;
float v2;
float v3;
} f;
} result;
};
typedef struct shader_backend
{
void *(*init)(void *data, const char *path);
void (*init_menu_shaders)(void *data);
void (*deinit)(void *data);
/* Set shader parameters. */
void (*set_params)(void *data, void *shader_data);
void (*set_uniform_parameter)(void *data, struct uniform_info *param,
void *uniform_data);
/* Compile a shader program. */
bool (*compile_program)(void *data, unsigned idx,
void *program_data, struct shader_program_info *program_info);
/* Use a shader program specified by variable 'index'. */
void (*use)(void *data, void *shader_data, unsigned index, bool set_active);
/* Returns the number of currently loaded shaders. */
unsigned (*num_shaders)(void *data);
bool (*filter_type)(void *data, unsigned index, bool *smooth);
enum gfx_wrap_type (*wrap_type)(void *data, unsigned index);
void (*shader_scale)(void *data,
unsigned index, struct gfx_fbo_scale *scale);
bool (*set_coords)(void *shader_data, const struct video_coords *coords);
bool (*set_mvp)(void *shader_data, const void *mat_data);
unsigned (*get_prev_textures)(void *data);
bool (*get_feedback_pass)(void *data, unsigned *pass);
bool (*mipmap_input)(void *data, unsigned index);
struct video_shader *(*get_current_shader)(void *data);
void (*get_flags)(uint32_t*);
enum rarch_shader_type type;
/* Human readable string. */
const char *ident;
} shader_backend_t;
typedef struct video_shader_ctx_init
{
const char *path;
const shader_backend_t *shader;
void *data;
void *shader_data;
enum rarch_shader_type shader_type;
struct
{
bool core_context_enabled;
} gl;
} video_shader_ctx_init_t;
typedef struct video_shader_ctx_params
{
void *data;
const void *info;
const void *prev_info;
const void *feedback_info;
const void *fbo_info;
unsigned width;
unsigned height;
unsigned tex_width;
unsigned tex_height;
unsigned out_width;
unsigned out_height;
unsigned frame_counter;
unsigned fbo_info_cnt;
} video_shader_ctx_params_t;
typedef struct video_shader_ctx_coords
{
void *handle_data;
const void *data;
} video_shader_ctx_coords_t;
typedef struct video_shader_ctx_scale
{
struct gfx_fbo_scale *scale;
unsigned idx;
} video_shader_ctx_scale_t;
typedef struct video_shader_ctx_info
{
void *data;
unsigned num;
unsigned idx;
bool set_active;
} video_shader_ctx_info_t;
typedef struct video_shader_ctx_mvp
{
void *data;
const void *matrix;
} video_shader_ctx_mvp_t;
typedef struct video_shader_ctx_filter
{
bool *smooth;
unsigned index;
} video_shader_ctx_filter_t;
typedef struct video_shader_ctx
{
struct video_shader *data;
} video_shader_ctx_t;
typedef struct video_shader_ctx_texture
{
unsigned id;
} video_shader_ctx_texture_t;
typedef struct video_pixel_scaler
{
struct scaler_ctx *scaler;
void *scaler_out;
} video_pixel_scaler_t;
typedef void (*gfx_ctx_proc_t)(void);
typedef struct video_info
{
const char *path_font;
uintptr_t parent;
int swap_interval;
/* Width of window.
* If fullscreen mode is requested,
* a width of 0 means the resolution of the
* desktop should be used. */
unsigned width;
/* Height of window.
* If fullscreen mode is requested,
* a height of 0 means the resolutiof the desktop should be used.
*/
unsigned height;
#ifdef GEKKO
/* TODO - we can't really have driver system-specific
* variables in here. There should be some
* kind of publicly accessible driver implementation
* video struct for specific things like this.
*/
/* Wii-specific settings. Ignored for everything else. */
unsigned viwidth;
#endif
/*
* input_scale defines the maximum size of the picture that will
* ever be used with the frame callback.
*
* The maximum resolution is a multiple of 256x256 size (RARCH_SCALE_BASE),
* so an input scale of 2 means you should allocate a texture or of 512x512.
*
* Maximum input size: RARCH_SCALE_BASE * input_scale
*/
unsigned input_scale;
float font_size;
bool adaptive_vsync;
#ifdef GEKKO
bool vfilter;
#endif
/* If true, applies bilinear filtering to the image,
* otherwise nearest filtering. */
bool smooth;
bool ctx_scaling;
bool is_threaded;
/* Use 32bit RGBA rather than native RGB565/XBGR1555.
*
* XRGB1555 format is 16-bit and has byte ordering: 0RRRRRGGGGGBBBBB,
* in native endian.
*
* ARGB8888 is AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB, native endian.
* Alpha channel should be disregarded.
* */
bool rgb32;
/* Launch in fullscreen mode instead of windowed mode. */
bool fullscreen;
/* Start with V-Sync enabled. */
bool vsync;
/* If true, the output image should have the aspect ratio
* as set in aspect_ratio. */
bool force_aspect;
bool font_enable;
} video_info_t;
typedef struct video_frame_info
{
void *userdata;
void *widgets_userdata;
void *disp_userdata;
int custom_vp_x;
int custom_vp_y;
int crt_switch_center_adjust;
int crt_switch_porch_adjust;
unsigned hard_sync_frames;
unsigned aspect_ratio_idx;
unsigned max_swapchain_images;
unsigned monitor_index;
unsigned crt_switch_resolution;
unsigned crt_switch_resolution_super;
unsigned width;
unsigned height;
unsigned xmb_theme;
unsigned xmb_color_theme;
unsigned menu_shader_pipeline;
unsigned materialui_color_theme;
unsigned ozone_color_theme;
unsigned custom_vp_width;
unsigned custom_vp_height;
unsigned custom_vp_full_width;
unsigned custom_vp_full_height;
unsigned black_frame_insertion;
unsigned fps_update_interval;
unsigned memory_update_interval;
float menu_wallpaper_opacity;
float menu_framebuffer_opacity;
float menu_header_opacity;
float menu_footer_opacity;
float refresh_rate;
float font_msg_pos_x;
float font_msg_pos_y;
float font_msg_color_r;
float font_msg_color_g;
float font_msg_color_b;
float xmb_alpha_factor;
struct
{
/* Drop shadow offset.
* If both are 0, no drop shadow will be rendered. */
int drop_x, drop_y;
/* ABGR. Use the macros. */
uint32_t color;
float x;
float y;
float scale;
/* Drop shadow color multiplier. */
float drop_mod;
/* Drop shadow alpha */
float drop_alpha;
enum text_alignment text_align;
bool full_screen;
} osd_stat_params;
char stat_text[512];
bool widgets_active;
bool notifications_hidden;
bool menu_mouse_enable;
bool widgets_is_paused;
bool widgets_is_fast_forwarding;
bool widgets_is_rewinding;
bool input_menu_swap_ok_cancel_buttons;
bool input_driver_nonblock_state;
bool input_driver_grab_mouse_state;
bool hard_sync;
bool fps_show;
bool memory_show;
bool statistics_show;
bool framecount_show;
bool core_status_msg_show;
bool post_filter_record;
bool windowed_fullscreen;
bool fullscreen;
bool font_enable;
bool use_rgba;
bool hdr_support;
bool libretro_running;
bool xmb_shadows_enable;
bool battery_level_enable;
bool timedate_enable;
bool runloop_is_slowmotion;
bool runloop_is_paused;
bool fastforward_frameskip;
bool menu_is_alive;
bool menu_screensaver_active;
bool msg_bgcolor_enable;
bool crt_switch_hires_menu;
bool hdr_enable;
bool overlay_behind_menu;
} video_frame_info_t;
typedef void (*update_window_title_cb)(void*);
typedef bool (*get_metrics_cb)(void *data, enum display_metric_types type,
float *value);
typedef bool (*set_resize_cb)(void*, unsigned, unsigned);
typedef struct gfx_ctx_driver
{
/* The opaque pointer is the underlying video driver data (e.g. gl_t for
* OpenGL contexts). Although not advised, the context driver is allowed
* to hold a pointer to it as the context never outlives the video driver.
*
* The context driver is responsible for it's own data.*/
void* (*init)(void *video_driver);
void (*destroy)(void *data);
enum gfx_ctx_api (*get_api)(void *data);
/* Which API to bind to. */
bool (*bind_api)(void *video_driver, enum gfx_ctx_api,
unsigned major, unsigned minor);
/* Sets the swap interval. */
void (*swap_interval)(void *data, int);
/* Sets video mode. Creates a window, etc. */
bool (*set_video_mode)(void*, unsigned, unsigned, bool);
/* Gets current window size.
* If not initialized yet, it returns current screen size. */
void (*get_video_size)(void*, unsigned*, unsigned*);
float (*get_refresh_rate)(void*);
void (*get_video_output_size)(void*, unsigned*, unsigned*, char *, size_t);
void (*get_video_output_prev)(void*);
void (*get_video_output_next)(void*);
get_metrics_cb get_metrics;
/* Translates a window size to an aspect ratio.
* In most cases this will be just width / height, but
* some contexts will better know which actual aspect ratio is used.
* This can be NULL to assume the default behavior.
*/
float (*translate_aspect)(void*, unsigned, unsigned);
/* Asks driver to update window title (FPS, etc). */
update_window_title_cb update_window_title;
/* Queries for resize and quit events.
* Also processes events. */
void (*check_window)(void*, bool*, bool*,
unsigned*, unsigned*);
/* Acknowledge a resize event. This is needed for some APIs.
* Most backends will ignore this. */
set_resize_cb set_resize;
/* Checks if window has input focus. */
bool (*has_focus)(void*);
/* Should the screensaver be suppressed? */
bool (*suppress_screensaver)(void *data, bool enable);
/* Checks if context driver has windowed support. */
bool has_windowed;
/* Swaps buffers. VBlank sync depends on
* earlier calls to swap_interval. */
void (*swap_buffers)(void*);
/* Most video backends will want to use a certain input driver.
* Checks for it here. */
void (*input_driver)(void*, const char *, input_driver_t**, void**);
/* Wraps whatever gl_proc_address() there is.
* Does not take opaque, to avoid lots of ugly wrapper code. */
gfx_ctx_proc_t (*get_proc_address)(const char*);
/* Returns true if this context supports EGLImage buffers for
* screen drawing and was initalized correctly. */
bool (*image_buffer_init)(void*, const video_info_t*);
/* Writes the frame to the EGLImage and sets image_handle to it.
* Returns true if a new image handle is created.
* Always returns true the first time it's called for a new index.
* The graphics core must handle a change in the handle correctly. */
bool (*image_buffer_write)(void*, const void *frame, unsigned width,
unsigned height, unsigned pitch, bool rgb32,
unsigned index, void **image_handle);
/* Shows or hides mouse. Can be NULL if context doesn't
* have a concept of mouse pointer. */
void (*show_mouse)(void *data, bool state);
/* Human readable string. */
const char *ident;
uint32_t (*get_flags)(void *data);
void (*set_flags)(void *data, uint32_t flags);
/* Optional. Binds HW-render offscreen context. */
void (*bind_hw_render)(void *data, bool enable);
/* Optional. Gets base data for the context which is used by the driver.
* This is mostly relevant for graphics APIs such as Vulkan
* which do not have global context state. */
void *(*get_context_data)(void *data);
/* Optional. Makes driver context (only GL right now)
* active for this thread. */
void (*make_current)(bool release);
} gfx_ctx_driver_t;
typedef struct gfx_ctx_size
{
bool *quit;
bool *resize;
unsigned *width;
unsigned *height;
} gfx_ctx_size_t;
typedef struct gfx_ctx_mode
{
unsigned width;
unsigned height;
bool fullscreen;
} gfx_ctx_mode_t;
typedef struct gfx_ctx_metrics
{
float *value;
enum display_metric_types type;
} gfx_ctx_metrics_t;
typedef struct gfx_ctx_aspect
{
float *aspect;
unsigned width;
unsigned height;
} gfx_ctx_aspect_t;
typedef struct gfx_ctx_input
{
input_driver_t **input;
void **input_data;
} gfx_ctx_input_t;
typedef struct gfx_ctx_ident
{
const char *ident;
} gfx_ctx_ident_t;
struct aspect_ratio_elem
{
float value;
char name[64];
};
/* Optionally implemented interface to poke more
* deeply into video driver. */
typedef struct video_poke_interface
{
uint32_t (*get_flags)(void *data);
uintptr_t (*load_texture)(void *video_data, void *data,
bool threaded, enum texture_filter_type filter_type);
void (*unload_texture)(void *data, bool threaded, uintptr_t id);
void (*set_video_mode)(void *data, unsigned width,
unsigned height, bool fullscreen);
float (*get_refresh_rate)(void *data);
void (*set_filtering)(void *data, unsigned index, bool smooth, bool ctx_scaling);
void (*get_video_output_size)(void *data,
unsigned *width, unsigned *height, char *desc, size_t desc_len);
/* Move index to previous resolution */
void (*get_video_output_prev)(void *data);
/* Move index to next resolution */
void (*get_video_output_next)(void *data);
uintptr_t (*get_current_framebuffer)(void *data);
retro_proc_address_t (*get_proc_address)(void *data, const char *sym);
void (*set_aspect_ratio)(void *data, unsigned aspectratio_index);
void (*apply_state_changes)(void *data);
/* Update texture. */
void (*set_texture_frame)(void *data, const void *frame, bool rgb32,
unsigned width, unsigned height, float alpha);
/* Enable or disable rendering. */
void (*set_texture_enable)(void *data, bool enable, bool full_screen);
void (*set_osd_msg)(void *data,
const char *msg,
const void *params, void *font);
void (*show_mouse)(void *data, bool state);
void (*grab_mouse_toggle)(void *data);
struct video_shader *(*get_current_shader)(void *data);
bool (*get_current_software_framebuffer)(void *data,
struct retro_framebuffer *framebuffer);
bool (*get_hw_render_interface)(void *data,
const struct retro_hw_render_interface **iface);
/* hdr settings */
void (*set_hdr_max_nits)(void *data, float max_nits);
void (*set_hdr_paper_white_nits)(void *data, float paper_white_nits);
void (*set_hdr_contrast)(void *data, float contrast);
void (*set_hdr_expand_gamut)(void *data, bool expand_gamut);
} video_poke_interface_t;
/* msg is for showing a message on the screen
* along with the video frame. */
typedef bool (*video_driver_frame_t)(void *data,
const void *frame, unsigned width,
unsigned height, uint64_t frame_count,
unsigned pitch, const char *msg, video_frame_info_t *video_info);
typedef struct video_driver
{
/* Should the video driver act as an input driver as well?
* The video initialization might preinitialize an input driver
* to override the settings in case the video driver relies on
* input driver for event handling. */
void *(*init)(const video_info_t *video,
input_driver_t **input,
void **input_data);
/* Updates frame on the screen.
* Frame can be either XRGB1555, RGB565 or ARGB32 format
* depending on rgb32 setting in video_info_t.
* Pitch is the distance in bytes between two scanlines in memory.
*
* When msg is non-NULL,
* it's a message that should be displayed to the user. */
video_driver_frame_t frame;
/* Should we care about syncing to vblank? Fast forwarding.
*
* Requests nonblocking operation.
*
* True = VSync is turned off.
* False = VSync is turned on.
* */
void (*set_nonblock_state)(void *data, bool toggle,
bool adaptive_vsync_enabled,
unsigned swap_interval);
/* Is the window still active? */
bool (*alive)(void *data);
/* Does the window have focus? */
bool (*focus)(void *data);
/* Should the screensaver be suppressed? */
bool (*suppress_screensaver)(void *data, bool enable);
/* Does the graphics context support windowed mode? */
bool (*has_windowed)(void *data);
/* Sets shader. Might not be implemented. Will be moved to
* poke_interface later. */
bool (*set_shader)(void *data, enum rarch_shader_type type,
const char *path);
/* Frees driver. */
void (*free)(void *data);
/* Human-readable identifier. */
const char *ident;
void (*set_viewport)(void *data, unsigned width, unsigned height,
bool force_full, bool allow_rotate);
void (*set_rotation)(void *data, unsigned rotation);
void (*viewport_info)(void *data, struct video_viewport *vp);
/* Reads out in BGR byte order (24bpp). */
bool (*read_viewport)(void *data, uint8_t *buffer, bool is_idle);
/* Returns a pointer to a newly allocated buffer that can
* (and must) be passed to free() by the caller, containing a
* copy of the current raw frame in the active pixel format
* and sets width, height and pitch to the correct values. */
void* (*read_frame_raw)(void *data, unsigned *width,
unsigned *height, size_t *pitch);
#ifdef HAVE_OVERLAY
void (*overlay_interface)(void *data,
const video_overlay_interface_t **iface);
#endif
#ifdef HAVE_VIDEO_LAYOUT
const video_layout_render_interface_t *(*video_layout_render_interface)(void *data);
#endif
void (*poke_interface)(void *data, const video_poke_interface_t **iface);
unsigned (*wrap_type_to_enum)(enum gfx_wrap_type type);
#if defined(HAVE_GFX_WIDGETS)
/* if set to true, will use display widgets when applicable
* if set to false, will use OSD as a fallback */
bool (*gfx_widgets_enabled)(void *data);
#endif
} video_driver_t;
typedef struct
{
#ifdef HAVE_CRTSWITCHRES
videocrt_switch_t crt_switch_st; /* double alignment */
#endif
struct retro_system_av_info av_info; /* double alignment */
retro_time_t frame_time_samples[MEASURE_FRAME_TIME_SAMPLES_COUNT];
retro_time_t core_frame_time;
uint64_t frame_time_count;
uint64_t frame_count;
uint8_t *record_gpu_buffer;
#ifdef HAVE_VIDEO_FILTER
rarch_softfilter_t *state_filter;
void *state_buffer;
#endif
void *data;
video_driver_t *current_video;
/* Interface for "poking". */
const video_poke_interface_t *poke;
gfx_ctx_driver_t current_video_context; /* ptr alignment */
struct retro_hw_render_callback hw_render; /* ptr alignment */
struct rarch_dir_shader_list dir_shader_list; /* ptr alignment */
#ifdef HAVE_THREADS
slock_t *display_lock;
slock_t *context_lock;
#endif
/* Used for 15-bit -> 16-bit conversions that take place before
* being passed to video driver. */
video_pixel_scaler_t *scaler_ptr;
video_driver_frame_t frame_bak; /* ptr alignment */
void *current_display_server_data;
const void *frame_cache_data;
const struct
retro_hw_render_context_negotiation_interface *
hw_render_context_negotiation;
#ifdef HAVE_MENU
struct video_shader *menu_driver_shader;
#endif
void *context_data;
/* Opaque handles to currently running window.
* Used by e.g. input drivers which bind to a window.
* Drivers are responsible for setting these if an input driver
* could potentially make use of this. */
uintptr_t display_userdata;
uintptr_t display;
uintptr_t window;
size_t frame_cache_pitch;
#ifdef HAVE_VIDEO_FILTER
unsigned state_scale;
unsigned state_out_bpp;
#endif
unsigned frame_delay_target;
unsigned frame_delay_effective;
unsigned frame_cache_width;
unsigned frame_cache_height;
unsigned width;
unsigned height;
float core_hz;
float aspect_ratio;
float video_refresh_rate_original;
enum retro_pixel_format pix_fmt;
enum rarch_display_type display_type;
enum rotation initial_screen_orientation;
enum rotation current_screen_orientation;
/**
* dynamic.c:dynamic_request_hw_context will try to set flag data when the context
* is in the middle of being rebuilt; in these cases we will save flag
* data and set this to true.
* When the context is reinit, it checks this, reads from
* deferred_flag_data and cleans it.
*
* TODO - Dirty hack, fix it better
*/
gfx_ctx_flags_t deferred_flag_data; /* uint32_t alignment */
char cli_shader_path[PATH_MAX_LENGTH];
char window_title[512];
char gpu_device_string[128];
char gpu_api_version_string[128];
char title_buf[64];
char cached_driver_id[32];
/**
* dynamic.c:dynamic_request_hw_context will try to set
* flag data when the context
* is in the middle of being rebuilt; in these cases we will save flag
* data and set this to true.
* When the context is reinit, it checks this, reads from
* deferred_flag_data and cleans it.
*
* TODO - Dirty hack, fix it better
*/
bool deferred_video_context_driver_set_flags;
bool window_title_update;
#ifdef HAVE_GFX_WIDGETS
bool widgets_paused;
bool widgets_fast_forward;
bool widgets_rewinding;
#endif
bool started_fullscreen;
/* Graphics driver requires RGBA byte order data (ABGR on little-endian)
* for 32-bit.
* This takes effect for overlay and shader cores that wants to load
* data into graphics driver. Kinda hackish to place it here, it is only
* used for GLES.
* TODO: Refactor this better. */
bool use_rgba;
/* Graphics driver supports HDR displays
* Currently only D3D11/D3D12 supports HDR displays and
* whether we've enabled it */
bool hdr_support;
/* If set during context deinit, the driver should keep
* graphics context alive to avoid having to reset all
* context state. */
bool cache_context;
/* Set to true by driver if context caching succeeded. */
bool cache_context_ack;
bool active;
#ifdef HAVE_VIDEO_FILTER
bool state_out_rgb32;
#endif
bool crt_switching_active;
bool force_fullscreen;
bool threaded;
bool is_switching_display_mode;
bool shader_presets_need_reload;
bool cli_shader_disable;
#ifdef HAVE_RUNAHEAD
bool runahead_is_active;
#endif
} video_driver_state_t;
typedef struct video_frame_delay_auto {
float refresh_rate;
unsigned frame_time_interval;
unsigned decrease;
unsigned target;
unsigned time;
} video_frame_delay_auto_t;
extern struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END];
bool video_driver_has_windowed(void);
bool video_driver_has_focus(void);
bool video_driver_cached_frame_has_valid_framebuffer(void);
void video_driver_set_cached_frame_ptr(const void *data);
void video_driver_set_stub_frame(void);
void video_driver_unset_stub_frame(void);
bool video_driver_supports_viewport_read(void);
bool video_driver_prefer_viewport_read(void);
bool video_driver_supports_read_frame_raw(void);
void video_driver_set_viewport_core(void);
void video_driver_reset_custom_viewport(settings_t *settings);
void video_driver_set_rgba(void);
void video_driver_unset_rgba(void);