1 /*  RetroArch - A frontend for libretro.
2  *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3  *  Copyright (C) 2011-2017 - Daniel De Matteis
4  *
5  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
6  *  of the GNU General Public License as published by the Free Software Found-
7  *  ation, either version 3 of the License, or (at your option) any later version.
8  *
9  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  *  PURPOSE.  See the GNU General Public License for more details.
12  *
13  *  You should have received a copy of the GNU General Public License along with RetroArch.
14  *  If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef __GFX_DISPLAY_H__
18 #define __GFX_DISPLAY_H__
19 
20 #include <stdint.h>
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
25 
26 #include <boolean.h>
27 #include <retro_common_api.h>
28 #include <string/stdstring.h>
29 #include <formats/image.h>
30 #include <gfx/math/matrix_4x4.h>
31 
32 #include "../retroarch.h"
33 #include "../file_path_special.h"
34 #include "../gfx/font_driver.h"
35 
36 RETRO_BEGIN_DECLS
37 
38 /* Number of pixels corner-to-corner on a 1080p
39  * display:
40  * > sqrt((1920 * 1920) + (1080 * 1080))
41  * Note: This is a double, so no suffix */
42 #define DIAGONAL_PIXELS_1080P 2202.90717008229831581901
43 
44 #define COLOR_TEXT_ALPHA(color, alpha) (color & 0xFFFFFF00) | alpha
45 
46 #define HEX_R(hex) ((hex >> 16) & 0xFF) * (1.0f / 255.0f)
47 #define HEX_G(hex) ((hex >> 8 ) & 0xFF) * (1.0f / 255.0f)
48 #define HEX_B(hex) ((hex >> 0 ) & 0xFF) * (1.0f / 255.0f)
49 
50 #define COLOR_HEX_TO_FLOAT(hex, alpha) { \
51    HEX_R(hex), HEX_G(hex), HEX_B(hex), alpha, \
52    HEX_R(hex), HEX_G(hex), HEX_B(hex), alpha, \
53    HEX_R(hex), HEX_G(hex), HEX_B(hex), alpha, \
54    HEX_R(hex), HEX_G(hex), HEX_B(hex), alpha  \
55 }
56 
57 #define gfx_display_set_alpha(color, alpha_value) (color[3] = color[7] = color[11] = color[15] = (alpha_value))
58 
59 /* Returns true if an animation is still active or
60  * when the display framebuffer still is dirty and
61  * therefore it still needs to be rendered onscreen.
62  *
63  * This macro can be used for optimization purposes
64  * so that we don't have to render the display graphics per-frame
65  * unless a change has happened.
66  * */
67 #define GFX_DISPLAY_GET_UPDATE_PENDING(p_anim, p_disp) (ANIM_IS_ACTIVE(p_anim) || p_disp->framebuf_dirty)
68 
69 enum menu_driver_id_type
70 {
71    MENU_DRIVER_ID_UNKNOWN = 0,
72    MENU_DRIVER_ID_RGUI,
73    MENU_DRIVER_ID_OZONE,
74    MENU_DRIVER_ID_GLUI,
75    MENU_DRIVER_ID_XMB,
76    MENU_DRIVER_ID_XUI,
77    MENU_DRIVER_ID_STRIPES
78 };
79 
80 
81 enum gfx_display_prim_type
82 {
83    GFX_DISPLAY_PRIM_NONE = 0,
84    GFX_DISPLAY_PRIM_TRIANGLESTRIP,
85    GFX_DISPLAY_PRIM_TRIANGLES
86 };
87 
88 enum gfx_display_driver_type
89 {
90    GFX_VIDEO_DRIVER_GENERIC = 0,
91    GFX_VIDEO_DRIVER_OPENGL,
92    GFX_VIDEO_DRIVER_OPENGL1,
93    GFX_VIDEO_DRIVER_OPENGL_CORE,
94    GFX_VIDEO_DRIVER_VULKAN,
95    GFX_VIDEO_DRIVER_METAL,
96    GFX_VIDEO_DRIVER_DIRECT3D8,
97    GFX_VIDEO_DRIVER_DIRECT3D9,
98    GFX_VIDEO_DRIVER_DIRECT3D10,
99    GFX_VIDEO_DRIVER_DIRECT3D11,
100    GFX_VIDEO_DRIVER_DIRECT3D12,
101    GFX_VIDEO_DRIVER_VITA2D,
102    GFX_VIDEO_DRIVER_CTR,
103    GFX_VIDEO_DRIVER_WIIU,
104    GFX_VIDEO_DRIVER_GDI,
105    GFX_VIDEO_DRIVER_SWITCH
106 };
107 
108 typedef struct gfx_display_frame_info
109 {
110    bool shadows_enable;
111 } gfx_display_frame_info_t;
112 
113 typedef struct gfx_display_ctx_draw gfx_display_ctx_draw_t;
114 
115 typedef struct gfx_display gfx_display_t;
116 
117 typedef struct gfx_display_ctx_driver
118 {
119    /* Draw graphics to the screen. */
120    void (*draw)(gfx_display_ctx_draw_t *draw,
121          void *data, unsigned video_width, unsigned video_height);
122    /* Draw one of the menu pipeline shaders. */
123    void (*draw_pipeline)(gfx_display_ctx_draw_t *draw,
124          gfx_display_t *p_disp,
125          void *data, unsigned video_width, unsigned video_height);
126    /* Start blending operation. */
127    void (*blend_begin)(void *data);
128    /* Finish blending operation. */
129    void (*blend_end)(void *data);
130    /* Get the default Model-View-Projection matrix */
131    void *(*get_default_mvp)(void *data);
132    /* Get the default vertices matrix */
133    const float *(*get_default_vertices)(void);
134    /* Get the default texture coordinates matrix */
135    const float *(*get_default_tex_coords)(void);
136    /* Initialize the first compatible font driver for this menu driver. */
137    bool (*font_init_first)(
138          void **font_handle, void *video_data,
139          const char *font_path, float font_size,
140          bool is_threaded);
141    enum gfx_display_driver_type type;
142    const char *ident;
143    bool handles_transform;
144    /* Enables and disables scissoring */
145    void (*scissor_begin)(void *data, unsigned video_width,
146          unsigned video_height,
147          int x, int y, unsigned width, unsigned height);
148    void (*scissor_end)(void *data, unsigned video_width,
149          unsigned video_height);
150 } gfx_display_ctx_driver_t;
151 
152 struct gfx_display_ctx_draw
153 {
154    float *color;
155    const float *vertex;
156    const float *tex_coord;
157    const void *backend_data;
158    struct video_coords *coords;
159    void *matrix_data;
160    uintptr_t texture;
161    size_t vertex_count;
162    size_t backend_data_size;
163    unsigned width;
164    unsigned height;
165    unsigned pipeline_id;
166    float x;
167    float y;
168    float rotation;
169    float scale_factor;
170    enum gfx_display_prim_type prim_type;
171    bool pipeline_active;
172 };
173 
174 typedef struct gfx_display_ctx_rotate_draw
175 {
176    math_matrix_4x4 *matrix;
177    float rotation;
178    float scale_x;
179    float scale_y;
180    float scale_z;
181    bool scale_enable;
182 } gfx_display_ctx_rotate_draw_t;
183 
184 typedef struct gfx_display_ctx_coord_draw
185 {
186    const float *ptr;
187 } gfx_display_ctx_coord_draw_t;
188 
189 typedef struct gfx_display_ctx_datetime
190 {
191    char *s;
192    size_t len;
193    unsigned time_mode;
194    unsigned date_separator;
195 } gfx_display_ctx_datetime_t;
196 
197 typedef struct gfx_display_ctx_powerstate
198 {
199    char *s;
200    size_t len;
201    unsigned percent;
202    bool battery_enabled;
203    bool charging;
204 } gfx_display_ctx_powerstate_t;
205 
206 struct gfx_display
207 {
208    gfx_display_ctx_driver_t *dispctx;
209    video_coord_array_t dispca; /* ptr alignment */
210 
211    /* Width, height and pitch of the display framebuffer */
212    size_t   framebuf_pitch;
213    unsigned framebuf_width;
214    unsigned framebuf_height;
215 
216    /* Height of the display header */
217    unsigned header_height;
218 
219    enum menu_driver_id_type menu_driver_id;
220 
221    bool has_windowed;
222    bool msg_force;
223    bool framebuf_dirty;
224 };
225 
226 void gfx_display_free(void);
227 
228 void gfx_display_init(void);
229 
230 void gfx_display_draw_cursor(
231       gfx_display_t *p_disp,
232       void *userdata,
233       unsigned video_width,
234       unsigned video_height,
235       bool cursor_visible,
236       float *color, float cursor_size, uintptr_t texture,
237       float x, float y, unsigned width, unsigned height);
238 
239 void gfx_display_draw_text(
240       const font_data_t *font, const char *text,
241       float x, float y, int width, int height,
242       uint32_t color, enum text_alignment text_align,
243       float scale_factor, bool shadows_enable, float shadow_offset,
244       bool draw_outside);
245 
246 font_data_t *gfx_display_font(
247       gfx_display_t *p_disp,
248       enum application_special_type type,
249       float font_size,
250       bool video_is_threaded);
251 
252 void gfx_display_scissor_begin(
253       gfx_display_t *p_disp,
254       void *userdata,
255       unsigned video_width,
256       unsigned video_height,
257       int x, int y, unsigned width, unsigned height);
258 
259 void gfx_display_font_free(font_data_t *font);
260 
261 void gfx_display_set_width(unsigned width);
262 void gfx_display_get_fb_size(unsigned *fb_width, unsigned *fb_height,
263       size_t *fb_pitch);
264 void gfx_display_set_height(unsigned height);
265 void gfx_display_set_framebuffer_pitch(size_t pitch);
266 
267 void gfx_display_set_msg_force(bool state);
268 bool gfx_display_init_first_driver(gfx_display_t *p_disp,
269       bool video_is_threaded);
270 
271 gfx_display_t *disp_get_ptr(void);
272 
273 void gfx_display_draw_keyboard(
274       gfx_display_t *p_disp,
275       void *userdata,
276       unsigned video_width,
277       unsigned video_height,
278       uintptr_t hover_texture,
279       const font_data_t *font,
280       char *grid[], unsigned id,
281       unsigned text_color);
282 
283 void gfx_display_draw_bg(
284       gfx_display_t *p_disp,
285       gfx_display_ctx_draw_t *draw,
286       void *userdata,
287       bool add_opacity, float opacity_override);
288 
289 void gfx_display_draw_quad(
290       gfx_display_t *p_disp,
291       void *data,
292       unsigned video_width,
293       unsigned video_height,
294       int x, int y, unsigned w, unsigned h,
295       unsigned width, unsigned height,
296       float *color);
297 
298 void gfx_display_draw_polygon(
299       gfx_display_t *p_disp,
300       void *userdata,
301       unsigned video_width,
302       unsigned video_height,
303       int x1, int y1,
304       int x2, int y2,
305       int x3, int y3,
306       int x4, int y4,
307       unsigned width, unsigned height,
308       float *color);
309 
310 void gfx_display_draw_texture_slice(
311       gfx_display_t *p_disp,
312       void *userdata,
313       unsigned video_width,
314       unsigned video_height,
315       int x, int y, unsigned w, unsigned h,
316       unsigned new_w, unsigned new_h,
317       unsigned width, unsigned height,
318       float *color, unsigned offset, float scale_factor, uintptr_t texture);
319 
320 void gfx_display_rotate_z(gfx_display_t *p_disp,
321       gfx_display_ctx_rotate_draw_t *draw, void *data);
322 
323 font_data_t *gfx_display_font_file(gfx_display_t *p_disp,
324       char* fontpath, float font_size, bool is_threaded);
325 
326 bool gfx_display_reset_textures_list(
327       const char *texture_path, const char *iconpath,
328       uintptr_t *item, enum texture_filter_type filter_type,
329       unsigned *width, unsigned *height);
330 
331 /* Returns the OSK key at a given position */
332 int gfx_display_osk_ptr_at_pos(void *data, int x, int y,
333       unsigned width, unsigned height);
334 
335 float gfx_display_get_adjusted_scale(
336       gfx_display_t *p_disp,
337       float base_scale, float scale_factor, unsigned width);
338 
339 float gfx_display_get_dpi_scale_internal(unsigned width, unsigned height);
340 
341 float gfx_display_get_dpi_scale(
342       gfx_display_t *p_disp,
343       void *settings_data,
344       unsigned width, unsigned height);
345 
346 void gfx_display_init_white_texture(uintptr_t white_texture);
347 
348 bool gfx_display_driver_exists(const char *s);
349 
350 bool gfx_display_init_first_driver(gfx_display_t *p_disp,
351       bool video_is_threaded);
352 
353 extern uintptr_t gfx_display_white_texture;
354 
355 extern gfx_display_ctx_driver_t gfx_display_ctx_gl;
356 extern gfx_display_ctx_driver_t gfx_display_ctx_gl_core;
357 extern gfx_display_ctx_driver_t gfx_display_ctx_gl1;
358 extern gfx_display_ctx_driver_t gfx_display_ctx_vulkan;
359 extern gfx_display_ctx_driver_t gfx_display_ctx_metal;
360 extern gfx_display_ctx_driver_t gfx_display_ctx_d3d8;
361 extern gfx_display_ctx_driver_t gfx_display_ctx_d3d9;
362 extern gfx_display_ctx_driver_t gfx_display_ctx_d3d10;
363 extern gfx_display_ctx_driver_t gfx_display_ctx_d3d11;
364 extern gfx_display_ctx_driver_t gfx_display_ctx_d3d12;
365 extern gfx_display_ctx_driver_t gfx_display_ctx_vita2d;
366 extern gfx_display_ctx_driver_t gfx_display_ctx_ctr;
367 extern gfx_display_ctx_driver_t gfx_display_ctx_wiiu;
368 extern gfx_display_ctx_driver_t gfx_display_ctx_gdi;
369 extern gfx_display_ctx_driver_t gfx_display_ctx_switch;
370 
371 RETRO_END_DECLS
372 
373 #endif
374