mesa/src/loader/loader_dri_helper.c

123 lines
4.5 KiB
C

/*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#include <GL/gl.h> /* dri_interface needs GL types */
#include <GL/internal/dri_interface.h>
#include "drm-uapi/drm_fourcc.h"
#include "loader_dri_helper.h"
#include "util/driconf.h"
__DRIimage *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)
{
if (modifiers && modifiers_count > 0 &&
image->base.version > 14 && image->createImageWithModifiers) {
bool has_valid_modifier = false;
int i;
/* It's acceptable to create an image with INVALID modifier in the list,
* but it cannot be on the only modifier (since it will certainly fail
* later). While we could easily catch this after modifier creation, doing
* the check here is a convenient debug check likely pointing at whatever
* interface the client is using to build its modifier list.
*/
for (i = 0; i < modifiers_count; i++) {
if (modifiers[i] != DRM_FORMAT_MOD_INVALID) {
has_valid_modifier = true;
break;
}
}
if (!has_valid_modifier)
return NULL;
if (image->base.version >= 19 && image->createImageWithModifiers2)
return image->createImageWithModifiers2(screen, width, height,
dri_format, modifiers,
modifiers_count, dri_usage,
loaderPrivate);
else
return image->createImageWithModifiers(screen, width, height,
dri_format, modifiers,
modifiers_count, loaderPrivate);
}
/* No modifier given or fallback to the legacy createImage allowed */
return image->createImage(screen, width, height, dri_format, dri_usage,
loaderPrivate);
}
static int dri_vblank_mode(__DRIscreen *driScreen, const __DRI2configQueryExtension *config)
{
GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
if (config)
config->configQueryi(driScreen, "vblank_mode", &vblank_mode);
return vblank_mode;
}
int dri_get_initial_swap_interval(__DRIscreen *driScreen,
const __DRI2configQueryExtension *config)
{
int vblank_mode = dri_vblank_mode(driScreen, config);
switch (vblank_mode) {
case DRI_CONF_VBLANK_NEVER:
case DRI_CONF_VBLANK_DEF_INTERVAL_0:
return 0;
case DRI_CONF_VBLANK_DEF_INTERVAL_1:
case DRI_CONF_VBLANK_ALWAYS_SYNC:
default:
return 1;
}
}
bool dri_valid_swap_interval(__DRIscreen *driScreen,
const __DRI2configQueryExtension *config, int interval)
{
int vblank_mode = dri_vblank_mode(driScreen, config);
switch (vblank_mode) {
case DRI_CONF_VBLANK_NEVER:
if (interval != 0)
return false;
break;
case DRI_CONF_VBLANK_ALWAYS_SYNC:
if (interval <= 0)
return false;
break;
default:
break;
}
return true;
}