• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Permission to use, copy, modify, distribute, and sell this software and its
3  * documentation for any purpose is hereby granted without fee, provided that
4  * the above copyright notice appear in all copies and that both that copyright
5  * notice and this permission notice appear in supporting documentation, and
6  * that the name of the copyright holders not be used in advertising or
7  * publicity pertaining to distribution of the software without specific,
8  * written prior permission.  The copyright holders make no representations
9  * about the suitability of this software for any purpose.  It is provided "as
10  * is" without express or implied warranty.
11  *
12  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
13  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
14  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
15  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
16  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
18  * OF THIS SOFTWARE.
19  */
20 
21 #include <errno.h>
22 #include <stdbool.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 
26 #include <GL/gl.h> /* dri_interface needs GL types */
27 #include <GL/internal/dri_interface.h>
28 
29 #include "drm-uapi/drm_fourcc.h"
30 #include "loader_dri_helper.h"
31 #include "util/driconf.h"
32 
loader_dri_create_image(__DRIscreen * screen,const __DRIimageExtension * image,uint32_t width,uint32_t height,uint32_t dri_format,uint32_t dri_usage,const uint64_t * modifiers,unsigned int modifiers_count,void * loaderPrivate)33 __DRIimage *loader_dri_create_image(__DRIscreen *screen,
34                                     const __DRIimageExtension *image,
35                                     uint32_t width, uint32_t height,
36                                     uint32_t dri_format, uint32_t dri_usage,
37                                     const uint64_t *modifiers,
38                                     unsigned int modifiers_count,
39                                     void *loaderPrivate)
40 {
41    if (modifiers && modifiers_count > 0 &&
42        image->base.version > 14 && image->createImageWithModifiers) {
43       bool has_valid_modifier = false;
44       int i;
45 
46       /* It's acceptable to create an image with INVALID modifier in the list,
47        * but it cannot be on the only modifier (since it will certainly fail
48        * later). While we could easily catch this after modifier creation, doing
49        * the check here is a convenient debug check likely pointing at whatever
50        * interface the client is using to build its modifier list.
51        */
52       for (i = 0; i < modifiers_count; i++) {
53          if (modifiers[i] != DRM_FORMAT_MOD_INVALID) {
54             has_valid_modifier = true;
55             break;
56          }
57       }
58       if (!has_valid_modifier)
59          return NULL;
60 
61       if (image->base.version >= 19 && image->createImageWithModifiers2)
62          return image->createImageWithModifiers2(screen, width, height,
63                                                  dri_format, modifiers,
64                                                  modifiers_count, dri_usage,
65                                                  loaderPrivate);
66       else
67          return image->createImageWithModifiers(screen, width, height,
68                                                 dri_format, modifiers,
69                                                 modifiers_count, loaderPrivate);
70    }
71 
72    /* No modifier given or fallback to the legacy createImage allowed */
73    return image->createImage(screen, width, height, dri_format, dri_usage,
74                              loaderPrivate);
75 }
76 
dri_vblank_mode(__DRIscreen * driScreen,const __DRI2configQueryExtension * config)77 static int dri_vblank_mode(__DRIscreen *driScreen, const __DRI2configQueryExtension *config)
78 {
79    GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
80 
81    if (config)
82       config->configQueryi(driScreen, "vblank_mode", &vblank_mode);
83 
84    return vblank_mode;
85 }
86 
dri_get_initial_swap_interval(__DRIscreen * driScreen,const __DRI2configQueryExtension * config)87 int dri_get_initial_swap_interval(__DRIscreen *driScreen,
88                                   const __DRI2configQueryExtension *config)
89 {
90    int vblank_mode = dri_vblank_mode(driScreen, config);
91 
92    switch (vblank_mode) {
93    case DRI_CONF_VBLANK_NEVER:
94    case DRI_CONF_VBLANK_DEF_INTERVAL_0:
95       return 0;
96    case DRI_CONF_VBLANK_DEF_INTERVAL_1:
97    case DRI_CONF_VBLANK_ALWAYS_SYNC:
98    default:
99       return 1;
100    }
101 }
102 
dri_valid_swap_interval(__DRIscreen * driScreen,const __DRI2configQueryExtension * config,int interval)103 bool dri_valid_swap_interval(__DRIscreen *driScreen,
104                              const __DRI2configQueryExtension *config, int interval)
105 {
106    int vblank_mode = dri_vblank_mode(driScreen, config);
107 
108    switch (vblank_mode) {
109    case DRI_CONF_VBLANK_NEVER:
110       if (interval != 0)
111          return false;
112       break;
113    case DRI_CONF_VBLANK_ALWAYS_SYNC:
114       if (interval <= 0)
115          return false;
116       break;
117    default:
118       break;
119    }
120 
121    return true;
122 }
123