Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4357 → Rev 4358

/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/Android.mk
0,0 → 1,60
# Mesa 3-D graphics library
#
# Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
# Copyright (C) 2010-2011 LunarG Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
 
LOCAL_PATH := $(call my-dir)
 
common_SOURCES := \
common/egl_g3d.c \
common/egl_g3d_api.c \
common/egl_g3d_image.c \
common/egl_g3d_st.c \
common/egl_g3d_sync.c \
common/native_helper.c
 
android_SOURCES := \
android/native_android.cpp
 
include $(CLEAR_VARS)
 
LOCAL_SRC_FILES := \
$(common_SOURCES) \
$(android_SOURCES)
 
LOCAL_CFLAGS := -DHAVE_ANDROID_BACKEND
 
LOCAL_C_INCLUDES := \
$(GALLIUM_TOP)/state_trackers/egl \
$(GALLIUM_TOP)/winsys/sw \
$(MESA_TOP)/src/egl/main
 
# swrast only
ifeq ($(MESA_GPU_DRIVERS),swrast)
LOCAL_CFLAGS += -DANDROID_BACKEND_NO_DRM
else
LOCAL_C_INCLUDES += $(DRM_GRALLOC_TOP)
endif
 
LOCAL_MODULE := libmesa_st_egl
 
include $(GALLIUM_COMMON_MK)
include $(BUILD_STATIC_LIBRARY)
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/Makefile.am
0,0 → 1,104
# Copyright © 2012 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
 
AUTOMAKE_OPTIONS = subdir-objects
 
include $(top_srcdir)/src/gallium/Automake.inc
 
AM_CFLAGS = $(GALLIUM_CFLAGS)
AM_CPPFLAGS = \
-I$(top_srcdir)/src/egl/main \
-I$(top_builddir)/src/egl/wayland/wayland-drm/ \
-I$(top_srcdir)/include
 
noinst_LTLIBRARIES = libegl.la
libegl_la_SOURCES = \
common/egl_g3d_api.c \
common/egl_g3d.c \
common/egl_g3d_image.c \
common/egl_g3d_st.c \
common/egl_g3d_sync.c \
common/native_helper.c \
common/native_wayland_drm_bufmgr_helper.c
 
if HAVE_EGL_PLATFORM_X11
libegl_la_SOURCES += \
x11/glxinit.c \
x11/native_dri2.c \
x11/native_x11.c \
x11/native_ximage.c \
x11/x11_screen.c \
x11/dri2.c
AM_CFLAGS += \
$(X11_CFLAGS) \
$(LIBDRM_CFLAGS) \
$(DRI2PROTO_CFLAGS)
AM_CPPFLAGS += \
-I$(top_srcdir)/src/gallium/drivers \
-I$(top_srcdir)/src/glx \
-I$(top_srcdir)/src/mapi \
-I$(top_srcdir)/src/mesa \
-DHAVE_X11_BACKEND
endif
 
if HAVE_EGL_PLATFORM_WAYLAND
libegl_la_SOURCES += \
wayland/native_drm.c \
wayland/native_shm.c \
wayland/native_wayland.c
AM_CFLAGS += \
$(LIBDRM_CFLAGS) \
$(WAYLAND_CFLAGS)
AM_CPPFLAGS += \
-I$(top_srcdir)/src/gallium/winsys \
-I$(top_srcdir)/src/egl/wayland/wayland-egl \
-I$(top_srcdir)/src/egl/wayland/wayland-drm \
-I$(top_builddir)/src/egl/wayland/wayland-drm \
-DHAVE_WAYLAND_BACKEND
endif
 
if HAVE_EGL_PLATFORM_DRM
libegl_la_SOURCES += \
drm/modeset.c \
drm/native_drm.c
AM_CFLAGS += \
$(LIBDRM_CFLAGS)
AM_CPPFLAGS += \
-I$(top_srcdir)/src/gallium/winsys \
-I$(top_srcdir)/src/gbm/main \
-I$(top_srcdir)/src/gallium/state_trackers/gbm \
-DHAVE_DRM_BACKEND
endif
 
if HAVE_EGL_PLATFORM_FBDEV
libegl_la_SOURCES += fbdev/native_fbdev.c
AM_CPPFLAGS += \
-I$(top_srcdir)/src/gallium/winsys/sw \
-DHAVE_FBDEV_BACKEND
endif
 
if HAVE_EGL_PLATFORM_NULL
libegl_la_SOURCES += null/native_null.c
AM_CPPFLAGS += \
-I$(top_srcdir)/src/gallium/winsys/sw \
-DHAVE_NULL_BACKEND
endif
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/Makefile.in
0,0 → 1,991
# Makefile.in generated by automake 1.14 from Makefile.am.
# @configure_input@
 
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
@SET_MAKE@
 
# Copyright © 2012 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
 
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(top_srcdir)/src/gallium/Automake.inc \
$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/bin/depcomp
@HAVE_EGL_PLATFORM_X11_TRUE@am__append_1 = \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/glxinit.c \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/native_dri2.c \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/native_x11.c \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/native_ximage.c \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/x11_screen.c \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/dri2.c
 
@HAVE_EGL_PLATFORM_X11_TRUE@am__append_2 = \
@HAVE_EGL_PLATFORM_X11_TRUE@ $(X11_CFLAGS) \
@HAVE_EGL_PLATFORM_X11_TRUE@ $(LIBDRM_CFLAGS) \
@HAVE_EGL_PLATFORM_X11_TRUE@ $(DRI2PROTO_CFLAGS)
 
@HAVE_EGL_PLATFORM_X11_TRUE@am__append_3 = \
@HAVE_EGL_PLATFORM_X11_TRUE@ -I$(top_srcdir)/src/gallium/drivers \
@HAVE_EGL_PLATFORM_X11_TRUE@ -I$(top_srcdir)/src/glx \
@HAVE_EGL_PLATFORM_X11_TRUE@ -I$(top_srcdir)/src/mapi \
@HAVE_EGL_PLATFORM_X11_TRUE@ -I$(top_srcdir)/src/mesa \
@HAVE_EGL_PLATFORM_X11_TRUE@ -DHAVE_X11_BACKEND
 
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@am__append_4 = \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ wayland/native_drm.c \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ wayland/native_shm.c \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ wayland/native_wayland.c
 
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@am__append_5 = \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ $(LIBDRM_CFLAGS) \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ $(WAYLAND_CFLAGS)
 
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@am__append_6 = \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ -I$(top_srcdir)/src/gallium/winsys \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ -I$(top_srcdir)/src/egl/wayland/wayland-egl \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ -I$(top_srcdir)/src/egl/wayland/wayland-drm \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ -I$(top_builddir)/src/egl/wayland/wayland-drm \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ -DHAVE_WAYLAND_BACKEND
 
@HAVE_EGL_PLATFORM_DRM_TRUE@am__append_7 = \
@HAVE_EGL_PLATFORM_DRM_TRUE@ drm/modeset.c \
@HAVE_EGL_PLATFORM_DRM_TRUE@ drm/native_drm.c
 
@HAVE_EGL_PLATFORM_DRM_TRUE@am__append_8 = \
@HAVE_EGL_PLATFORM_DRM_TRUE@ $(LIBDRM_CFLAGS)
 
@HAVE_EGL_PLATFORM_DRM_TRUE@am__append_9 = \
@HAVE_EGL_PLATFORM_DRM_TRUE@ -I$(top_srcdir)/src/gallium/winsys \
@HAVE_EGL_PLATFORM_DRM_TRUE@ -I$(top_srcdir)/src/gbm/main \
@HAVE_EGL_PLATFORM_DRM_TRUE@ -I$(top_srcdir)/src/gallium/state_trackers/gbm \
@HAVE_EGL_PLATFORM_DRM_TRUE@ -DHAVE_DRM_BACKEND
 
@HAVE_EGL_PLATFORM_FBDEV_TRUE@am__append_10 = fbdev/native_fbdev.c
@HAVE_EGL_PLATFORM_FBDEV_TRUE@am__append_11 = \
@HAVE_EGL_PLATFORM_FBDEV_TRUE@ -I$(top_srcdir)/src/gallium/winsys/sw \
@HAVE_EGL_PLATFORM_FBDEV_TRUE@ -DHAVE_FBDEV_BACKEND
 
@HAVE_EGL_PLATFORM_NULL_TRUE@am__append_12 = null/native_null.c
@HAVE_EGL_PLATFORM_NULL_TRUE@am__append_13 = \
@HAVE_EGL_PLATFORM_NULL_TRUE@ -I$(top_srcdir)/src/gallium/winsys/sw \
@HAVE_EGL_PLATFORM_NULL_TRUE@ -DHAVE_NULL_BACKEND
 
subdir = src/gallium/state_trackers/egl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_prog_bison.m4 \
$(top_srcdir)/m4/ax_prog_cc_for_build.m4 \
$(top_srcdir)/m4/ax_prog_cxx_for_build.m4 \
$(top_srcdir)/m4/ax_prog_flex.m4 \
$(top_srcdir)/m4/ax_pthread.m4 \
$(top_srcdir)/m4/ax_python_module.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libegl_la_LIBADD =
am__libegl_la_SOURCES_DIST = common/egl_g3d_api.c common/egl_g3d.c \
common/egl_g3d_image.c common/egl_g3d_st.c \
common/egl_g3d_sync.c common/native_helper.c \
common/native_wayland_drm_bufmgr_helper.c x11/glxinit.c \
x11/native_dri2.c x11/native_x11.c x11/native_ximage.c \
x11/x11_screen.c x11/dri2.c wayland/native_drm.c \
wayland/native_shm.c wayland/native_wayland.c drm/modeset.c \
drm/native_drm.c fbdev/native_fbdev.c null/native_null.c
am__dirstamp = $(am__leading_dot)dirstamp
@HAVE_EGL_PLATFORM_X11_TRUE@am__objects_1 = x11/glxinit.lo \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/native_dri2.lo \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/native_x11.lo \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/native_ximage.lo \
@HAVE_EGL_PLATFORM_X11_TRUE@ x11/x11_screen.lo x11/dri2.lo
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@am__objects_2 = wayland/native_drm.lo \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ wayland/native_shm.lo \
@HAVE_EGL_PLATFORM_WAYLAND_TRUE@ wayland/native_wayland.lo
@HAVE_EGL_PLATFORM_DRM_TRUE@am__objects_3 = drm/modeset.lo \
@HAVE_EGL_PLATFORM_DRM_TRUE@ drm/native_drm.lo
@HAVE_EGL_PLATFORM_FBDEV_TRUE@am__objects_4 = fbdev/native_fbdev.lo
@HAVE_EGL_PLATFORM_NULL_TRUE@am__objects_5 = null/native_null.lo
am_libegl_la_OBJECTS = common/egl_g3d_api.lo common/egl_g3d.lo \
common/egl_g3d_image.lo common/egl_g3d_st.lo \
common/egl_g3d_sync.lo common/native_helper.lo \
common/native_wayland_drm_bufmgr_helper.lo $(am__objects_1) \
$(am__objects_2) $(am__objects_3) $(am__objects_4) \
$(am__objects_5)
libegl_la_OBJECTS = $(am_libegl_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/bin/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libegl_la_SOURCES)
DIST_SOURCES = $(am__libegl_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_EXEEXT = @BUILD_EXEEXT@
BUILD_OBJEXT = @BUILD_OBJEXT@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CC_FOR_BUILD = @CC_FOR_BUILD@
CFLAGS = @CFLAGS@
CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@
CLOCK_LIB = @CLOCK_LIB@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
CPP_FOR_BUILD = @CPP_FOR_BUILD@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXCPPFLAGS_FOR_BUILD = @CXXCPPFLAGS_FOR_BUILD@
CXXCPP_FOR_BUILD = @CXXCPP_FOR_BUILD@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
CXX_FOR_BUILD = @CXX_FOR_BUILD@
CYGPATH_W = @CYGPATH_W@
DEFINES = @DEFINES@
DEFINES_FOR_BUILD = @DEFINES_FOR_BUILD@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DLOPEN_LIBS = @DLOPEN_LIBS@
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
DRIGL_CFLAGS = @DRIGL_CFLAGS@
DRIGL_LIBS = @DRIGL_LIBS@
DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@
DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@
DRI_LIB_DEPS = @DRI_LIB_DEPS@
DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGL_CFLAGS = @EGL_CFLAGS@
EGL_CLIENT_APIS = @EGL_CLIENT_APIS@
EGL_DRIVER_INSTALL_DIR = @EGL_DRIVER_INSTALL_DIR@
EGL_LIB_DEPS = @EGL_LIB_DEPS@
EGL_LIB_GLOB = @EGL_LIB_GLOB@
EGL_LIB_NAME = @EGL_LIB_NAME@
EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@
EGL_PLATFORMS = @EGL_PLATFORMS@
EGREP = @EGREP@
ELF_LIB = @ELF_LIB@
EXEEXT = @EXEEXT@
EXPAT_INCLUDES = @EXPAT_INCLUDES@
FGREP = @FGREP@
FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@
FREEDRENO_LIBS = @FREEDRENO_LIBS@
GALLIUM_DRI_LIB_DEPS = @GALLIUM_DRI_LIB_DEPS@
GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@
GALLIUM_PIPE_LOADER_LIBS = @GALLIUM_PIPE_LOADER_LIBS@
GALLIUM_PIPE_LOADER_XCB_CFLAGS = @GALLIUM_PIPE_LOADER_XCB_CFLAGS@
GALLIUM_PIPE_LOADER_XCB_LIBS = @GALLIUM_PIPE_LOADER_XCB_LIBS@
GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@
GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@
GLAPI_LIB_GLOB = @GLAPI_LIB_GLOB@
GLAPI_LIB_NAME = @GLAPI_LIB_NAME@
GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@
GLESv1_CM_LIB_GLOB = @GLESv1_CM_LIB_GLOB@
GLESv1_CM_LIB_NAME = @GLESv1_CM_LIB_NAME@
GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@
GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@
GLESv2_LIB_GLOB = @GLESv2_LIB_GLOB@
GLESv2_LIB_NAME = @GLESv2_LIB_NAME@
GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@
GLPROTO_CFLAGS = @GLPROTO_CFLAGS@
GLPROTO_LIBS = @GLPROTO_LIBS@
GLX_TLS = @GLX_TLS@
GL_LIB = @GL_LIB@
GL_LIB_DEPS = @GL_LIB_DEPS@
GL_LIB_GLOB = @GL_LIB_GLOB@
GL_LIB_NAME = @GL_LIB_NAME@
GL_PC_CFLAGS = @GL_PC_CFLAGS@
GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@
GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@
GREP = @GREP@
HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@
INDENT = @INDENT@
INDENT_FLAGS = @INDENT_FLAGS@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTEL_CFLAGS = @INTEL_CFLAGS@
INTEL_LIBS = @INTEL_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@
LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@
LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
LIBDRM_LIBS = @LIBDRM_LIBS@
LIBDRM_XORG_CFLAGS = @LIBDRM_XORG_CFLAGS@
LIBDRM_XORG_LIBS = @LIBDRM_XORG_LIBS@
LIBKMS_XORG_CFLAGS = @LIBKMS_XORG_CFLAGS@
LIBKMS_XORG_LIBS = @LIBKMS_XORG_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@
LIBUDEV_LIBS = @LIBUDEV_LIBS@
LIB_DIR = @LIB_DIR@
LIPO = @LIPO@
LLVM_BINDIR = @LLVM_BINDIR@
LLVM_CFLAGS = @LLVM_CFLAGS@
LLVM_CONFIG = @LLVM_CONFIG@
LLVM_CPPFLAGS = @LLVM_CPPFLAGS@
LLVM_CXXFLAGS = @LLVM_CXXFLAGS@
LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@
LLVM_LDFLAGS = @LLVM_LDFLAGS@
LLVM_LIBDIR = @LLVM_LIBDIR@
LLVM_LIBS = @LLVM_LIBS@
LLVM_VERSION = @LLVM_VERSION@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKE = @MAKE@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MESA_LLVM = @MESA_LLVM@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@
NOUVEAU_LIBS = @NOUVEAU_LIBS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OPENCL_LIB_INSTALL_DIR = @OPENCL_LIB_INSTALL_DIR@
OSMESA_LIB = @OSMESA_LIB@
OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@
OSMESA_LIB_NAME = @OSMESA_LIB_NAME@
OSMESA_MESA_DEPS = @OSMESA_MESA_DEPS@
OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@
OSMESA_PC_REQ = @OSMESA_PC_REQ@
OSMESA_VERSION = @OSMESA_VERSION@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSIX_SHELL = @POSIX_SHELL@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
PYTHON2 = @PYTHON2@
RADEON_CFLAGS = @RADEON_CFLAGS@
RADEON_LIBS = @RADEON_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SELINUX_LIBS = @SELINUX_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VDPAU_CFLAGS = @VDPAU_CFLAGS@
VDPAU_LIBS = @VDPAU_LIBS@
VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@
VDPAU_MAJOR = @VDPAU_MAJOR@
VDPAU_MINOR = @VDPAU_MINOR@
VERSION = @VERSION@
VG_LIB_DEPS = @VG_LIB_DEPS@
VG_LIB_GLOB = @VG_LIB_GLOB@
VG_LIB_NAME = @VG_LIB_NAME@
VG_PC_LIB_PRIV = @VG_PC_LIB_PRIV@
VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@
VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@
WAYLAND_CFLAGS = @WAYLAND_CFLAGS@
WAYLAND_LIBS = @WAYLAND_LIBS@
WAYLAND_SCANNER = @WAYLAND_SCANNER@
X11_INCLUDES = @X11_INCLUDES@
XA_MAJOR = @XA_MAJOR@
XA_MINOR = @XA_MINOR@
XA_TINY = @XA_TINY@
XA_VERSION = @XA_VERSION@
XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@
XCB_DRI2_LIBS = @XCB_DRI2_LIBS@
XEXT_CFLAGS = @XEXT_CFLAGS@
XEXT_LIBS = @XEXT_LIBS@
XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
XLIBGL_CFLAGS = @XLIBGL_CFLAGS@
XLIBGL_LIBS = @XLIBGL_LIBS@
XORG_CFLAGS = @XORG_CFLAGS@
XORG_DRIVER_INSTALL_DIR = @XORG_DRIVER_INSTALL_DIR@
XORG_LIBS = @XORG_LIBS@
XVMC_CFLAGS = @XVMC_CFLAGS@
XVMC_LIBS = @XVMC_LIBS@
XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@
XVMC_MAJOR = @XVMC_MAJOR@
XVMC_MINOR = @XVMC_MINOR@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_CXX_FOR_BUILD = @ac_ct_CXX_FOR_BUILD@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = subdir-objects
GALLIUM_CFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/gallium/include \
-I$(top_srcdir)/src/gallium/auxiliary \
$(DEFINES)
 
AM_CFLAGS = $(GALLIUM_CFLAGS) $(am__append_2) $(am__append_5) \
$(am__append_8)
AM_CPPFLAGS = -I$(top_srcdir)/src/egl/main \
-I$(top_builddir)/src/egl/wayland/wayland-drm/ \
-I$(top_srcdir)/include $(am__append_3) $(am__append_6) \
$(am__append_9) $(am__append_11) $(am__append_13)
noinst_LTLIBRARIES = libegl.la
libegl_la_SOURCES = common/egl_g3d_api.c common/egl_g3d.c \
common/egl_g3d_image.c common/egl_g3d_st.c \
common/egl_g3d_sync.c common/native_helper.c \
common/native_wayland_drm_bufmgr_helper.c $(am__append_1) \
$(am__append_4) $(am__append_7) $(am__append_10) \
$(am__append_12)
all: all-am
 
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/src/gallium/Automake.inc $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/gallium/state_trackers/egl/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/gallium/state_trackers/egl/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_srcdir)/src/gallium/Automake.inc:
 
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
 
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
common/$(am__dirstamp):
@$(MKDIR_P) common
@: > common/$(am__dirstamp)
common/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) common/$(DEPDIR)
@: > common/$(DEPDIR)/$(am__dirstamp)
common/egl_g3d_api.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/egl_g3d.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/egl_g3d_image.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/egl_g3d_st.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/egl_g3d_sync.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/native_helper.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/native_wayland_drm_bufmgr_helper.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
x11/$(am__dirstamp):
@$(MKDIR_P) x11
@: > x11/$(am__dirstamp)
x11/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) x11/$(DEPDIR)
@: > x11/$(DEPDIR)/$(am__dirstamp)
x11/glxinit.lo: x11/$(am__dirstamp) x11/$(DEPDIR)/$(am__dirstamp)
x11/native_dri2.lo: x11/$(am__dirstamp) x11/$(DEPDIR)/$(am__dirstamp)
x11/native_x11.lo: x11/$(am__dirstamp) x11/$(DEPDIR)/$(am__dirstamp)
x11/native_ximage.lo: x11/$(am__dirstamp) \
x11/$(DEPDIR)/$(am__dirstamp)
x11/x11_screen.lo: x11/$(am__dirstamp) x11/$(DEPDIR)/$(am__dirstamp)
x11/dri2.lo: x11/$(am__dirstamp) x11/$(DEPDIR)/$(am__dirstamp)
wayland/$(am__dirstamp):
@$(MKDIR_P) wayland
@: > wayland/$(am__dirstamp)
wayland/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) wayland/$(DEPDIR)
@: > wayland/$(DEPDIR)/$(am__dirstamp)
wayland/native_drm.lo: wayland/$(am__dirstamp) \
wayland/$(DEPDIR)/$(am__dirstamp)
wayland/native_shm.lo: wayland/$(am__dirstamp) \
wayland/$(DEPDIR)/$(am__dirstamp)
wayland/native_wayland.lo: wayland/$(am__dirstamp) \
wayland/$(DEPDIR)/$(am__dirstamp)
drm/$(am__dirstamp):
@$(MKDIR_P) drm
@: > drm/$(am__dirstamp)
drm/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) drm/$(DEPDIR)
@: > drm/$(DEPDIR)/$(am__dirstamp)
drm/modeset.lo: drm/$(am__dirstamp) drm/$(DEPDIR)/$(am__dirstamp)
drm/native_drm.lo: drm/$(am__dirstamp) drm/$(DEPDIR)/$(am__dirstamp)
fbdev/$(am__dirstamp):
@$(MKDIR_P) fbdev
@: > fbdev/$(am__dirstamp)
fbdev/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) fbdev/$(DEPDIR)
@: > fbdev/$(DEPDIR)/$(am__dirstamp)
fbdev/native_fbdev.lo: fbdev/$(am__dirstamp) \
fbdev/$(DEPDIR)/$(am__dirstamp)
null/$(am__dirstamp):
@$(MKDIR_P) null
@: > null/$(am__dirstamp)
null/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) null/$(DEPDIR)
@: > null/$(DEPDIR)/$(am__dirstamp)
null/native_null.lo: null/$(am__dirstamp) \
null/$(DEPDIR)/$(am__dirstamp)
 
libegl.la: $(libegl_la_OBJECTS) $(libegl_la_DEPENDENCIES) $(EXTRA_libegl_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(libegl_la_OBJECTS) $(libegl_la_LIBADD) $(LIBS)
 
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f common/*.$(OBJEXT)
-rm -f common/*.lo
-rm -f drm/*.$(OBJEXT)
-rm -f drm/*.lo
-rm -f fbdev/*.$(OBJEXT)
-rm -f fbdev/*.lo
-rm -f null/*.$(OBJEXT)
-rm -f null/*.lo
-rm -f wayland/*.$(OBJEXT)
-rm -f wayland/*.lo
-rm -f x11/*.$(OBJEXT)
-rm -f x11/*.lo
 
distclean-compile:
-rm -f *.tab.c
 
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/egl_g3d.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/egl_g3d_api.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/egl_g3d_image.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/egl_g3d_st.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/egl_g3d_sync.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/native_helper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/native_wayland_drm_bufmgr_helper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@drm/$(DEPDIR)/modeset.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@drm/$(DEPDIR)/native_drm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@fbdev/$(DEPDIR)/native_fbdev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@null/$(DEPDIR)/native_null.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@wayland/$(DEPDIR)/native_drm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@wayland/$(DEPDIR)/native_shm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@wayland/$(DEPDIR)/native_wayland.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@x11/$(DEPDIR)/dri2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@x11/$(DEPDIR)/glxinit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@x11/$(DEPDIR)/native_dri2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@x11/$(DEPDIR)/native_x11.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@x11/$(DEPDIR)/native_ximage.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@x11/$(DEPDIR)/x11_screen.Plo@am__quote@
 
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
 
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
mostlyclean-libtool:
-rm -f *.lo
 
clean-libtool:
-rm -rf .libs _libs
-rm -rf common/.libs common/_libs
-rm -rf drm/.libs drm/_libs
-rm -rf fbdev/.libs fbdev/_libs
-rm -rf null/.libs null/_libs
-rm -rf wayland/.libs wayland/_libs
-rm -rf x11/.libs x11/_libs
 
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
 
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
 
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
 
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
 
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
 
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-rm -f common/$(DEPDIR)/$(am__dirstamp)
-rm -f common/$(am__dirstamp)
-rm -f drm/$(DEPDIR)/$(am__dirstamp)
-rm -f drm/$(am__dirstamp)
-rm -f fbdev/$(DEPDIR)/$(am__dirstamp)
-rm -f fbdev/$(am__dirstamp)
-rm -f null/$(DEPDIR)/$(am__dirstamp)
-rm -f null/$(am__dirstamp)
-rm -f wayland/$(DEPDIR)/$(am__dirstamp)
-rm -f wayland/$(am__dirstamp)
-rm -f x11/$(DEPDIR)/$(am__dirstamp)
-rm -f x11/$(am__dirstamp)
 
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
 
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
 
distclean: distclean-am
-rm -rf common/$(DEPDIR) drm/$(DEPDIR) fbdev/$(DEPDIR) null/$(DEPDIR) wayland/$(DEPDIR) x11/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
 
dvi: dvi-am
 
dvi-am:
 
html: html-am
 
html-am:
 
info: info-am
 
info-am:
 
install-data-am:
 
install-dvi: install-dvi-am
 
install-dvi-am:
 
install-exec-am:
 
install-html: install-html-am
 
install-html-am:
 
install-info: install-info-am
 
install-info-am:
 
install-man:
 
install-pdf: install-pdf-am
 
install-pdf-am:
 
install-ps: install-ps-am
 
install-ps-am:
 
installcheck-am:
 
maintainer-clean: maintainer-clean-am
-rm -rf common/$(DEPDIR) drm/$(DEPDIR) fbdev/$(DEPDIR) null/$(DEPDIR) wayland/$(DEPDIR) x11/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
 
mostlyclean: mostlyclean-am
 
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
 
pdf: pdf-am
 
pdf-am:
 
ps: ps-am
 
ps-am:
 
uninstall-am:
 
.MAKE: install-am install-strip
 
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
 
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/SConscript
0,0 → 1,59
#######################################################################
# SConscript for egl state_tracker
 
Import('*')
 
env = env.Clone()
 
env.Append(CPPPATH = [
'#/src/egl/main',
'#/src/gallium/winsys/sw',
'.',
])
 
sources = [
'common/egl_g3d.c',
'common/egl_g3d_api.c',
'common/egl_g3d_image.c',
'common/egl_g3d_st.c',
'common/egl_g3d_sync.c',
'common/native_helper.c',
]
 
if env['platform'] == 'windows':
env.Append(CPPDEFINES = ['HAVE_GDI_BACKEND'])
sources.append('gdi/native_gdi.c')
else:
if env['drm']:
env.PkgUseModules('DRM')
if env['x11']:
env.Append(CPPDEFINES = ['HAVE_X11_BACKEND'])
env.Prepend(CPPPATH = [
'#/src/glx',
'#/src/mapi',
])
sources.append([
'x11/native_x11.c',
'x11/native_dri2.c',
'x11/native_ximage.c',
'x11/glxinit.c'])
if env['drm']:
env.Append(CPPDEFINES = ['GLX_DIRECT_RENDERING'])
sources.append([
'#/src/glx/dri2.c',
'x11/x11_screen.c',
])
if env['drm'] and False:
# XXX: Disabled as it depends on gbm, which is not yet built with scons
env.Append(CPPDEFINES = ['HAVE_DRM_BACKEND'])
env.Append(CPPPATH = [
'#/src/gbm/main',
'#/src/gallium/state_trackers/gbm',
])
sources.append(['drm/native_drm.c', 'drm/modeset.c'])
 
st_egl = env.ConvenienceLibrary(
target = 'st_egl',
source = sources,
)
Export('st_egl')
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/android/native_android.cpp
0,0 → 1,889
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
* Copyright (C) 2010-2011 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#define LOG_TAG "EGL-GALLIUM"
 
#if ANDROID_VERSION >= 0x0400
 
#if ANDROID_VERSION >= 0x0402
#include <sync/sync.h>
#endif
 
#include <stdlib.h>
#include <system/window.h>
 
#else /* ANDROID_VERSION >= 0x0400 */
 
#define android_native_buffer_t ANativeWindowBuffer
#include <ui/egl/android_natives.h>
#include <ui/android_native_buffer.h>
 
#endif /* ANDROID_VERSION >= 0x0400 */
 
#if ANDROID_VERSION < 0x0402
/* rename to old logging macros */
#define ALOGE(...) LOGE(__VA_ARGS__)
#define ALOGW(...) LOGW(__VA_ARGS__)
#define ALOGI(...) LOGI(__VA_ARGS__)
#define ALOGD(...) LOGD(__VA_ARGS__)
#endif
 
#include <hardware/gralloc.h>
#include <cutils/properties.h>
#include <cutils/log.h>
#include <utils/Errors.h>
 
extern "C" {
#include "egllog.h"
}
 
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_box.h"
#include "common/native.h"
#include "common/native_helper.h"
#include "android/android_sw_winsys.h"
#include "state_tracker/drm_driver.h"
 
struct android_config;
 
struct android_display {
struct native_display base;
 
boolean use_drm;
const struct native_event_handler *event_handler;
struct android_config *configs;
int num_configs;
};
 
struct android_surface {
struct native_surface base;
 
struct android_display *adpy;
ANativeWindow *win;
 
/* staging color buffer for when buffer preserving is enabled */
struct pipe_resource *color_res;
 
uint stamp;
ANativeWindowBuffer *buf;
struct pipe_resource *buf_res;
 
/* cache the current back buffers */
struct {
int width;
int height;
int format;
} cache_key;
void *cache_handles[2];
struct pipe_resource *cache_resources[2];
};
 
struct android_config {
struct native_config base;
};
 
static INLINE struct android_display *
android_display(const struct native_display *ndpy)
{
return (struct android_display *) ndpy;
}
 
static INLINE struct android_surface *
android_surface(const struct native_surface *nsurf)
{
return (struct android_surface *) nsurf;
}
 
static INLINE struct android_config *
android_config(const struct native_config *nconf)
{
return (struct android_config *) nconf;
}
 
namespace android {
 
static enum pipe_format
get_pipe_format(int native)
{
enum pipe_format fmt;
 
switch (native) {
case HAL_PIXEL_FORMAT_RGBA_8888:
fmt = PIPE_FORMAT_R8G8B8A8_UNORM;
break;
case HAL_PIXEL_FORMAT_RGBX_8888:
fmt = PIPE_FORMAT_R8G8B8X8_UNORM;
break;
case HAL_PIXEL_FORMAT_RGB_888:
fmt = PIPE_FORMAT_R8G8B8_UNORM;
break;
case HAL_PIXEL_FORMAT_RGB_565:
fmt = PIPE_FORMAT_B5G6R5_UNORM;
break;
case HAL_PIXEL_FORMAT_BGRA_8888:
fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case HAL_PIXEL_FORMAT_RGBA_5551:
/* fmt = PIPE_FORMAT_A1B5G5R5_UNORM; */
case HAL_PIXEL_FORMAT_RGBA_4444:
/* fmt = PIPE_FORMAT_A4B4G4R4_UNORM; */
default:
ALOGE("unsupported native format 0x%x", native);
fmt = PIPE_FORMAT_NONE;
break;
}
 
return fmt;
}
 
#ifndef ANDROID_BACKEND_NO_DRM
 
extern "C" {
#include <gralloc_drm.h>
}
 
static int
get_handle_name(buffer_handle_t handle)
{
return gralloc_drm_get_gem_handle(handle);
}
#else
 
static int
get_handle_name(buffer_handle_t handle)
{
return 0;
}
 
#endif /* ANDROID_BACKEND_NO_DRM */
 
/**
* Import an ANativeWindowBuffer allocated by the server.
*/
static struct pipe_resource *
import_buffer(struct android_display *adpy, const struct pipe_resource *templ,
ANativeWindowBuffer *abuf)
{
struct pipe_screen *screen = adpy->base.screen;
struct pipe_resource *res;
 
if (templ->bind & PIPE_BIND_RENDER_TARGET) {
if (!screen->is_format_supported(screen, templ->format,
templ->target, 0, PIPE_BIND_RENDER_TARGET))
ALOGW("importing unsupported buffer as render target");
}
if (templ->bind & PIPE_BIND_SAMPLER_VIEW) {
if (!screen->is_format_supported(screen, templ->format,
templ->target, 0, PIPE_BIND_SAMPLER_VIEW))
ALOGW("importing unsupported buffer as sampler view");
}
 
if (adpy->use_drm) {
struct winsys_handle handle;
 
memset(&handle, 0, sizeof(handle));
handle.type = DRM_API_HANDLE_TYPE_SHARED;
/* for DRM, we need the GEM name */
handle.handle = get_handle_name(abuf->handle);
if (!handle.handle) {
ALOGE("unable to import invalid buffer %p", abuf);
return NULL;
}
 
handle.stride =
abuf->stride * util_format_get_blocksize(templ->format);
 
res = screen->resource_from_handle(screen, templ, &handle);
}
else {
struct android_winsys_handle handle;
 
memset(&handle, 0, sizeof(handle));
handle.handle = abuf->handle;
handle.stride =
abuf->stride * util_format_get_blocksize(templ->format);
 
res = screen->resource_from_handle(screen,
templ, (struct winsys_handle *) &handle);
}
 
if (!res)
ALOGE("failed to import buffer %p", abuf);
 
return res;
}
 
static void
android_surface_clear_cache(struct native_surface *nsurf)
{
struct android_surface *asurf = android_surface(nsurf);
int i;
 
for (i = 0; i < Elements(asurf->cache_handles); i++) {
asurf->cache_handles[i] = NULL;
pipe_resource_reference(&asurf->cache_resources[i], NULL);
}
 
memset(&asurf->cache_key, 0, sizeof(asurf->cache_key));
}
 
static struct pipe_resource *
android_surface_add_cache(struct native_surface *nsurf,
ANativeWindowBuffer *abuf)
{
struct android_surface *asurf = android_surface(nsurf);
void *handle;
int idx;
 
/* how about abuf->usage? */
if (asurf->cache_key.width != abuf->width ||
asurf->cache_key.height != abuf->height ||
asurf->cache_key.format != abuf->format)
android_surface_clear_cache(&asurf->base);
 
if (asurf->adpy->use_drm)
handle = (void *) get_handle_name(abuf->handle);
else
handle = (void *) abuf->handle;
/* NULL is invalid */
if (!handle) {
ALOGE("invalid buffer native buffer %p", abuf);
return NULL;
}
 
/* find the slot to use */
for (idx = 0; idx < Elements(asurf->cache_handles); idx++) {
if (asurf->cache_handles[idx] == handle || !asurf->cache_handles[idx])
break;
}
if (idx == Elements(asurf->cache_handles)) {
ALOGW("cache full: buf %p, width %d, height %d, format %d, usage 0x%x",
abuf, abuf->width, abuf->height, abuf->format, abuf->usage);
android_surface_clear_cache(&asurf->base);
idx = 0;
}
 
if (idx == 0) {
asurf->cache_key.width = abuf->width;
asurf->cache_key.height = abuf->height;
asurf->cache_key.format = abuf->format;
}
 
if (!asurf->cache_handles[idx]) {
struct pipe_resource templ;
 
assert(!asurf->cache_resources[idx]);
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = get_pipe_format(asurf->buf->format);
templ.bind = PIPE_BIND_RENDER_TARGET;
if (!asurf->adpy->use_drm) {
templ.bind |= PIPE_BIND_TRANSFER_WRITE |
PIPE_BIND_TRANSFER_READ;
}
 
templ.width0 = asurf->buf->width;
templ.height0 = asurf->buf->height;
templ.depth0 = 1;
templ.array_size = 1;
 
if (templ.format != PIPE_FORMAT_NONE) {
asurf->cache_resources[idx] =
import_buffer(asurf->adpy, &templ, asurf->buf);
}
else {
asurf->cache_resources[idx] = NULL;
}
 
asurf->cache_handles[idx] = handle;
}
 
return asurf->cache_resources[idx];
}
 
/**
* Dequeue the next back buffer for rendering.
*/
static boolean
android_surface_dequeue_buffer(struct native_surface *nsurf)
{
struct android_surface *asurf = android_surface(nsurf);
struct pipe_resource *res;
 
#if ANDROID_VERSION >= 0x0402
int fence_fd;
 
if (asurf->win->dequeueBuffer(asurf->win, &asurf->buf, &fence_fd) != NO_ERROR) {
ALOGE("failed to dequeue window %p", asurf->win);
return FALSE;
}
 
if (fence_fd >= 0) {
sync_wait(fence_fd, -1);
close(fence_fd);
}
 
asurf->buf->common.incRef(&asurf->buf->common);
#else
if (asurf->win->dequeueBuffer(asurf->win, &asurf->buf) != NO_ERROR) {
ALOGE("failed to dequeue window %p", asurf->win);
return FALSE;
}
 
asurf->buf->common.incRef(&asurf->buf->common);
asurf->win->lockBuffer(asurf->win, asurf->buf);
#endif
 
res = android_surface_add_cache(&asurf->base, asurf->buf);
if (!res)
return FALSE;
 
pipe_resource_reference(&asurf->buf_res, res);
 
return TRUE;
}
 
/**
* Enqueue the back buffer. This will make it the next front buffer.
*/
static boolean
android_surface_enqueue_buffer(struct native_surface *nsurf)
{
struct android_surface *asurf = android_surface(nsurf);
 
pipe_resource_reference(&asurf->buf_res, NULL);
 
#if ANDROID_VERSION >= 0x0402
asurf->win->queueBuffer(asurf->win, asurf->buf, -1);
#else
asurf->win->queueBuffer(asurf->win, asurf->buf);
#endif
 
asurf->buf->common.decRef(&asurf->buf->common);
asurf->buf = NULL;
 
return TRUE;
}
 
static boolean
android_surface_swap_buffers(struct native_surface *nsurf)
{
struct android_surface *asurf = android_surface(nsurf);
struct android_display *adpy = asurf->adpy;
 
android_surface_enqueue_buffer(&asurf->base);
 
asurf->stamp++;
adpy->event_handler->invalid_surface(&adpy->base,
&asurf->base, asurf->stamp);
 
return TRUE;
}
 
static void
copy_resources(struct native_display *ndpy,
struct pipe_resource *src,
struct pipe_resource *dst)
{
struct pipe_context *pipe;
struct pipe_box box;
 
pipe = ndpy_get_copy_context(ndpy);
if (!pipe)
return;
 
u_box_origin_2d(src->width0, src->height0, &box);
pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &box);
pipe->flush(pipe, NULL, 0);
}
 
static boolean
android_surface_present(struct native_surface *nsurf,
const native_present_control *ctrl)
{
struct android_surface *asurf = android_surface(nsurf);
struct android_display *adpy = asurf->adpy;
boolean ret;
 
if (ctrl->swap_interval || ctrl->natt != NATIVE_ATTACHMENT_BACK_LEFT)
return FALSE;
 
/* this happens when eglSwapBuffers is called more than once in a row */
if (!asurf->buf)
return TRUE;
 
/* we always render to color_res first when it exists */
if (asurf->color_res) {
copy_resources(&adpy->base, asurf->color_res, asurf->buf_res);
if (!ctrl->preserve)
pipe_resource_reference(&asurf->color_res, NULL);
}
else if (ctrl->preserve) {
struct pipe_resource templ;
 
memset(&templ, 0, sizeof(templ));
templ.target = asurf->buf_res->target;
templ.format = asurf->buf_res->format;
templ.bind = PIPE_BIND_RENDER_TARGET;
templ.width0 = asurf->buf_res->width0;
templ.height0 = asurf->buf_res->height0;
templ.depth0 = asurf->buf_res->depth0;
templ.array_size = asurf->buf_res->array_size;
 
asurf->color_res =
adpy->base.screen->resource_create(adpy->base.screen, &templ);
if (!asurf->color_res)
return FALSE;
 
/* preserve the contents */
copy_resources(&adpy->base, asurf->buf_res, asurf->color_res);
}
 
return android_surface_swap_buffers(nsurf);
}
 
static boolean
android_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct android_surface *asurf = android_surface(nsurf);
struct winsys_handle handle;
 
if (!asurf->buf) {
if (!android_surface_dequeue_buffer(&asurf->base))
return FALSE;
 
/* color_res must be compatible with buf_res */
if (asurf->color_res &&
(asurf->color_res->format != asurf->buf_res->format ||
asurf->color_res->width0 != asurf->buf_res->width0 ||
asurf->color_res->height0 != asurf->buf_res->height0))
pipe_resource_reference(&asurf->color_res, NULL);
}
 
if (textures) {
/* we have access to only the back buffer */
const enum native_attachment att = NATIVE_ATTACHMENT_BACK_LEFT;
 
if (native_attachment_mask_test(attachment_mask, att)) {
textures[att] = NULL;
pipe_resource_reference(&textures[att],
(asurf->color_res) ? asurf->color_res : asurf->buf_res);
}
}
 
if (seq_num)
*seq_num = asurf->stamp;
if (width)
*width = asurf->buf->width;
if (height)
*height = asurf->buf->height;
 
return TRUE;
}
 
static void
android_surface_wait(struct native_surface *nsurf)
{
}
 
static void
android_surface_destroy(struct native_surface *nsurf)
{
struct android_surface *asurf = android_surface(nsurf);
int i;
 
pipe_resource_reference(&asurf->color_res, NULL);
 
if (asurf->buf)
android_surface_enqueue_buffer(&asurf->base);
 
android_surface_clear_cache(&asurf->base);
 
asurf->win->common.decRef(&asurf->win->common);
 
FREE(asurf);
}
 
static struct native_surface *
android_display_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct android_display *adpy = android_display(ndpy);
struct android_config *aconf = android_config(nconf);
struct android_surface *asurf;
enum pipe_format format;
int val;
 
if (win->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
ALOGE("invalid native window with magic 0x%x", win->common.magic);
return NULL;
}
if (win->query(win, NATIVE_WINDOW_FORMAT, &val)) {
ALOGE("failed to query native window format");
return NULL;
}
format = get_pipe_format(val);
if (format != nconf->color_format) {
ALOGW("native window format 0x%x != config format 0x%x",
format, nconf->color_format);
if (!adpy->base.screen->is_format_supported(adpy->base.screen,
format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) {
ALOGE("and the native window cannot be used as a render target");
return NULL;
}
}
 
asurf = CALLOC_STRUCT(android_surface);
if (!asurf)
return NULL;
 
asurf->adpy = adpy;
asurf->win = win;
asurf->win->common.incRef(&asurf->win->common);
 
/* request buffers that are for CPU access */
if (!adpy->use_drm) {
native_window_set_usage(asurf->win,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
}
 
asurf->base.destroy = android_surface_destroy;
asurf->base.present = android_surface_present;
asurf->base.validate = android_surface_validate;
asurf->base.wait = android_surface_wait;
 
return &asurf->base;
}
 
static boolean
android_display_init_configs(struct native_display *ndpy)
{
struct android_display *adpy = android_display(ndpy);
const int native_formats[] = {
HAL_PIXEL_FORMAT_RGBA_8888,
HAL_PIXEL_FORMAT_RGBX_8888,
HAL_PIXEL_FORMAT_RGB_888,
HAL_PIXEL_FORMAT_RGB_565,
HAL_PIXEL_FORMAT_BGRA_8888,
};
int i;
 
adpy->configs = (struct android_config *)
CALLOC(Elements(native_formats), sizeof(*adpy->configs));
if (!adpy->configs)
return FALSE;
 
for (i = 0; i < Elements(native_formats); i++) {
enum pipe_format color_format;
struct android_config *aconf;
 
color_format = get_pipe_format(native_formats[i]);
if (color_format == PIPE_FORMAT_NONE ||
!adpy->base.screen->is_format_supported(adpy->base.screen,
color_format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) {
ALOGI("skip unsupported native format 0x%x", native_formats[i]);
continue;
}
 
aconf = &adpy->configs[adpy->num_configs++];
/* only the back buffer */
aconf->base.buffer_mask = 1 << NATIVE_ATTACHMENT_BACK_LEFT;
aconf->base.color_format = color_format;
aconf->base.window_bit = TRUE;
 
aconf->base.native_visual_id = native_formats[i];
aconf->base.native_visual_type = native_formats[i];
}
 
return TRUE;
}
 
static boolean
android_display_init_drm(struct native_display *ndpy)
{
struct android_display *adpy = android_display(ndpy);
const hw_module_t *mod;
int fd, err;
 
#ifndef ANDROID_BACKEND_NO_DRM
/* get the authorized fd from gralloc */
err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
if (!err) {
const gralloc_module_t *gr = (gralloc_module_t *) mod;
 
err = -EINVAL;
if (gr->perform)
err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd);
}
if (!err && fd >= 0) {
adpy->base.screen =
adpy->event_handler->new_drm_screen(&adpy->base, NULL, fd);
}
#endif
 
if (adpy->base.screen) {
ALOGI("using DRM screen");
return TRUE;
}
else {
ALOGW("failed to create DRM screen");
ALOGW("will fall back to other EGL drivers if any");
return FALSE;
}
}
 
static boolean
android_display_init_sw(struct native_display *ndpy)
{
struct android_display *adpy = android_display(ndpy);
struct sw_winsys *ws;
 
ws = android_create_sw_winsys();
if (ws) {
adpy->base.screen =
adpy->event_handler->new_sw_screen(&adpy->base, ws);
}
 
if (adpy->base.screen) {
ALOGI("using SW screen");
return TRUE;
}
else {
ALOGE("failed to create SW screen");
return FALSE;
}
}
 
static boolean
android_display_init_screen(struct native_display *ndpy)
{
struct android_display *adpy = android_display(ndpy);
 
if (adpy->use_drm)
android_display_init_drm(&adpy->base);
else
android_display_init_sw(&adpy->base);
 
if (!adpy->base.screen)
return FALSE;
 
if (!android_display_init_configs(&adpy->base)) {
adpy->base.screen->destroy(adpy->base.screen);
adpy->base.screen = NULL;
return FALSE;
}
 
return TRUE;
}
 
static void
android_display_destroy(struct native_display *ndpy)
{
struct android_display *adpy = android_display(ndpy);
 
FREE(adpy->configs);
if (adpy->base.screen)
adpy->base.screen->destroy(adpy->base.screen);
FREE(adpy);
}
 
static const struct native_config **
android_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct android_display *adpy = android_display(ndpy);
const struct native_config **configs;
int i;
 
configs = (const struct native_config **)
MALLOC(adpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < adpy->num_configs; i++)
configs[i] = (const struct native_config *) &adpy->configs[i];
if (num_configs)
*num_configs = adpy->num_configs;
}
 
return configs;
}
 
static int
android_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_PRESERVE_BUFFER:
val = 1;
break;
default:
val = 0;
break;
}
 
return val;
}
 
static struct pipe_resource *
android_display_import_buffer(struct native_display *ndpy,
struct native_buffer *nbuf)
{
struct android_display *adpy = android_display(ndpy);
ANativeWindowBuffer *abuf;
enum pipe_format format;
struct pipe_resource templ;
 
if (nbuf->type != NATIVE_BUFFER_ANDROID)
return NULL;
 
abuf = nbuf->u.android;
 
if (!abuf || abuf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
abuf->common.version != sizeof(*abuf)) {
ALOGE("invalid android native buffer");
return NULL;
}
 
format = get_pipe_format(abuf->format);
if (format == PIPE_FORMAT_NONE)
return NULL;
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = format;
/* assume for texturing only */
templ.bind = PIPE_BIND_SAMPLER_VIEW;
templ.width0 = abuf->width;
templ.height0 = abuf->height;
templ.depth0 = 1;
templ.array_size = 1;
 
return import_buffer(adpy, &templ, abuf);
}
 
static boolean
android_display_export_buffer(struct native_display *ndpy,
struct pipe_resource *res,
struct native_buffer *nbuf)
{
return FALSE;
}
 
static struct native_display_buffer android_display_buffer = {
android_display_import_buffer,
android_display_export_buffer
};
 
static struct android_display *
android_display_create(const struct native_event_handler *event_handler,
boolean use_sw)
{
struct android_display *adpy;
char value[PROPERTY_VALUE_MAX];
boolean force_sw;
 
/* check if SW renderer is forced */
if (property_get("debug.mesa.software", value, NULL))
force_sw = (atoi(value) != 0);
else
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
if (force_sw)
use_sw = TRUE;
 
adpy = CALLOC_STRUCT(android_display);
if (!adpy)
return NULL;
 
adpy->event_handler = event_handler;
adpy->use_drm = !use_sw;
 
adpy->base.init_screen = android_display_init_screen;
adpy->base.destroy = android_display_destroy;
adpy->base.get_param = android_display_get_param;
adpy->base.get_configs = android_display_get_configs;
adpy->base.create_window_surface = android_display_create_window_surface;
 
adpy->base.buffer = &android_display_buffer;
 
return adpy;
}
 
static const struct native_event_handler *android_event_handler;
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
struct android_display *adpy;
 
adpy = android_display_create(android_event_handler, use_sw);
 
return (adpy) ? &adpy->base : NULL;
}
 
static const struct native_platform android_platform = {
"Android", /* name */
native_create_display
};
 
}; /* namespace android */
 
using namespace android;
 
static void
android_log(EGLint level, const char *msg)
{
switch (level) {
case _EGL_DEBUG:
ALOGD("%s", msg);
break;
case _EGL_INFO:
ALOGI("%s", msg);
break;
case _EGL_WARNING:
ALOGW("%s", msg);
break;
case _EGL_FATAL:
LOG_FATAL("%s", msg);
break;
default:
break;
}
}
 
const struct native_platform *
native_get_android_platform(const struct native_event_handler *event_handler)
{
android_event_handler = event_handler;
/* use Android logger */
_eglSetLogProc(android_log);
 
return &android_platform;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d.c
0,0 → 1,670
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include "egldriver.h"
#include "eglcurrent.h"
#include "egllog.h"
 
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_format.h"
#include "util/u_string.h"
#include "util/u_atomic.h"
 
#include "egl_g3d.h"
#include "egl_g3d_api.h"
#include "egl_g3d_st.h"
#include "egl_g3d_loader.h"
#include "native.h"
 
static void
egl_g3d_invalid_surface(struct native_display *ndpy,
struct native_surface *nsurf,
unsigned int seq_num)
{
/* XXX not thread safe? */
struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
 
if (gsurf && gsurf->stfbi)
p_atomic_inc(&gsurf->stfbi->stamp);
}
 
static struct pipe_screen *
egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
{
_EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
return gdpy->loader->create_drm_screen(name, fd);
}
 
static struct pipe_screen *
egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
{
_EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
return gdpy->loader->create_sw_screen(ws);
}
 
static struct pipe_resource *
egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image)
{
_EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct st_egl_image img;
struct pipe_resource *resource = NULL;
 
memset(&img, 0, sizeof(img));
if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img))
resource = img.texture;
 
return resource;
}
 
static const struct native_event_handler egl_g3d_native_event_handler = {
egl_g3d_invalid_surface,
egl_g3d_new_drm_screen,
egl_g3d_new_sw_screen,
egl_g3d_lookup_egl_image
};
 
/**
* Get the native platform.
*/
static const struct native_platform *
egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
 
if (!gdrv->platforms[plat]) {
const char *plat_name = NULL;
const struct native_platform *nplat = NULL;
 
switch (plat) {
case _EGL_PLATFORM_WINDOWS:
plat_name = "Windows";
#ifdef HAVE_GDI_BACKEND
nplat = native_get_gdi_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_X11:
plat_name = "X11";
#ifdef HAVE_X11_BACKEND
nplat = native_get_x11_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_WAYLAND:
plat_name = "wayland";
#ifdef HAVE_WAYLAND_BACKEND
nplat = native_get_wayland_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_DRM:
plat_name = "DRM";
#ifdef HAVE_DRM_BACKEND
nplat = native_get_drm_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_FBDEV:
plat_name = "FBDEV";
#ifdef HAVE_FBDEV_BACKEND
nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_NULL:
plat_name = "NULL";
#ifdef HAVE_NULL_BACKEND
nplat = native_get_null_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_ANDROID:
plat_name = "Android";
#ifdef HAVE_ANDROID_BACKEND
nplat = native_get_android_platform(&egl_g3d_native_event_handler);
#endif
break;
default:
break;
}
 
if (!nplat)
_eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
 
gdrv->platforms[plat] = nplat;
}
 
return gdrv->platforms[plat];
}
 
#ifdef EGL_MESA_screen_surface
 
static void
egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
const struct native_connector **native_connectors;
EGLint num_connectors, i;
 
native_connectors =
gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
if (!num_connectors) {
FREE(native_connectors);
return;
}
 
for (i = 0; i < num_connectors; i++) {
const struct native_connector *nconn = native_connectors[i];
struct egl_g3d_screen *gscr;
const struct native_mode **native_modes;
EGLint num_modes, j;
 
/* TODO support for hotplug */
native_modes =
gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
if (!num_modes) {
FREE(native_modes);
continue;
}
 
gscr = CALLOC_STRUCT(egl_g3d_screen);
if (!gscr) {
FREE(native_modes);
continue;
}
 
_eglInitScreen(&gscr->base, dpy, num_modes);
for (j = 0; j < gscr->base.NumModes; j++) {
const struct native_mode *nmode = native_modes[j];
_EGLMode *mode = &gscr->base.Modes[j];
 
mode->Width = nmode->width;
mode->Height = nmode->height;
mode->RefreshRate = nmode->refresh_rate;
mode->Optimal = EGL_FALSE;
mode->Interlaced = EGL_FALSE;
/* no need to strdup() */
mode->Name = nmode->desc;
}
 
gscr->native = nconn;
gscr->native_modes = native_modes;
 
_eglLinkScreen(&gscr->base);
}
 
FREE(native_connectors);
}
 
#endif /* EGL_MESA_screen_surface */
 
/**
* Initialize and validate the EGL config attributes.
*/
static EGLBoolean
init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
EGLint api_mask, enum pipe_format depth_stencil_format,
EGLint preserve_buffer, EGLint max_swap_interval,
EGLBoolean pre_alpha)
{
uint rgba[4], depth_stencil[2], buffer_size;
EGLint surface_type;
EGLint i;
 
/* get the color and depth/stencil component sizes */
assert(nconf->color_format != PIPE_FORMAT_NONE);
buffer_size = 0;
for (i = 0; i < 4; i++) {
rgba[i] = util_format_get_component_bits(nconf->color_format,
UTIL_FORMAT_COLORSPACE_RGB, i);
buffer_size += rgba[i];
}
for (i = 0; i < 2; i++) {
if (depth_stencil_format != PIPE_FORMAT_NONE) {
depth_stencil[i] =
util_format_get_component_bits(depth_stencil_format,
UTIL_FORMAT_COLORSPACE_ZS, i);
}
else {
depth_stencil[i] = 0;
}
}
 
surface_type = 0x0;
/* pixmap surfaces should be EGL_SINGLE_BUFFER */
if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT)) {
if (nconf->pixmap_bit)
surface_type |= EGL_PIXMAP_BIT;
}
/* the others surfaces should be EGL_BACK_BUFFER (or settable) */
if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT)) {
if (nconf->window_bit)
surface_type |= EGL_WINDOW_BIT;
#ifdef EGL_MESA_screen_surface
if (nconf->scanout_bit)
surface_type |= EGL_SCREEN_BIT_MESA;
#endif
surface_type |= EGL_PBUFFER_BIT;
}
 
if (preserve_buffer)
surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
 
if (pre_alpha && rgba[3]) {
surface_type |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
/* st/vega does not support premultiplied alpha yet */
api_mask &= ~EGL_OPENVG_BIT;
}
 
conf->Conformant = api_mask;
conf->RenderableType = api_mask;
 
conf->RedSize = rgba[0];
conf->GreenSize = rgba[1];
conf->BlueSize = rgba[2];
conf->AlphaSize = rgba[3];
conf->BufferSize = buffer_size;
 
conf->DepthSize = depth_stencil[0];
conf->StencilSize = depth_stencil[1];
 
/* st/vega will allocate the mask on demand */
if (api_mask & EGL_OPENVG_BIT)
conf->AlphaMaskSize = 8;
 
conf->SurfaceType = surface_type;
 
conf->NativeRenderable = EGL_TRUE;
if (surface_type & EGL_WINDOW_BIT) {
conf->NativeVisualID = nconf->native_visual_id;
conf->NativeVisualType = nconf->native_visual_type;
}
 
if (surface_type & EGL_PBUFFER_BIT) {
conf->BindToTextureRGB = EGL_TRUE;
if (rgba[3])
conf->BindToTextureRGBA = EGL_TRUE;
 
conf->MaxPbufferWidth = 4096;
conf->MaxPbufferHeight = 4096;
conf->MaxPbufferPixels = 4096 * 4096;
}
 
conf->Level = nconf->level;
 
if (nconf->transparent_rgb) {
conf->TransparentType = EGL_TRANSPARENT_RGB;
conf->TransparentRedValue = nconf->transparent_rgb_values[0];
conf->TransparentGreenValue = nconf->transparent_rgb_values[1];
conf->TransparentBlueValue = nconf->transparent_rgb_values[2];
}
 
conf->MinSwapInterval = 0;
conf->MaxSwapInterval = max_swap_interval;
 
return _eglValidateConfig(conf, EGL_FALSE);
}
 
/**
* Initialize an EGL config from the native config.
*/
static EGLBoolean
egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, const struct native_config *nconf,
enum pipe_format depth_stencil_format,
int preserve_buffer, int max_swap_interval,
int pre_alpha)
{
struct egl_g3d_config *gconf = egl_g3d_config(conf);
EGLint buffer_mask;
EGLBoolean valid;
 
buffer_mask = 0x0;
if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT))
buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_RIGHT))
buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_RIGHT))
buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
 
gconf->stvis.buffer_mask = buffer_mask;
gconf->stvis.color_format = nconf->color_format;
gconf->stvis.depth_stencil_format = depth_stencil_format;
gconf->stvis.accum_format = PIPE_FORMAT_NONE;
gconf->stvis.samples = 0;
 
/* will be overridden per surface */
gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
 
valid = init_config_attributes(&gconf->base,
nconf, dpy->ClientAPIs, depth_stencil_format,
preserve_buffer, max_swap_interval, pre_alpha);
if (!valid) {
_eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
return EGL_FALSE;
}
 
gconf->native = nconf;
 
return EGL_TRUE;
}
 
/**
* Get all interested depth/stencil formats of a display.
*/
static EGLint
egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
enum pipe_format formats[8])
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct pipe_screen *screen = gdpy->native->screen;
const EGLint candidates[] = {
1, PIPE_FORMAT_Z16_UNORM,
1, PIPE_FORMAT_Z32_UNORM,
2, PIPE_FORMAT_Z24_UNORM_S8_UINT, PIPE_FORMAT_S8_UINT_Z24_UNORM,
2, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM,
0
};
const EGLint *fmt = candidates;
EGLint count;
 
count = 0;
formats[count++] = PIPE_FORMAT_NONE;
 
while (*fmt) {
EGLint i, n = *fmt++;
 
/* pick the first supported format */
for (i = 0; i < n; i++) {
if (screen->is_format_supported(screen, fmt[i],
PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) {
formats[count++] = fmt[i];
break;
}
}
 
fmt += n;
}
 
return count;
}
 
/**
* Add configs to display and return the next config ID.
*/
static EGLint
egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
const struct native_config **native_configs;
enum pipe_format depth_stencil_formats[8];
int num_formats, num_configs, i, j;
int preserve_buffer, max_swap_interval, premultiplied_alpha;
 
native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
if (!num_configs) {
FREE(native_configs);
return id;
}
 
preserve_buffer =
gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER);
max_swap_interval =
gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL);
premultiplied_alpha =
gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PREMULTIPLIED_ALPHA);
 
num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
depth_stencil_formats);
 
for (i = 0; i < num_configs; i++) {
for (j = 0; j < num_formats; j++) {
struct egl_g3d_config *gconf;
 
gconf = CALLOC_STRUCT(egl_g3d_config);
if (gconf) {
_eglInitConfig(&gconf->base, dpy, id);
if (!egl_g3d_init_config(drv, dpy, &gconf->base,
native_configs[i], depth_stencil_formats[j],
preserve_buffer, max_swap_interval,
premultiplied_alpha)) {
FREE(gconf);
break;
}
 
_eglLinkConfig(&gconf->base);
id++;
}
}
}
 
FREE(native_configs);
return id;
}
 
static void
egl_g3d_free_config(void *conf)
{
struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf);
FREE(gconf);
}
 
static void
egl_g3d_free_screen(void *scr)
{
#ifdef EGL_MESA_screen_surface
struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr);
FREE(gscr->native_modes);
FREE(gscr);
#endif
}
 
static EGLBoolean
egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
 
_eglReleaseDisplayResources(drv, dpy);
 
if (dpy->Configs) {
_eglDestroyArray(dpy->Configs, egl_g3d_free_config);
dpy->Configs = NULL;
}
if (dpy->Screens) {
_eglDestroyArray(dpy->Screens, egl_g3d_free_screen);
dpy->Screens = NULL;
}
 
_eglCleanupDisplay(dpy);
 
if (gdpy->smapi)
egl_g3d_destroy_st_manager(gdpy->smapi);
 
if (gdpy->native)
gdpy->native->destroy(gdpy->native);
 
FREE(gdpy);
dpy->DriverData = NULL;
 
return EGL_TRUE;
}
 
static EGLBoolean
egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_display *gdpy;
const struct native_platform *nplat;
 
nplat = egl_g3d_get_platform(drv, dpy->Platform);
if (!nplat)
return EGL_FALSE;
 
if (dpy->Options.TestOnly)
return EGL_TRUE;
 
gdpy = CALLOC_STRUCT(egl_g3d_display);
if (!gdpy) {
_eglError(EGL_BAD_ALLOC, "eglInitialize");
goto fail;
}
gdpy->loader = gdrv->loader;
dpy->DriverData = gdpy;
 
_eglLog(_EGL_INFO, "use %s for display %p",
nplat->name, dpy->PlatformDisplay);
gdpy->native =
nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
}
gdpy->native->user_data = (void *) dpy;
if (!gdpy->native->init_screen(gdpy->native)) {
_eglError(EGL_NOT_INITIALIZED,
"eglInitialize(failed to initialize screen)");
goto fail;
}
 
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
dpy->ClientAPIs |= EGL_OPENGL_BIT;
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK)
dpy->ClientAPIs |= EGL_OPENGL_ES_BIT;
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK)
dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT;
if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK)
dpy->ClientAPIs |= EGL_OPENVG_BIT;
 
gdpy->smapi = egl_g3d_create_st_manager(dpy);
if (!gdpy->smapi) {
_eglError(EGL_NOT_INITIALIZED,
"eglInitialize(failed to create st manager)");
goto fail;
}
 
#ifdef EGL_MESA_screen_surface
/* enable MESA_screen_surface before adding (and validating) configs */
if (gdpy->native->modeset) {
dpy->Extensions.MESA_screen_surface = EGL_TRUE;
egl_g3d_add_screens(drv, dpy);
}
#endif
 
dpy->Extensions.KHR_image_base = EGL_TRUE;
if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
 
dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
dpy->Extensions.KHR_fence_sync = EGL_TRUE;
 
dpy->Extensions.KHR_surfaceless_context = EGL_TRUE;
 
if (dpy->Platform == _EGL_PLATFORM_DRM) {
dpy->Extensions.MESA_drm_display = EGL_TRUE;
if (gdpy->native->buffer)
dpy->Extensions.MESA_drm_image = EGL_TRUE;
}
 
if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer)
dpy->Extensions.MESA_drm_image = EGL_TRUE;
 
#ifdef EGL_ANDROID_image_native_buffer
if (dpy->Platform == _EGL_PLATFORM_ANDROID && gdpy->native->buffer)
dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
#endif
 
#ifdef EGL_WL_bind_wayland_display
if (gdpy->native->wayland_bufmgr)
dpy->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif
 
if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESENT_REGION) &&
gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER)) {
#ifdef EGL_NOK_swap_region
dpy->Extensions.NOK_swap_region = EGL_TRUE;
#endif
dpy->Extensions.NV_post_sub_buffer = EGL_TRUE;
}
 
if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
goto fail;
}
 
dpy->VersionMajor = 1;
dpy->VersionMinor = 4;
 
return EGL_TRUE;
 
fail:
if (gdpy)
egl_g3d_terminate(drv, dpy);
return EGL_FALSE;
}
 
static _EGLProc
egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct st_api *stapi = NULL;
 
if (procname && procname[0] == 'v' && procname[1] == 'g')
stapi = gdrv->loader->get_st_api(ST_API_OPENVG);
else if (procname && procname[0] == 'g' && procname[1] == 'l')
stapi = gdrv->loader->get_st_api(ST_API_OPENGL);
 
return (_EGLProc) ((stapi) ?
stapi->get_proc_address(stapi, procname) : NULL);
}
 
_EGLDriver *
egl_g3d_create_driver(const struct egl_g3d_loader *loader)
{
struct egl_g3d_driver *gdrv;
 
gdrv = CALLOC_STRUCT(egl_g3d_driver);
if (!gdrv)
return NULL;
 
gdrv->loader = loader;
 
egl_g3d_init_driver_api(&gdrv->base);
gdrv->base.API.Initialize = egl_g3d_initialize;
gdrv->base.API.Terminate = egl_g3d_terminate;
gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
 
/* to be filled by the caller */
gdrv->base.Name = NULL;
gdrv->base.Unload = NULL;
 
return &gdrv->base;
}
 
void
egl_g3d_destroy_driver(_EGLDriver *drv)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
FREE(gdrv);
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d.h
0,0 → 1,132
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _EGL_G3D_H_
#define _EGL_G3D_H_
 
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_format.h"
#include "os/os_thread.h"
#include "egldriver.h"
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglsurface.h"
#include "eglconfig.h"
#include "eglimage.h"
#include "eglsync.h"
#include "eglscreen.h"
#include "eglmode.h"
 
#include "native.h"
#include "egl_g3d_st.h"
#include "egl_g3d_loader.h"
 
struct egl_g3d_driver {
_EGLDriver base;
const struct egl_g3d_loader *loader;
const struct native_platform *platforms[_EGL_NUM_PLATFORMS];
};
 
struct egl_g3d_display {
struct native_display *native;
 
const struct egl_g3d_loader *loader;
struct st_manager *smapi;
};
 
struct egl_g3d_context {
_EGLContext base;
 
struct st_api *stapi;
 
struct st_context_iface *stctxi;
};
 
struct egl_g3d_surface {
_EGLSurface base;
 
struct st_visual stvis;
struct st_framebuffer_iface *stfbi;
 
/* the native surface; NULL for pbuffers */
struct native_surface *native;
struct pipe_resource *render_texture;
 
EGLenum client_buffer_type;
EGLClientBuffer client_buffer;
 
unsigned int sequence_number;
};
 
struct egl_g3d_config {
_EGLConfig base;
const struct native_config *native;
struct st_visual stvis;
};
 
struct egl_g3d_image {
_EGLImage base;
struct pipe_resource *texture;
unsigned level;
unsigned layer;
};
 
/* standard typecasts */
_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d)
_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj)
 
struct egl_g3d_sync {
_EGLSync base;
 
/* the mutex protects only the condvar, not the struct */
pipe_mutex mutex;
pipe_condvar condvar;
 
/* for fence sync */
struct pipe_fence_handle *fence;
};
_EGL_DRIVER_TYPECAST(egl_g3d_sync, _EGLSync, obj)
 
#ifdef EGL_MESA_screen_surface
 
struct egl_g3d_screen {
_EGLScreen base;
const struct native_connector *native;
const struct native_mode **native_modes;
};
_EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj)
 
#endif /* EGL_MESA_screen_surface */
 
static INLINE struct st_api *
egl_g3d_get_st_api(_EGLDriver *drv, enum st_api_type api)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
 
return gdrv->loader->get_st_api(api);
}
 
#endif /* _EGL_G3D_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_api.c
0,0 → 1,940
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include "egldriver.h"
#include "eglcurrent.h"
#include "egllog.h"
 
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_box.h"
 
#include "egl_g3d.h"
#include "egl_g3d_api.h"
#include "egl_g3d_image.h"
#include "egl_g3d_sync.h"
#include "egl_g3d_st.h"
#include "native.h"
 
/**
* Return the state tracker for the given context.
*/
static struct st_api *
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
enum st_profile_type *profile)
{
struct st_api *stapi;
EGLint api = -1;
 
*profile = ST_PROFILE_DEFAULT;
 
switch (ctx->ClientAPI) {
case EGL_OPENGL_ES_API:
switch (ctx->ClientMajorVersion) {
case 1:
api = ST_API_OPENGL;
*profile = ST_PROFILE_OPENGL_ES1;
break;
case 2:
api = ST_API_OPENGL;
*profile = ST_PROFILE_OPENGL_ES2;
break;
default:
_eglLog(_EGL_WARNING, "unknown client major version %d",
ctx->ClientMajorVersion);
break;
}
break;
case EGL_OPENVG_API:
api = ST_API_OPENVG;
break;
case EGL_OPENGL_API:
api = ST_API_OPENGL;
break;
default:
_eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
break;
}
 
stapi = egl_g3d_get_st_api(drv, api);
if (stapi && !(stapi->profile_mask & (1 << *profile)))
stapi = NULL;
 
return stapi;
}
 
struct egl_g3d_choose_config_data {
_EGLConfig criteria;
enum pipe_format format;
};
 
static int
egl_g3d_compare_config(const _EGLConfig *conf1, const _EGLConfig *conf2,
void *priv_data)
{
struct egl_g3d_choose_config_data *data =
(struct egl_g3d_choose_config_data *) priv_data;
const _EGLConfig *criteria = &data->criteria;;
 
/* EGL_NATIVE_VISUAL_TYPE ignored? */
return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE);
}
 
static EGLBoolean
egl_g3d_match_config(const _EGLConfig *conf, void *priv_data)
{
struct egl_g3d_choose_config_data *data =
(struct egl_g3d_choose_config_data *) priv_data;
struct egl_g3d_config *gconf = egl_g3d_config(conf);
 
if (data->format != PIPE_FORMAT_NONE &&
data->format != gconf->native->color_format)
return EGL_FALSE;
 
return _eglMatchConfig(conf, &data->criteria);
}
 
static EGLBoolean
egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
EGLConfig *configs, EGLint size, EGLint *num_configs)
{
struct egl_g3d_choose_config_data data;
 
if (!_eglParseConfigAttribList(&data.criteria, dpy, attribs))
return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
 
data.format = PIPE_FORMAT_NONE;
if (data.criteria.MatchNativePixmap != EGL_NONE &&
data.criteria.MatchNativePixmap != EGL_DONT_CARE) {
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
 
if (!gdpy->native->get_pixmap_format(gdpy->native,
(EGLNativePixmapType) data.criteria.MatchNativePixmap,
&data.format))
return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglChooseConfig");
}
 
return _eglFilterConfigArray(dpy->Configs, configs, size, num_configs,
egl_g3d_match_config, egl_g3d_compare_config, &data);
}
 
static _EGLContext *
egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
_EGLContext *share, const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_context *gshare = egl_g3d_context(share);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_context *gctx;
struct st_context_attribs stattribs;
enum st_context_error ctx_err = 0;
 
gctx = CALLOC_STRUCT(egl_g3d_context);
if (!gctx) {
_eglError(EGL_BAD_ALLOC, "eglCreateContext");
return NULL;
}
 
if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) {
FREE(gctx);
return NULL;
}
 
memset(&stattribs, 0, sizeof(stattribs));
if (gconf)
stattribs.visual = gconf->stvis;
 
gctx->stapi = egl_g3d_choose_st(drv, &gctx->base, &stattribs.profile);
if (!gctx->stapi) {
FREE(gctx);
return NULL;
}
 
gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
&stattribs, &ctx_err, (gshare) ? gshare->stctxi : NULL);
if (!gctx->stctxi) {
FREE(gctx);
return NULL;
}
 
gctx->stctxi->st_manager_private = (void *) &gctx->base;
 
return &gctx->base;
}
 
/**
* Destroy a context.
*/
static void
destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
 
/* FIXME a context might live longer than its display */
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
 
gctx->stctxi->destroy(gctx->stctxi);
 
FREE(gctx);
}
 
static EGLBoolean
egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
if (_eglPutContext(ctx))
destroy_context(dpy, ctx);
return EGL_TRUE;
}
 
struct egl_g3d_create_surface_arg {
EGLint type;
union {
EGLNativeWindowType win;
EGLNativePixmapType pix;
} u;
};
 
static _EGLSurface *
egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
struct egl_g3d_create_surface_arg *arg,
const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_surface *gsurf;
struct native_surface *nsurf;
const char *err;
 
switch (arg->type) {
case EGL_WINDOW_BIT:
err = "eglCreateWindowSurface";
break;
case EGL_PIXMAP_BIT:
err = "eglCreatePixmapSurface";
break;
#ifdef EGL_MESA_screen_surface
case EGL_SCREEN_BIT_MESA:
err = "eglCreateScreenSurface";
break;
#endif
default:
err = "eglCreateUnknownSurface";
break;
}
 
gsurf = CALLOC_STRUCT(egl_g3d_surface);
if (!gsurf) {
_eglError(EGL_BAD_ALLOC, err);
return NULL;
}
 
if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) {
FREE(gsurf);
return NULL;
}
 
/* create the native surface */
switch (arg->type) {
case EGL_WINDOW_BIT:
nsurf = gdpy->native->create_window_surface(gdpy->native,
arg->u.win, gconf->native);
break;
case EGL_PIXMAP_BIT:
nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
arg->u.pix, gconf->native);
break;
#ifdef EGL_MESA_screen_surface
case EGL_SCREEN_BIT_MESA:
/* prefer back buffer (move to _eglInitSurface?) */
gsurf->base.RenderBuffer = EGL_BACK_BUFFER;
nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native,
gconf->native, gsurf->base.Width, gsurf->base.Height);
break;
#endif
default:
nsurf = NULL;
break;
}
 
if (!nsurf) {
FREE(gsurf);
return NULL;
}
/* initialize the geometry */
if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL,
&gsurf->base.Width, &gsurf->base.Height)) {
nsurf->destroy(nsurf);
FREE(gsurf);
return NULL;
}
 
gsurf->stvis = gconf->stvis;
if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER &&
gconf->stvis.buffer_mask & ST_ATTACHMENT_FRONT_LEFT_MASK)
gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT;
 
/* surfaces can always be posted when the display supports it */
if (dpy->Extensions.NV_post_sub_buffer)
gsurf->base.PostSubBufferSupportedNV = EGL_TRUE;
 
gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
if (!gsurf->stfbi) {
nsurf->destroy(nsurf);
FREE(gsurf);
return NULL;
}
 
nsurf->user_data = &gsurf->base;
gsurf->native = nsurf;
 
return &gsurf->base;
}
 
static _EGLSurface *
egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, EGLNativeWindowType win,
const EGLint *attribs)
{
struct egl_g3d_create_surface_arg arg;
 
memset(&arg, 0, sizeof(arg));
arg.type = EGL_WINDOW_BIT;
arg.u.win = win;
 
return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
 
static _EGLSurface *
egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, EGLNativePixmapType pix,
const EGLint *attribs)
{
struct egl_g3d_create_surface_arg arg;
 
memset(&arg, 0, sizeof(arg));
arg.type = EGL_PIXMAP_BIT;
arg.u.pix = pix;
 
return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
 
static struct egl_g3d_surface *
create_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attribs, const char *func)
{
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_surface *gsurf;
 
gsurf = CALLOC_STRUCT(egl_g3d_surface);
if (!gsurf) {
_eglError(EGL_BAD_ALLOC, func);
return NULL;
}
 
if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) {
FREE(gsurf);
return NULL;
}
 
gsurf->stvis = gconf->stvis;
 
gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
if (!gsurf->stfbi) {
FREE(gsurf);
return NULL;
}
 
return gsurf;
}
 
static _EGLSurface *
egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, const EGLint *attribs)
{
struct egl_g3d_surface *gsurf;
 
gsurf = create_pbuffer_surface(dpy, conf, attribs,
"eglCreatePbufferSurface");
if (!gsurf)
return NULL;
 
gsurf->client_buffer_type = EGL_NONE;
 
return &gsurf->base;
}
 
static _EGLSurface *
egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
EGLenum buftype,
EGLClientBuffer buffer,
_EGLConfig *conf,
const EGLint *attribs)
{
struct egl_g3d_surface *gsurf;
struct pipe_resource *ptex = NULL;
EGLint pbuffer_attribs[32];
EGLint count, i;
 
switch (buftype) {
case EGL_OPENVG_IMAGE:
break;
default:
_eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
return NULL;
break;
}
 
/* parse the attributes first */
count = 0;
for (i = 0; attribs && attribs[i] != EGL_NONE; i++) {
EGLint attr = attribs[i++];
EGLint val = attribs[i];
EGLint err = EGL_SUCCESS;
 
switch (attr) {
case EGL_TEXTURE_FORMAT:
case EGL_TEXTURE_TARGET:
case EGL_MIPMAP_TEXTURE:
pbuffer_attribs[count++] = attr;
pbuffer_attribs[count++] = val;
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
/* bail out */
if (err != EGL_SUCCESS) {
_eglError(err, "eglCreatePbufferFromClientBuffer");
return NULL;
}
}
 
pbuffer_attribs[count++] = EGL_NONE;
 
gsurf = create_pbuffer_surface(dpy, conf, pbuffer_attribs,
"eglCreatePbufferFromClientBuffer");
if (!gsurf)
return NULL;
 
gsurf->client_buffer_type = buftype;
gsurf->client_buffer = buffer;
 
/* validate now so that it fails if the client buffer is invalid */
if (!gsurf->stfbi->validate(NULL, gsurf->stfbi,
&gsurf->stvis.render_buffer, 1, &ptex)) {
egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
FREE(gsurf);
return NULL;
}
pipe_resource_reference(&ptex, NULL);
 
return &gsurf->base;
}
 
/**
* Destroy a surface.
*/
static void
destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
 
/* FIXME a surface might live longer than its display */
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
 
pipe_resource_reference(&gsurf->render_texture, NULL);
egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
if (gsurf->native)
gsurf->native->destroy(gsurf->native);
FREE(gsurf);
}
 
static EGLBoolean
egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
if (_eglPutSurface(surf))
destroy_surface(dpy, surf);
return EGL_TRUE;
}
 
static EGLBoolean
egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
struct egl_g3d_surface *gread = egl_g3d_surface(read);
struct egl_g3d_context *old_gctx;
_EGLContext *old_ctx;
_EGLSurface *old_draw, *old_read;
EGLBoolean ok = EGL_TRUE;
 
/* make new bindings */
if (!_eglBindContext(ctx, draw, read, &old_ctx, &old_draw, &old_read))
return EGL_FALSE;
 
old_gctx = egl_g3d_context(old_ctx);
if (old_gctx) {
/* flush old context */
old_gctx->stctxi->flush(old_gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
 
if (gctx) {
ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi,
(gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
if (ok) {
if (gdraw) {
if (gdraw->base.Type == EGL_WINDOW_BIT) {
gctx->base.WindowRenderBuffer =
(gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
}
}
}
}
else if (old_gctx) {
ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL);
if (ok)
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
 
if (ok) {
if (_eglPutContext(old_ctx))
destroy_context(dpy, old_ctx);
if (_eglPutSurface(old_draw))
destroy_surface(dpy, old_draw);
if (_eglPutSurface(old_read))
destroy_surface(dpy, old_read);
}
else {
/* undo the previous _eglBindContext */
_eglBindContext(old_ctx, old_draw, old_read, &ctx, &draw, &read);
assert(&gctx->base == ctx &&
&gdraw->base == draw &&
&gread->base == read);
 
_eglPutSurface(draw);
_eglPutSurface(read);
_eglPutContext(ctx);
 
_eglPutSurface(old_draw);
_eglPutSurface(old_read);
_eglPutContext(old_ctx);
}
 
return ok;
}
 
static EGLBoolean
swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLint num_rects, const EGLint *rects, EGLBoolean preserve)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
_EGLContext *ctx = _eglGetCurrentContext();
struct egl_g3d_context *gctx = NULL;
struct native_present_control ctrl;
 
/* no-op for pixmap or pbuffer surface */
if (gsurf->base.Type == EGL_PIXMAP_BIT ||
gsurf->base.Type == EGL_PBUFFER_BIT)
return EGL_TRUE;
 
/* or when the surface is single-buffered */
if (gsurf->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT)
return EGL_TRUE;
 
if (ctx && ctx->DrawSurface == surf)
gctx = egl_g3d_context(ctx);
 
/* flush if the surface is current */
if (gctx) {
gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
 
memset(&ctrl, 0, sizeof(ctrl));
ctrl.natt = NATIVE_ATTACHMENT_BACK_LEFT;
ctrl.preserve = preserve;
ctrl.swap_interval = gsurf->base.SwapInterval;
ctrl.premultiplied_alpha = (gsurf->base.VGAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE);
ctrl.num_rects = num_rects;
ctrl.rects = rects;
 
return gsurf->native->present(gsurf->native, &ctrl);
}
 
static EGLBoolean
egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
 
return swap_buffers(drv, dpy, surf, 0, NULL,
(gsurf->base.SwapBehavior == EGL_BUFFER_PRESERVED));
}
 
#ifdef EGL_NOK_swap_region
static EGLBoolean
egl_g3d_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLint num_rects, const EGLint *rects)
{
/* Note: y=0=top */
return swap_buffers(drv, dpy, surf, num_rects, rects, EGL_TRUE);
}
#endif /* EGL_NOK_swap_region */
 
static EGLBoolean
egl_g3d_post_sub_buffer(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLint x, EGLint y, EGLint width, EGLint height)
{
EGLint rect[4];
 
if (x < 0 || y < 0 || width < 0 || height < 0)
return _eglError(EGL_BAD_PARAMETER, "eglPostSubBufferNV");
 
/* clamp */
if (x + width > surf->Width)
width = surf->Width - x;
if (y + height > surf->Height)
height = surf->Height - y;
 
if (width <= 0 || height <= 0)
return EGL_TRUE;
 
rect[0] = x;
/* Note: y=0=bottom */
rect[1] = surf->Height - y - height;
rect[2] = width;
rect[3] = height;
 
return swap_buffers(drv, dpy, surf, 1, rect, EGL_TRUE);
}
 
static EGLBoolean
egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLNativePixmapType target)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
_EGLContext *ctx = _eglGetCurrentContext();
 
if (!gsurf->render_texture)
return EGL_TRUE;
 
/* flush if the surface is current */
if (ctx && ctx->DrawSurface == &gsurf->base) {
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
 
return gdpy->native->copy_to_pixmap(gdpy->native,
target, gsurf->render_texture);
}
 
static EGLBoolean
egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_fence_handle *fence = NULL;
 
gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, &fence);
if (fence) {
screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
}
 
return EGL_TRUE;
}
 
static EGLBoolean
egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
{
_EGLContext *ctx = _eglGetCurrentContext();
 
if (engine != EGL_CORE_NATIVE_ENGINE)
return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
 
if (ctx && ctx->DrawSurface) {
struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
 
if (gsurf->native)
gsurf->native->wait(gsurf->native);
}
 
return EGL_TRUE;
}
 
static EGLBoolean
egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLSurface *surf, EGLint buffer)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
_EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx;
enum pipe_format internal_format;
enum st_texture_type target;
 
if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
if (gsurf->base.BoundToTexture)
return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
 
switch (gsurf->base.TextureFormat) {
case EGL_TEXTURE_RGB:
internal_format = PIPE_FORMAT_R8G8B8_UNORM;
break;
case EGL_TEXTURE_RGBA:
internal_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
}
 
switch (gsurf->base.TextureTarget) {
case EGL_TEXTURE_2D:
target = ST_TEXTURE_2D;
break;
default:
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
}
 
if (!es1)
return EGL_TRUE;
if (!gsurf->render_texture)
return EGL_FALSE;
 
/* flush properly if the surface is bound */
if (gsurf->base.CurrentContext) {
gctx = egl_g3d_context(gsurf->base.CurrentContext);
gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
 
gctx = egl_g3d_context(es1);
if (gctx->stctxi->teximage) {
if (!gctx->stctxi->teximage(gctx->stctxi, target,
gsurf->base.MipmapLevel, internal_format,
gsurf->render_texture, gsurf->base.MipmapTexture))
return EGL_FALSE;
gsurf->base.BoundToTexture = EGL_TRUE;
}
 
return EGL_TRUE;
}
 
static EGLBoolean
egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLSurface *surf, EGLint buffer)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
 
if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT ||
!gsurf->base.BoundToTexture)
return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
 
if (gsurf->render_texture) {
_EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
 
/* what if the context the surface binds to is no longer current? */
if (gctx) {
gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D,
gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE);
}
}
 
gsurf->base.BoundToTexture = EGL_FALSE;
 
return EGL_TRUE;
}
 
#ifdef EGL_MESA_screen_surface
 
static _EGLSurface *
egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, const EGLint *attribs)
{
struct egl_g3d_create_surface_arg arg;
 
memset(&arg, 0, sizeof(arg));
arg.type = EGL_SCREEN_BIT_MESA;
 
return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
 
static EGLBoolean
egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLScreen *scr, _EGLSurface *surf,
_EGLMode *mode)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_screen *gscr = egl_g3d_screen(scr);
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
struct native_surface *nsurf;
const struct native_mode *nmode;
EGLBoolean changed;
 
if (gsurf) {
EGLint idx;
 
if (!mode)
return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
if (gsurf->base.Type != EGL_SCREEN_BIT_MESA)
return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA");
if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height)
return _eglError(EGL_BAD_MATCH,
"eglShowSurfaceMESA(surface smaller than mode size)");
 
/* find the index of the mode */
for (idx = 0; idx < gscr->base.NumModes; idx++)
if (mode == &gscr->base.Modes[idx])
break;
if (idx >= gscr->base.NumModes) {
return _eglError(EGL_BAD_MODE_MESA,
"eglShowSurfaceMESA(unknown mode)");
}
 
nsurf = gsurf->native;
nmode = gscr->native_modes[idx];
}
else {
if (mode)
return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
 
/* disable the screen */
nsurf = NULL;
nmode = NULL;
}
 
/* TODO surface panning by CRTC choosing */
changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf,
gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode);
if (changed) {
gscr->base.CurrentSurface = &gsurf->base;
gscr->base.CurrentMode = mode;
}
 
return changed;
}
 
#endif /* EGL_MESA_screen_surface */
 
#ifdef EGL_WL_bind_wayland_display
 
static EGLBoolean
egl_g3d_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *dpy,
struct wl_display *wl_dpy)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
 
if (!gdpy->native->wayland_bufmgr)
return EGL_FALSE;
 
return gdpy->native->wayland_bufmgr->bind_display(gdpy->native, wl_dpy);
}
 
static EGLBoolean
egl_g3d_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *dpy,
struct wl_display *wl_dpy)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
 
if (!gdpy->native->wayland_bufmgr)
return EGL_FALSE;
 
return gdpy->native->wayland_bufmgr->unbind_display(gdpy->native, wl_dpy);
}
 
static EGLBoolean
egl_g3d_query_wayland_buffer_wl(_EGLDriver *drv, _EGLDisplay *dpy,
struct wl_buffer *buffer,
EGLint attribute, EGLint *value)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
 
if (!gdpy->native->wayland_bufmgr)
return EGL_FALSE;
 
return gdpy->native->wayland_bufmgr->query_buffer(gdpy->native,
buffer, attribute, value);
}
#endif /* EGL_WL_bind_wayland_display */
 
void
egl_g3d_init_driver_api(_EGLDriver *drv)
{
_eglInitDriverFallbacks(drv);
 
drv->API.ChooseConfig = egl_g3d_choose_config;
 
drv->API.CreateContext = egl_g3d_create_context;
drv->API.DestroyContext = egl_g3d_destroy_context;
drv->API.CreateWindowSurface = egl_g3d_create_window_surface;
drv->API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
drv->API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
drv->API.CreatePbufferFromClientBuffer = egl_g3d_create_pbuffer_from_client_buffer;
drv->API.DestroySurface = egl_g3d_destroy_surface;
drv->API.MakeCurrent = egl_g3d_make_current;
drv->API.SwapBuffers = egl_g3d_swap_buffers;
drv->API.CopyBuffers = egl_g3d_copy_buffers;
drv->API.WaitClient = egl_g3d_wait_client;
drv->API.WaitNative = egl_g3d_wait_native;
 
drv->API.BindTexImage = egl_g3d_bind_tex_image;
drv->API.ReleaseTexImage = egl_g3d_release_tex_image;
 
drv->API.CreateImageKHR = egl_g3d_create_image;
drv->API.DestroyImageKHR = egl_g3d_destroy_image;
#ifdef EGL_MESA_drm_image
drv->API.CreateDRMImageMESA = egl_g3d_create_drm_image;
drv->API.ExportDRMImageMESA = egl_g3d_export_drm_image;
#endif
#ifdef EGL_WL_bind_wayland_display
drv->API.BindWaylandDisplayWL = egl_g3d_bind_wayland_display_wl;
drv->API.UnbindWaylandDisplayWL = egl_g3d_unbind_wayland_display_wl;
drv->API.QueryWaylandBufferWL = egl_g3d_query_wayland_buffer_wl;
#endif
 
drv->API.CreateSyncKHR = egl_g3d_create_sync;
drv->API.DestroySyncKHR = egl_g3d_destroy_sync;
drv->API.ClientWaitSyncKHR = egl_g3d_client_wait_sync;
drv->API.SignalSyncKHR = egl_g3d_signal_sync;
 
#ifdef EGL_MESA_screen_surface
drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
drv->API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
#endif
 
#ifdef EGL_NOK_swap_region
drv->API.SwapBuffersRegionNOK = egl_g3d_swap_buffers_region;
#endif
 
drv->API.PostSubBufferNV = egl_g3d_post_sub_buffer;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_api.h
0,0 → 1,33
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _EGL_G3D_API_H_
#define _EGL_G3D_API_H_
 
#include "egl_g3d.h"
 
void
egl_g3d_init_driver_api(_EGLDriver *drv);
 
#endif /* _EGL_G3D_API_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_image.c
0,0 → 1,371
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
#include "util/u_inlines.h"
#include "eglcurrent.h"
#include "egllog.h"
 
#include "native.h"
#include "egl_g3d.h"
#include "egl_g3d_image.h"
 
/**
* Reference and return the front left buffer of the native pixmap.
*/
static struct pipe_resource *
egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct native_surface *nsurf;
struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
enum native_attachment natt;
 
nsurf = gdpy->native->create_pixmap_surface(gdpy->native, pix, NULL);
if (!nsurf)
return NULL;
 
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
if (!nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL))
textures[natt] = NULL;
 
nsurf->destroy(nsurf);
 
return textures[natt];
}
 
#ifdef EGL_MESA_drm_image
 
static struct pipe_resource *
egl_g3d_create_drm_buffer(_EGLDisplay *dpy, _EGLImage *img,
const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_resource templ;
_EGLImageAttribs attrs;
EGLint format, valid_use;
 
if (_eglParseImageAttribList(&attrs, dpy, attribs) != EGL_SUCCESS)
return NULL;
 
if (attrs.Width <= 0 || attrs.Height <= 0) {
_eglLog(_EGL_DEBUG, "bad width or height (%dx%d)",
attrs.Width, attrs.Height);
return NULL;
}
 
switch (attrs.DRMBufferFormatMESA) {
case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
_eglLog(_EGL_DEBUG, "bad image format value 0x%04x",
attrs.DRMBufferFormatMESA);
return NULL;
break;
}
 
valid_use = EGL_DRM_BUFFER_USE_SCANOUT_MESA |
EGL_DRM_BUFFER_USE_SHARE_MESA |
EGL_DRM_BUFFER_USE_CURSOR_MESA;
if (attrs.DRMBufferUseMESA & ~valid_use) {
_eglLog(_EGL_DEBUG, "bad image use bit 0x%04x",
attrs.DRMBufferUseMESA);
return NULL;
}
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = format;
templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
templ.width0 = attrs.Width;
templ.height0 = attrs.Height;
templ.depth0 = 1;
templ.array_size = 1;
 
/*
* XXX fix apps (e.g. wayland) and pipe drivers (e.g. i915) and remove the
* size check
*/
if ((attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SCANOUT_MESA) &&
attrs.Width >= 640 && attrs.Height >= 480)
templ.bind |= PIPE_BIND_SCANOUT;
if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA)
templ.bind |= PIPE_BIND_SHARED;
if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_CURSOR_MESA) {
if (attrs.Width != 64 || attrs.Height != 64)
return NULL;
templ.bind |= PIPE_BIND_CURSOR;
}
 
return screen->resource_create(screen, &templ);
}
 
static struct pipe_resource *
egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
_EGLImage *img, const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
_EGLImageAttribs attrs;
EGLint format;
struct native_buffer nbuf;
 
if (!dpy->Extensions.MESA_drm_image)
return NULL;
 
if (_eglParseImageAttribList(&attrs, dpy, attribs) != EGL_SUCCESS)
return NULL;
 
if (attrs.Width <= 0 || attrs.Height <= 0 ||
attrs.DRMBufferStrideMESA <= 0) {
_eglLog(_EGL_DEBUG, "bad width, height, or stride (%dx%dx%d)",
attrs.Width, attrs.Height, attrs.DRMBufferStrideMESA);
return NULL;
}
 
switch (attrs.DRMBufferFormatMESA) {
case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
_eglLog(_EGL_DEBUG, "bad image format value 0x%04x",
attrs.DRMBufferFormatMESA);
return NULL;
break;
}
 
memset(&nbuf, 0, sizeof(nbuf));
nbuf.type = NATIVE_BUFFER_DRM;
nbuf.u.drm.templ.target = PIPE_TEXTURE_2D;
nbuf.u.drm.templ.format = format;
nbuf.u.drm.templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
nbuf.u.drm.templ.width0 = attrs.Width;
nbuf.u.drm.templ.height0 = attrs.Height;
nbuf.u.drm.templ.depth0 = 1;
nbuf.u.drm.templ.array_size = 1;
 
nbuf.u.drm.name = name;
nbuf.u.drm.stride =
attrs.DRMBufferStrideMESA * util_format_get_blocksize(format);
 
return gdpy->native->buffer->import_buffer(gdpy->native, &nbuf);
}
 
#endif /* EGL_MESA_drm_image */
 
#ifdef EGL_WL_bind_wayland_display
 
static struct pipe_resource *
egl_g3d_reference_wl_buffer(_EGLDisplay *dpy, struct wl_buffer *buffer,
_EGLImage *img, const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct pipe_resource *resource = NULL, *tmp = NULL;
 
if (!gdpy->native->wayland_bufmgr)
return NULL;
 
tmp = gdpy->native->wayland_bufmgr->buffer_get_resource(gdpy->native, buffer);
 
pipe_resource_reference(&resource, tmp);
 
return resource;
}
 
#endif /* EGL_WL_bind_wayland_display */
 
#ifdef EGL_ANDROID_image_native_buffer
 
static struct pipe_resource *
egl_g3d_reference_android_native_buffer(_EGLDisplay *dpy,
struct ANativeWindowBuffer *buf)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct native_buffer nbuf;
 
memset(&nbuf, 0, sizeof(nbuf));
nbuf.type = NATIVE_BUFFER_ANDROID;
nbuf.u.android = buf;
return gdpy->native->buffer->import_buffer(gdpy->native, &nbuf);
}
 
#endif /* EGL_ANDROID_image_native_buffer */
 
_EGLImage *
egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer,
const EGLint *attribs)
{
struct pipe_resource *ptex;
struct egl_g3d_image *gimg;
unsigned level = 0, layer = 0;
 
gimg = CALLOC_STRUCT(egl_g3d_image);
if (!gimg) {
_eglError(EGL_BAD_ALLOC, "eglCreateEGLImageKHR");
return NULL;
}
 
if (!_eglInitImage(&gimg->base, dpy)) {
FREE(gimg);
return NULL;
}
 
switch (target) {
case EGL_NATIVE_PIXMAP_KHR:
ptex = egl_g3d_reference_native_pixmap(dpy,
(EGLNativePixmapType) buffer);
break;
#ifdef EGL_MESA_drm_image
case EGL_DRM_BUFFER_MESA:
ptex = egl_g3d_reference_drm_buffer(dpy,
(EGLint) pointer_to_intptr(buffer), &gimg->base, attribs);
break;
#endif
#ifdef EGL_WL_bind_wayland_display
case EGL_WAYLAND_BUFFER_WL:
ptex = egl_g3d_reference_wl_buffer(dpy,
(struct wl_buffer *) buffer, &gimg->base, attribs);
break;
#endif
#ifdef EGL_ANDROID_image_native_buffer
case EGL_NATIVE_BUFFER_ANDROID:
ptex = egl_g3d_reference_android_native_buffer(dpy,
(struct ANativeWindowBuffer *) buffer);
break;
#endif
default:
ptex = NULL;
break;
}
 
if (!ptex) {
FREE(gimg);
return NULL;
}
 
if (level > ptex->last_level) {
_eglError(EGL_BAD_MATCH, "eglCreateEGLImageKHR");
pipe_resource_reference(&gimg->texture, NULL);
FREE(gimg);
return NULL;
}
if (layer >= (u_minify(ptex->depth0, level) + ptex->array_size - 1)) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
pipe_resource_reference(&gimg->texture, NULL);
FREE(gimg);
return NULL;
}
 
/* transfer the ownership to the image */
gimg->texture = ptex;
gimg->level = level;
gimg->layer = layer;
 
return &gimg->base;
}
 
EGLBoolean
egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
{
struct egl_g3d_image *gimg = egl_g3d_image(img);
 
pipe_resource_reference(&gimg->texture, NULL);
FREE(gimg);
 
return EGL_TRUE;
}
 
_EGLImage *
egl_g3d_create_drm_image(_EGLDriver *drv, _EGLDisplay *dpy,
const EGLint *attribs)
{
struct egl_g3d_image *gimg;
struct pipe_resource *ptex;
 
gimg = CALLOC_STRUCT(egl_g3d_image);
if (!gimg) {
_eglError(EGL_BAD_ALLOC, "eglCreateDRMImageKHR");
return NULL;
}
 
if (!_eglInitImage(&gimg->base, dpy)) {
FREE(gimg);
return NULL;
}
 
#ifdef EGL_MESA_drm_image
ptex = egl_g3d_create_drm_buffer(dpy, &gimg->base, attribs);
#else
ptex = NULL;
#endif
if (!ptex) {
FREE(gimg);
return NULL;
}
 
/* transfer the ownership to the image */
gimg->texture = ptex;
gimg->level = 0;
gimg->layer = 0;
 
return &gimg->base;
}
 
EGLBoolean
egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img,
EGLint *name, EGLint *handle, EGLint *stride)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_image *gimg = egl_g3d_image(img);
struct native_buffer nbuf;
 
if (!dpy->Extensions.MESA_drm_image)
return EGL_FALSE;
 
memset(&nbuf, 0, sizeof(nbuf));
nbuf.type = NATIVE_BUFFER_DRM;
if (name)
nbuf.u.drm.templ.bind |= PIPE_BIND_SHARED;
 
if (!gdpy->native->buffer->export_buffer(gdpy->native,
gimg->texture, &nbuf))
return EGL_FALSE;
 
if (name)
*name = nbuf.u.drm.name;
if (handle)
*handle = nbuf.u.drm.handle;
if (stride)
*stride = nbuf.u.drm.stride;
 
return EGL_TRUE;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_image.h
0,0 → 1,49
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#ifndef _EGL_G3D_IMAGE_H_
#define _EGL_G3D_IMAGE_H_
 
#include "egl_g3d.h"
 
_EGLImage *
egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer,
const EGLint *attribs);
 
EGLBoolean
egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
 
_EGLImage *
egl_g3d_create_drm_image(_EGLDriver *drv, _EGLDisplay *dpy,
const EGLint *attribs);
 
EGLBoolean
egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img,
EGLint *name, EGLint *handle, EGLint *stride);
 
#endif /* _EGL_G3D_IMAGE_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
0,0 → 1,52
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#ifndef _EGL_G3D_LOADER_H_
#define _EGL_G3D_LOADER_H_
 
#include "pipe/p_compiler.h"
#include "state_tracker/st_api.h"
#include "egltypedefs.h"
 
struct pipe_screen;
struct sw_winsys;
 
struct egl_g3d_loader {
uint profile_masks[ST_API_COUNT];
struct st_api *(*get_st_api)(enum st_api_type api);
 
struct pipe_screen *(*create_drm_screen)(const char *name, int fd);
struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws);
};
 
_EGLDriver *
egl_g3d_create_driver(const struct egl_g3d_loader *loader);
 
void
egl_g3d_destroy_driver(_EGLDriver *drv);
 
#endif /* _EGL_G3D_LOADER_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_st.c
0,0 → 1,321
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#include "util/u_memory.h"
#include "util/u_string.h"
#include "util/u_inlines.h"
#include "util/u_pointer.h"
#include "util/u_dl.h"
#include "egldriver.h"
#include "eglimage.h"
#include "eglmutex.h"
 
#include "egl_g3d.h"
#include "egl_g3d_st.h"
 
struct egl_g3d_st_manager {
struct st_manager base;
_EGLDisplay *display;
};
 
static INLINE struct egl_g3d_st_manager *
egl_g3d_st_manager(struct st_manager *smapi)
{
return (struct egl_g3d_st_manager *) smapi;
}
 
static boolean
egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
void *egl_image,
struct st_egl_image *out)
{
struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
EGLImageKHR handle = (EGLImageKHR) egl_image;
_EGLImage *img;
struct egl_g3d_image *gimg;
 
/* this is called from state trackers */
_eglLockMutex(&gsmapi->display->Mutex);
 
img = _eglLookupImage(handle, gsmapi->display);
if (!img) {
_eglUnlockMutex(&gsmapi->display->Mutex);
return FALSE;
}
 
gimg = egl_g3d_image(img);
 
out->texture = NULL;
pipe_resource_reference(&out->texture, gimg->texture);
out->level = gimg->level;
out->layer = gimg->layer;
 
_eglUnlockMutex(&gsmapi->display->Mutex);
 
return TRUE;
}
 
static int
egl_g3d_st_manager_get_param(struct st_manager *smapi,
enum st_manager_param param)
{
return 0;
}
 
struct st_manager *
egl_g3d_create_st_manager(_EGLDisplay *dpy)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_st_manager *gsmapi;
 
gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
if (gsmapi) {
gsmapi->display = dpy;
 
gsmapi->base.screen = gdpy->native->screen;
gsmapi->base.get_egl_image = egl_g3d_st_manager_get_egl_image;
gsmapi->base.get_param = egl_g3d_st_manager_get_param;
}
 
return &gsmapi->base;;
}
 
void
egl_g3d_destroy_st_manager(struct st_manager *smapi)
{
struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
FREE(gsmapi);
}
 
static boolean
egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_context_iface *stctx,
struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
{
return TRUE;
}
 
static void
pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf)
{
/* TODO */
}
 
static void
pbuffer_allocate_pbuffer_texture(struct egl_g3d_surface *gsurf)
{
struct egl_g3d_display *gdpy =
egl_g3d_display(gsurf->base.Resource.Display);
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_resource templ, *ptex;
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
templ.width0 = gsurf->base.Width;
templ.height0 = gsurf->base.Height;
templ.depth0 = 1;
templ.array_size = 1;
templ.format = gsurf->stvis.color_format;
/* for rendering and binding to texture */
templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
 
ptex = screen->resource_create(screen, &templ);
gsurf->render_texture = ptex;
}
 
static boolean
egl_g3d_st_framebuffer_validate_pbuffer(struct st_context_iface *stctx,
struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_resource **out)
{
_EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
unsigned i;
 
for (i = 0; i < count; i++) {
out[i] = NULL;
 
if (gsurf->stvis.render_buffer != statts[i])
continue;
 
if (!gsurf->render_texture) {
switch (gsurf->client_buffer_type) {
case EGL_NONE:
pbuffer_allocate_pbuffer_texture(gsurf);
break;
case EGL_OPENVG_IMAGE:
pbuffer_reference_openvg_image(gsurf);
break;
default:
break;
}
 
if (!gsurf->render_texture)
return FALSE;
}
 
pipe_resource_reference(&out[i], gsurf->render_texture);
}
 
return TRUE;
}
 
static boolean
egl_g3d_st_framebuffer_flush_front(struct st_context_iface *stctx,
struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
{
_EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
struct native_present_control ctrl;
 
memset(&ctrl, 0, sizeof(ctrl));
ctrl.natt = NATIVE_ATTACHMENT_FRONT_LEFT;
 
return gsurf->native->present(gsurf->native, &ctrl);
}
 
static boolean
egl_g3d_st_framebuffer_validate(struct st_context_iface *stctx,
struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_resource **out)
{
_EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
uint attachment_mask = 0;
unsigned i;
 
for (i = 0; i < count; i++) {
int natt;
 
switch (statts[i]) {
case ST_ATTACHMENT_FRONT_LEFT:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
break;
case ST_ATTACHMENT_BACK_LEFT:
natt = NATIVE_ATTACHMENT_BACK_LEFT;
break;
case ST_ATTACHMENT_FRONT_RIGHT:
natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
break;
case ST_ATTACHMENT_BACK_RIGHT:
natt = NATIVE_ATTACHMENT_BACK_RIGHT;
break;
default:
natt = -1;
break;
}
 
if (natt >= 0)
attachment_mask |= 1 << natt;
}
 
if (!gsurf->native->validate(gsurf->native, attachment_mask,
&gsurf->sequence_number, textures, &gsurf->base.Width,
&gsurf->base.Height))
return FALSE;
 
for (i = 0; i < count; i++) {
struct pipe_resource *tex;
int natt;
 
switch (statts[i]) {
case ST_ATTACHMENT_FRONT_LEFT:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
break;
case ST_ATTACHMENT_BACK_LEFT:
natt = NATIVE_ATTACHMENT_BACK_LEFT;
break;
case ST_ATTACHMENT_FRONT_RIGHT:
natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
break;
case ST_ATTACHMENT_BACK_RIGHT:
natt = NATIVE_ATTACHMENT_BACK_RIGHT;
break;
default:
natt = -1;
break;
}
 
if (natt >= 0) {
tex = textures[natt];
 
if (statts[i] == stfbi->visual->render_buffer)
pipe_resource_reference(&gsurf->render_texture, tex);
 
if (attachment_mask & (1 << natt)) {
/* transfer the ownership to the caller */
out[i] = tex;
attachment_mask &= ~(1 << natt);
}
else {
/* the attachment is listed more than once */
pipe_resource_reference(&out[i], tex);
}
}
}
 
return TRUE;
}
 
struct st_framebuffer_iface *
egl_g3d_create_st_framebuffer(_EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
struct st_framebuffer_iface *stfbi;
 
stfbi = CALLOC_STRUCT(st_framebuffer_iface);
if (!stfbi)
return NULL;
 
stfbi->visual = &gsurf->stvis;
p_atomic_set(&stfbi->stamp, 1);
 
if (gsurf->base.Type != EGL_PBUFFER_BIT) {
stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
stfbi->validate = egl_g3d_st_framebuffer_validate;
}
else {
stfbi->flush_front = egl_g3d_st_framebuffer_flush_front_pbuffer;
stfbi->validate = egl_g3d_st_framebuffer_validate_pbuffer;
}
stfbi->st_manager_private = (void *) &gsurf->base;
 
return stfbi;
}
 
void
egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
{
FREE(stfbi);
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_st.h
0,0 → 1,47
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#ifndef _EGL_G3D_ST_H_
#define _EGL_G3D_ST_H_
 
#include "pipe/p_compiler.h"
#include "state_tracker/st_api.h"
#include "egltypedefs.h"
 
struct st_manager *
egl_g3d_create_st_manager(_EGLDisplay *dpy);
 
void
egl_g3d_destroy_st_manager(struct st_manager *smapi);
 
struct st_framebuffer_iface *
egl_g3d_create_st_framebuffer(_EGLSurface *surf);
 
void
egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
 
#endif /* _EGL_G3D_ST_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
0,0 → 1,278
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#include "util/u_memory.h"
#include "util/u_atomic.h"
#include "os/os_thread.h"
#include "eglsync.h"
#include "eglcurrent.h"
 
#include "egl_g3d.h"
#include "egl_g3d_sync.h"
 
/**
* Wait for the conditional variable.
*/
static EGLint
egl_g3d_wait_sync_condvar(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
{
_EGLDisplay *dpy = gsync->base.Resource.Display;
 
pipe_mutex_lock(gsync->mutex);
 
/* unlock display lock just before waiting */
_eglUnlockMutex(&dpy->Mutex);
 
/* No timed wait. Always treat timeout as EGL_FOREVER_KHR */
pipe_condvar_wait(gsync->condvar, gsync->mutex);
 
_eglLockMutex(&dpy->Mutex);
 
pipe_mutex_unlock(gsync->mutex);
 
return EGL_CONDITION_SATISFIED_KHR;
}
 
/**
* Signal the conditional variable.
*/
static void
egl_g3d_signal_sync_condvar(struct egl_g3d_sync *gsync)
{
pipe_mutex_lock(gsync->mutex);
pipe_condvar_broadcast(gsync->condvar);
pipe_mutex_unlock(gsync->mutex);
}
 
/**
* Insert a fence command to the command stream of the current context.
*/
static EGLint
egl_g3d_insert_fence_sync(struct egl_g3d_sync *gsync)
{
_EGLContext *ctx = _eglGetCurrentContext();
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
 
/* already checked in egl_g3d_create_sync */
assert(gctx);
 
/* insert the fence command */
gctx->stctxi->flush(gctx->stctxi, 0x0, &gsync->fence);
if (!gsync->fence)
gsync->base.SyncStatus = EGL_SIGNALED_KHR;
 
return EGL_SUCCESS;
}
 
/**
* Wait for the fence sync to be signaled.
*/
static EGLint
egl_g3d_wait_fence_sync(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
{
EGLint ret;
 
if (gsync->fence) {
_EGLDisplay *dpy = gsync->base.Resource.Display;
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_fence_handle *fence = gsync->fence;
 
gsync->fence = NULL;
 
_eglUnlockMutex(&dpy->Mutex);
/* no timed finish? */
screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
ret = EGL_CONDITION_SATISFIED_KHR;
_eglLockMutex(&dpy->Mutex);
 
gsync->base.SyncStatus = EGL_SIGNALED_KHR;
 
screen->fence_reference(screen, &fence, NULL);
egl_g3d_signal_sync_condvar(gsync);
}
else {
ret = egl_g3d_wait_sync_condvar(gsync, timeout);
}
 
return ret;
}
 
static INLINE void
egl_g3d_ref_sync(struct egl_g3d_sync *gsync)
{
_eglGetSync(&gsync->base);
}
 
static INLINE void
egl_g3d_unref_sync(struct egl_g3d_sync *gsync)
{
if (_eglPutSync(&gsync->base)) {
pipe_condvar_destroy(gsync->condvar);
pipe_mutex_destroy(gsync->mutex);
 
if (gsync->fence) {
struct egl_g3d_display *gdpy =
egl_g3d_display(gsync->base.Resource.Display);
struct pipe_screen *screen = gdpy->native->screen;
 
screen->fence_reference(screen, &gsync->fence, NULL);
}
 
FREE(gsync);
}
}
 
_EGLSync *
egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
EGLenum type, const EGLint *attrib_list)
{
_EGLContext *ctx = _eglGetCurrentContext();
struct egl_g3d_sync *gsync;
EGLint err;
 
if (!ctx || ctx->Resource.Display != dpy) {
_eglError(EGL_BAD_MATCH, "eglCreateSyncKHR");
return NULL;
}
 
gsync = CALLOC_STRUCT(egl_g3d_sync);
if (!gsync) {
_eglError(EGL_BAD_ALLOC, "eglCreateSyncKHR");
return NULL;
}
 
if (!_eglInitSync(&gsync->base, dpy, type, attrib_list)) {
FREE(gsync);
return NULL;
}
 
switch (type) {
case EGL_SYNC_REUSABLE_KHR:
err = EGL_SUCCESS;
break;
case EGL_SYNC_FENCE_KHR:
err = egl_g3d_insert_fence_sync(gsync);
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
 
if (err != EGL_SUCCESS) {
_eglError(err, "eglCreateSyncKHR");
FREE(gsync);
return NULL;
}
 
pipe_mutex_init(gsync->mutex);
pipe_condvar_init(gsync->condvar);
 
return &gsync->base;
}
 
EGLBoolean
egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
{
struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
 
switch (gsync->base.Type) {
case EGL_SYNC_REUSABLE_KHR:
/* signal the waiters */
if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
gsync->base.SyncStatus = EGL_SIGNALED_KHR;
egl_g3d_signal_sync_condvar(gsync);
}
break;
default:
break;
}
 
egl_g3d_unref_sync(gsync);
 
return EGL_TRUE;
}
 
EGLint
egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
EGLint flags, EGLTimeKHR timeout)
{
struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
EGLint ret = EGL_CONDITION_SATISFIED_KHR;
 
if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
/* flush if there is a current context */
if (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) {
_EGLContext *ctx = _eglGetCurrentContext();
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
 
if (gctx)
gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
 
if (timeout) {
/* reference the sync object in case it is destroyed while waiting */
egl_g3d_ref_sync(gsync);
 
switch (gsync->base.Type) {
case EGL_SYNC_REUSABLE_KHR:
ret = egl_g3d_wait_sync_condvar(gsync, timeout);
break;
case EGL_SYNC_FENCE_KHR:
ret = egl_g3d_wait_fence_sync(gsync, timeout);
default:
break;
}
 
egl_g3d_unref_sync(gsync);
}
else {
ret = EGL_TIMEOUT_EXPIRED_KHR;
}
}
 
return ret;
}
 
EGLBoolean
egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
EGLenum mode)
{
struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
 
/* only for reusable sync */
if (sync->Type != EGL_SYNC_REUSABLE_KHR)
return _eglError(EGL_BAD_MATCH, "eglSignalSyncKHR");
 
if (gsync->base.SyncStatus != mode) {
gsync->base.SyncStatus = mode;
if (mode == EGL_SIGNALED_KHR)
egl_g3d_signal_sync_condvar(gsync);
}
 
return EGL_TRUE;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/egl_g3d_sync.h
0,0 → 1,48
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#ifndef _EGL_G3D_SYNC_H_
#define _EGL_G3D_SYNC_H_
 
#include "egl_g3d.h"
 
_EGLSync *
egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
EGLenum type, const EGLint *attrib_list);
 
EGLBoolean
egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
 
EGLint
egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
EGLint flags, EGLTimeKHR timeout);
 
EGLBoolean
egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
EGLenum mode);
 
#endif /* _EGL_G3D_SYNC_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native.h
0,0 → 1,342
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _NATIVE_H_
#define _NATIVE_H_
 
#include "EGL/egl.h" /* for EGL native types */
 
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "state_tracker/sw_winsys.h"
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include "native_buffer.h"
#include "native_modeset.h"
#include "native_wayland_bufmgr.h"
 
/**
* Only color buffers are listed. The others are allocated privately through,
* for example, st_renderbuffer_alloc_storage().
*/
enum native_attachment {
NATIVE_ATTACHMENT_FRONT_LEFT,
NATIVE_ATTACHMENT_BACK_LEFT,
NATIVE_ATTACHMENT_FRONT_RIGHT,
NATIVE_ATTACHMENT_BACK_RIGHT,
 
NUM_NATIVE_ATTACHMENTS
};
 
enum native_param_type {
/*
* Return TRUE if window/pixmap surfaces use the buffers of the native
* types.
*/
NATIVE_PARAM_USE_NATIVE_BUFFER,
 
/**
* Return TRUE if native_surface::present can preserve the buffer.
*/
NATIVE_PARAM_PRESERVE_BUFFER,
 
/**
* Return the maximum supported swap interval.
*/
NATIVE_PARAM_MAX_SWAP_INTERVAL,
 
/**
* Return TRUE if the display supports premultiplied alpha, regardless of
* the surface color format.
*
* Note that returning TRUE for this parameter will make
* EGL_VG_ALPHA_FORMAT_PRE_BIT to be set for all EGLConfig's with non-zero
* EGL_ALPHA_SIZE. EGL_VG_ALPHA_FORMAT attribute of a surface will affect
* how the surface is presented.
*/
NATIVE_PARAM_PREMULTIPLIED_ALPHA,
 
/**
* Return TRUE if native_surface::present supports presenting a partial
* surface.
*/
NATIVE_PARAM_PRESENT_REGION
};
 
/**
* Control how a surface presentation should happen.
*/
struct native_present_control {
/**< the attachment to present */
enum native_attachment natt;
 
/**< the contents of the presented attachment should be preserved */
boolean preserve;
 
/**< wait until the given vsyncs has passed since the last presentation */
uint swap_interval;
 
/**< pixels use premultiplied alpha */
boolean premultiplied_alpha;
 
/**< The region to present. y=0=top.
If num_rects is 0, the whole surface is to be presented */
int num_rects;
const int *rects; /* x, y, width, height */
};
 
struct native_surface {
/**
* Available for caller's use.
*/
void *user_data;
 
void (*destroy)(struct native_surface *nsurf);
 
/**
* Present the given buffer to the native engine.
*/
boolean (*present)(struct native_surface *nsurf,
const struct native_present_control *ctrl);
 
/**
* Validate the buffers of the surface. textures, if not NULL, points to an
* array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned
* by the caller. A sequence number is also returned. The caller can use
* it to check if anything has changed since the last call. Any of the
* pointers may be NULL and it indicates the caller has no interest in those
* values.
*
* If this function is called multiple times with different attachment
* masks, those not listed in the latest call might be destroyed. This
* behavior might change in the future.
*/
boolean (*validate)(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height);
 
/**
* Wait until all native commands affecting the surface has been executed.
*/
void (*wait)(struct native_surface *nsurf);
};
 
/**
* Describe a native display config.
*/
struct native_config {
/* available buffers and their format */
uint buffer_mask;
enum pipe_format color_format;
 
/* supported surface types */
boolean window_bit;
boolean pixmap_bit;
boolean scanout_bit;
 
int native_visual_id;
int native_visual_type;
int level;
boolean transparent_rgb;
int transparent_rgb_values[3];
};
 
/**
* A pipe winsys abstracts the OS. A pipe screen abstracts the graphcis
* hardware. A native display consists of a pipe winsys, a pipe screen, and
* the native display server.
*/
struct native_display {
/**
* The pipe screen of the native display.
*/
struct pipe_screen *screen;
 
/**
* Context used for copy operations.
*/
struct pipe_context *pipe;
 
/**
* Available for caller's use.
*/
void *user_data;
 
/**
* Initialize and create the pipe screen.
*/
boolean (*init_screen)(struct native_display *ndpy);
 
void (*destroy)(struct native_display *ndpy);
 
/**
* Query the parameters of the native display.
*
* The return value is defined by the parameter.
*/
int (*get_param)(struct native_display *ndpy,
enum native_param_type param);
 
/**
* Get the supported configs. The configs are owned by the display, but
* the returned array should be FREE()ed.
*/
const struct native_config **(*get_configs)(struct native_display *ndpy,
int *num_configs);
 
/**
* Get the color format of the pixmap. Required unless no config has
* pixmap_bit set.
*/
boolean (*get_pixmap_format)(struct native_display *ndpy,
EGLNativePixmapType pix,
enum pipe_format *format);
 
/**
* Copy the contents of the resource to the pixmap's front-left attachment.
* This is used to implement eglCopyBuffers. Required unless no config has
* pixmap_bit set.
*/
boolean (*copy_to_pixmap)(struct native_display *ndpy,
EGLNativePixmapType pix,
struct pipe_resource *src);
 
/**
* Create a window surface. Required unless no config has window_bit set.
*/
struct native_surface *(*create_window_surface)(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf);
 
/**
* Create a pixmap surface. The native config may be NULL. In that case, a
* "best config" will be picked. Required unless no config has pixmap_bit
* set.
*/
struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy,
EGLNativePixmapType pix,
const struct native_config *nconf);
 
const struct native_display_buffer *buffer;
const struct native_display_modeset *modeset;
const struct native_display_wayland_bufmgr *wayland_bufmgr;
};
 
/**
* The handler for events that a native display may generate. The events are
* generated asynchronously and the handler may be called by any thread at any
* time.
*/
struct native_event_handler {
/**
* This function is called when a surface needs to be validated.
*/
void (*invalid_surface)(struct native_display *ndpy,
struct native_surface *nsurf,
unsigned int seq_num);
 
struct pipe_screen *(*new_drm_screen)(struct native_display *ndpy,
const char *name, int fd);
struct pipe_screen *(*new_sw_screen)(struct native_display *ndpy,
struct sw_winsys *ws);
 
struct pipe_resource *(*lookup_egl_image)(struct native_display *ndpy,
void *egl_image);
};
 
/**
* Test whether an attachment is set in the mask.
*/
static INLINE boolean
native_attachment_mask_test(uint mask, enum native_attachment att)
{
return !!(mask & (1 << att));
}
 
/**
* Get the display copy context
*/
static INLINE struct pipe_context *
ndpy_get_copy_context(struct native_display *ndpy)
{
if (!ndpy->pipe)
ndpy->pipe = ndpy->screen->context_create(ndpy->screen, NULL);
return ndpy->pipe;
}
 
/**
* Free display screen and context resources
*/
static INLINE void
ndpy_uninit(struct native_display *ndpy)
{
if (ndpy->pipe)
ndpy->pipe->destroy(ndpy->pipe);
if (ndpy->screen)
ndpy->screen->destroy(ndpy->screen);
}
 
struct native_platform {
const char *name;
 
/**
* Create the native display and usually establish a connection to the
* display server.
*
* No event should be generated at this stage.
*/
struct native_display *(*create_display)(void *dpy, boolean use_sw);
};
 
const struct native_platform *
native_get_gdi_platform(const struct native_event_handler *event_handler);
 
const struct native_platform *
native_get_x11_platform(const struct native_event_handler *event_handler);
 
const struct native_platform *
native_get_wayland_platform(const struct native_event_handler *event_handler);
 
const struct native_platform *
native_get_drm_platform(const struct native_event_handler *event_handler);
 
const struct native_platform *
native_get_fbdev_platform(const struct native_event_handler *event_handler);
 
const struct native_platform *
native_get_null_platform(const struct native_event_handler *event_handler);
 
const struct native_platform *
native_get_android_platform(const struct native_event_handler *event_handler);
 
#ifdef __cplusplus
}
#endif
 
#endif /* _NATIVE_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native_buffer.h
0,0 → 1,75
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#ifndef _NATIVE_BUFFER_H_
#define _NATIVE_BUFFER_H_
 
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
 
struct native_display;
struct ANativeWindowBuffer;
 
enum native_buffer_type {
NATIVE_BUFFER_DRM,
NATIVE_BUFFER_ANDROID,
 
NUM_NATIVE_BUFFERS
};
 
struct native_buffer {
enum native_buffer_type type;
 
union {
struct {
struct pipe_resource templ;
unsigned name; /**< the name of the GEM object */
unsigned handle; /**< the handle of the GEM object */
unsigned stride;
} drm;
 
struct ANativeWindowBuffer *android; /**< opaque native buffer */
} u;
};
 
/**
* Buffer interface of the native display. It allows native buffers to be
* imported and exported.
*/
struct native_display_buffer {
struct pipe_resource *(*import_buffer)(struct native_display *ndpy,
struct native_buffer *buf);
 
/**
* The resource must be creatred with PIPE_BIND_SHARED.
*/
boolean (*export_buffer)(struct native_display *ndpy,
struct pipe_resource *res,
struct native_buffer *nbuf);
};
 
#endif /* _NATIVE_BUFFER_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native_helper.c
0,0 → 1,485
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
* Copyright (C) 2011 VMware Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
* Thomas Hellstrom <thellstrom@vmware.com>
*/
 
#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
 
#include "native_helper.h"
 
/**
* Number of swap fences and mask
*/
 
#define EGL_SWAP_FENCES_MAX 4
#define EGL_SWAP_FENCES_MASK 3
#define EGL_SWAP_FENCES_DEFAULT 1
 
struct resource_surface {
struct pipe_screen *screen;
enum pipe_format format;
uint bind;
 
struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS];
uint resource_mask;
uint width, height;
 
/**
* Swap fences.
*/
struct pipe_fence_handle *swap_fences[EGL_SWAP_FENCES_MAX];
unsigned int cur_fences;
unsigned int head;
unsigned int tail;
unsigned int desired_fences;
};
 
struct resource_surface *
resource_surface_create(struct pipe_screen *screen,
enum pipe_format format, uint bind)
{
struct resource_surface *rsurf = CALLOC_STRUCT(resource_surface);
char *swap_fences = getenv("EGL_THROTTLE_FENCES");
 
if (rsurf) {
rsurf->screen = screen;
rsurf->format = format;
rsurf->bind = bind;
rsurf->desired_fences = (swap_fences) ? atoi(swap_fences) :
EGL_SWAP_FENCES_DEFAULT;
if (rsurf->desired_fences > EGL_SWAP_FENCES_MAX)
rsurf->desired_fences = EGL_SWAP_FENCES_MAX;
}
 
return rsurf;
}
 
static void
resource_surface_free_resources(struct resource_surface *rsurf)
{
if (rsurf->resource_mask) {
int i;
 
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
if (rsurf->resources[i])
pipe_resource_reference(&rsurf->resources[i], NULL);
}
rsurf->resource_mask = 0x0;
}
}
 
void
resource_surface_destroy(struct resource_surface *rsurf)
{
resource_surface_free_resources(rsurf);
FREE(rsurf);
}
 
boolean
resource_surface_set_size(struct resource_surface *rsurf,
uint width, uint height)
{
boolean changed = FALSE;
 
if (rsurf->width != width || rsurf->height != height) {
resource_surface_free_resources(rsurf);
rsurf->width = width;
rsurf->height = height;
changed = TRUE;
}
 
return changed;
}
 
void
resource_surface_get_size(struct resource_surface *rsurf,
uint *width, uint *height)
{
if (width)
*width = rsurf->width;
if (height)
*height = rsurf->height;
}
 
boolean
resource_surface_add_resources(struct resource_surface *rsurf,
uint resource_mask)
{
struct pipe_resource templ;
int i;
 
resource_mask &= ~rsurf->resource_mask;
if (!resource_mask)
return TRUE;
 
if (!rsurf->width || !rsurf->height)
return FALSE;
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = rsurf->format;
templ.bind = rsurf->bind;
templ.width0 = rsurf->width;
templ.height0 = rsurf->height;
templ.depth0 = 1;
templ.array_size = 1;
 
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
if (resource_mask & (1 <<i)) {
assert(!rsurf->resources[i]);
 
rsurf->resources[i] =
rsurf->screen->resource_create(rsurf->screen, &templ);
if (rsurf->resources[i])
rsurf->resource_mask |= 1 << i;
}
}
 
return ((rsurf->resource_mask & resource_mask) == resource_mask);
}
 
void
resource_surface_import_resource(struct resource_surface *rsurf,
enum native_attachment which,
struct pipe_resource *pres)
{
pipe_resource_reference(&rsurf->resources[which], pres);
rsurf->resource_mask |= 1 << which;
}
 
void
resource_surface_get_resources(struct resource_surface *rsurf,
struct pipe_resource **resources,
uint resource_mask)
{
int i;
 
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
if (resource_mask & (1 << i)) {
resources[i] = NULL;
pipe_resource_reference(&resources[i], rsurf->resources[i]);
}
}
}
 
struct pipe_resource *
resource_surface_get_single_resource(struct resource_surface *rsurf,
enum native_attachment which)
{
struct pipe_resource *pres = NULL;
pipe_resource_reference(&pres, rsurf->resources[which]);
return pres;
}
 
static INLINE void
pointer_swap(const void **p1, const void **p2)
{
const void *tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
 
void
resource_surface_swap_buffers(struct resource_surface *rsurf,
enum native_attachment buf1,
enum native_attachment buf2,
boolean only_if_exist)
{
const uint buf1_bit = 1 << buf1;
const uint buf2_bit = 1 << buf2;
uint mask;
 
if (only_if_exist && !(rsurf->resources[buf1] && rsurf->resources[buf2]))
return;
 
pointer_swap((const void **) &rsurf->resources[buf1],
(const void **) &rsurf->resources[buf2]);
 
/* swap mask bits */
mask = rsurf->resource_mask & ~(buf1_bit | buf2_bit);
if (rsurf->resource_mask & buf1_bit)
mask |= buf2_bit;
if (rsurf->resource_mask & buf2_bit)
mask |= buf1_bit;
 
rsurf->resource_mask = mask;
}
 
boolean
resource_surface_present(struct resource_surface *rsurf,
enum native_attachment which,
void *winsys_drawable_handle)
{
struct pipe_resource *pres = rsurf->resources[which];
 
if (!pres)
return TRUE;
 
rsurf->screen->flush_frontbuffer(rsurf->screen,
pres, 0, 0, winsys_drawable_handle);
 
return TRUE;
}
 
/**
* Schedule a copy swap from the back to the front buffer using the
* native display's copy context.
*/
boolean
resource_surface_copy_swap(struct resource_surface *rsurf,
struct native_display *ndpy)
{
struct pipe_resource *ftex;
struct pipe_resource *btex;
struct pipe_context *pipe;
struct pipe_box src_box;
boolean ret = FALSE;
 
pipe = ndpy_get_copy_context(ndpy);
if (!pipe)
return FALSE;
 
ftex = resource_surface_get_single_resource(rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT);
if (!ftex)
goto out_no_ftex;
btex = resource_surface_get_single_resource(rsurf,
NATIVE_ATTACHMENT_BACK_LEFT);
if (!btex)
goto out_no_btex;
 
u_box_origin_2d(ftex->width0, ftex->height0, &src_box);
pipe->resource_copy_region(pipe, ftex, 0, 0, 0, 0,
btex, 0, &src_box);
ret = TRUE;
 
out_no_btex:
pipe_resource_reference(&btex, NULL);
out_no_ftex:
pipe_resource_reference(&ftex, NULL);
 
return ret;
}
 
static struct pipe_fence_handle *
swap_fences_pop_front(struct resource_surface *rsurf)
{
struct pipe_screen *screen = rsurf->screen;
struct pipe_fence_handle *fence = NULL;
 
if (rsurf->desired_fences == 0)
return NULL;
 
if (rsurf->cur_fences >= rsurf->desired_fences) {
screen->fence_reference(screen, &fence, rsurf->swap_fences[rsurf->tail]);
screen->fence_reference(screen, &rsurf->swap_fences[rsurf->tail++], NULL);
rsurf->tail &= EGL_SWAP_FENCES_MASK;
--rsurf->cur_fences;
}
return fence;
}
 
static void
swap_fences_push_back(struct resource_surface *rsurf,
struct pipe_fence_handle *fence)
{
struct pipe_screen *screen = rsurf->screen;
 
if (!fence || rsurf->desired_fences == 0)
return;
 
while(rsurf->cur_fences == rsurf->desired_fences)
swap_fences_pop_front(rsurf);
 
rsurf->cur_fences++;
screen->fence_reference(screen, &rsurf->swap_fences[rsurf->head++],
fence);
rsurf->head &= EGL_SWAP_FENCES_MASK;
}
 
boolean
resource_surface_throttle(struct resource_surface *rsurf)
{
struct pipe_screen *screen = rsurf->screen;
struct pipe_fence_handle *fence = swap_fences_pop_front(rsurf);
 
if (fence) {
(void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
return TRUE;
}
 
return FALSE;
}
 
boolean
resource_surface_flush(struct resource_surface *rsurf,
struct native_display *ndpy)
{
struct pipe_fence_handle *fence = NULL;
struct pipe_screen *screen = rsurf->screen;
struct pipe_context *pipe= ndpy_get_copy_context(ndpy);
 
if (!pipe)
return FALSE;
 
pipe->flush(pipe, &fence, 0);
if (fence == NULL)
return FALSE;
 
swap_fences_push_back(rsurf, fence);
screen->fence_reference(screen, &fence, NULL);
 
return TRUE;
}
 
void
resource_surface_wait(struct resource_surface *rsurf)
{
while (resource_surface_throttle(rsurf));
}
 
boolean
native_display_copy_to_pixmap(struct native_display *ndpy,
EGLNativePixmapType pix,
struct pipe_resource *src)
{
struct pipe_context *pipe;
struct native_surface *nsurf;
struct pipe_resource *dst;
struct pipe_resource *tmp[NUM_NATIVE_ATTACHMENTS];
const enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
 
pipe = ndpy_get_copy_context(ndpy);
if (!pipe)
return FALSE;
 
nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL);
if (!nsurf)
return FALSE;
 
/* get the texutre */
tmp[natt] = NULL;
nsurf->validate(nsurf, 1 << natt, NULL, tmp, NULL, NULL);
dst = tmp[natt];
 
if (dst && dst->format == src->format) {
struct native_present_control ctrl;
struct pipe_box src_box;
 
u_box_origin_2d(src->width0, src->height0, &src_box);
pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &src_box);
pipe->flush(pipe, NULL, 0);
 
memset(&ctrl, 0, sizeof(ctrl));
ctrl.natt = natt;
nsurf->present(nsurf, &ctrl);
}
 
if (dst)
pipe_resource_reference(&dst, NULL);
 
nsurf->destroy(nsurf);
 
return TRUE;
}
 
#include "state_tracker/drm_driver.h"
struct pipe_resource *
drm_display_import_native_buffer(struct native_display *ndpy,
struct native_buffer *nbuf)
{
struct pipe_screen *screen = ndpy->screen;
struct pipe_resource *res = NULL;
 
switch (nbuf->type) {
case NATIVE_BUFFER_DRM:
{
struct winsys_handle wsh;
 
memset(&wsh, 0, sizeof(wsh));
wsh.handle = nbuf->u.drm.name;
wsh.stride = nbuf->u.drm.stride;
 
res = screen->resource_from_handle(screen, &nbuf->u.drm.templ, &wsh);
}
break;
default:
break;
}
 
return res;
}
 
boolean
drm_display_export_native_buffer(struct native_display *ndpy,
struct pipe_resource *res,
struct native_buffer *nbuf)
{
struct pipe_screen *screen = ndpy->screen;
boolean ret = FALSE;
 
switch (nbuf->type) {
case NATIVE_BUFFER_DRM:
{
struct winsys_handle wsh;
 
if ((nbuf->u.drm.templ.bind & res->bind) != nbuf->u.drm.templ.bind)
break;
 
memset(&wsh, 0, sizeof(wsh));
wsh.type = DRM_API_HANDLE_TYPE_KMS;
if (!screen->resource_get_handle(screen, res, &wsh))
break;
 
nbuf->u.drm.handle = wsh.handle;
nbuf->u.drm.stride = wsh.stride;
 
/* get the name of the GEM object */
if (nbuf->u.drm.templ.bind & PIPE_BIND_SHARED) {
memset(&wsh, 0, sizeof(wsh));
wsh.type = DRM_API_HANDLE_TYPE_SHARED;
if (!screen->resource_get_handle(screen, res, &wsh))
break;
 
nbuf->u.drm.name = wsh.handle;
}
 
nbuf->u.drm.templ = *res;
ret = TRUE;
}
break;
default:
break;
}
 
return ret;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native_helper.h
0,0 → 1,120
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
* Copyright (C) 2011 VMware Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
* Thomas Hellstrom <thellstrom@vmware.com>
*/
 
#include "native.h"
 
struct resource_surface;
struct sw_winsys;
 
struct resource_surface *
resource_surface_create(struct pipe_screen *screen,
enum pipe_format format, uint bind);
 
void
resource_surface_destroy(struct resource_surface *rsurf);
 
boolean
resource_surface_set_size(struct resource_surface *rsurf,
uint width, uint height);
 
void
resource_surface_get_size(struct resource_surface *rsurf,
uint *width, uint *height);
 
boolean
resource_surface_add_resources(struct resource_surface *rsurf,
uint resource_mask);
 
void
resource_surface_import_resource(struct resource_surface *rsurf,
enum native_attachment which,
struct pipe_resource *pres);
 
void
resource_surface_get_resources(struct resource_surface *rsurf,
struct pipe_resource **resources,
uint resource_mask);
 
struct pipe_resource *
resource_surface_get_single_resource(struct resource_surface *rsurf,
enum native_attachment which);
 
void
resource_surface_swap_buffers(struct resource_surface *rsurf,
enum native_attachment buf1,
enum native_attachment buf2,
boolean only_if_exist);
 
boolean
resource_surface_present(struct resource_surface *rsurf,
enum native_attachment which,
void *winsys_drawable_handle);
 
/**
* Perform a gallium copy blit between the back left and front left
* surfaces. Needs to be followed by a call to resource_surface_flush.
*/
boolean
resource_surface_copy_swap(struct resource_surface *rsurf,
struct native_display *ndpy);
 
/**
* Throttle on outstanding rendering using the copy context. For example
* copy swaps.
*/
boolean
resource_surface_throttle(struct resource_surface *rsurf);
 
/**
* Flush pending rendering using the copy context. This function saves a
* marker for upcoming throttles.
*/
boolean
resource_surface_flush(struct resource_surface *rsurf,
struct native_display *ndpy);
/**
* Wait for all rendering using the copy context to be complete. Frees all
* throttle markers saved using resource_surface_flush.
*/
void
resource_surface_wait(struct resource_surface *rsurf);
 
boolean
native_display_copy_to_pixmap(struct native_display *ndpy,
EGLNativePixmapType pix,
struct pipe_resource *src);
 
struct pipe_resource *
drm_display_import_native_buffer(struct native_display *ndpy,
struct native_buffer *nbuf);
 
boolean
drm_display_export_native_buffer(struct native_display *ndpy,
struct pipe_resource *res,
struct native_buffer *nbuf);
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native_modeset.h
0,0 → 1,87
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _NATIVE_MODESET_H_
#define _NATIVE_MODESET_H_
 
#include "pipe/p_compiler.h"
 
struct native_display;
struct native_surface;
struct native_config;
 
struct native_connector {
int dummy;
};
 
struct native_mode {
const char *desc;
int width, height;
int refresh_rate; /* HZ * 1000 */
};
 
/**
* Mode setting interface of the native display. It exposes the mode setting
* capabilities of the underlying graphics hardware.
*/
struct native_display_modeset {
/**
* Get the available physical connectors and the number of CRTCs.
*/
const struct native_connector **(*get_connectors)(struct native_display *ndpy,
int *num_connectors,
int *num_crtcs);
 
/**
* Get the current supported modes of a connector. The returned modes may
* change every time this function is called and those from previous calls
* might become invalid.
*/
const struct native_mode **(*get_modes)(struct native_display *ndpy,
const struct native_connector *nconn,
int *num_modes);
 
/**
* Create a scan-out surface. Required unless no config has scanout_bit
* set.
*/
struct native_surface *(*create_scanout_surface)(struct native_display *ndpy,
const struct native_config *nconf,
uint width, uint height);
 
/**
* Program the CRTC to output the surface to the given connectors with the
* given mode. When surface is not given, the CRTC is disabled.
*
* This interface does not export a way to query capabilities of the CRTCs.
* The native display usually needs to dynamically map the index to a CRTC
* that supports the given connectors.
*/
boolean (*program)(struct native_display *ndpy, int crtc_idx,
struct native_surface *nsurf, uint x, uint y,
const struct native_connector **nconns, int num_nconns,
const struct native_mode *nmode);
};
 
#endif /* _NATIVE_MODESET_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native_wayland_bufmgr.h
0,0 → 1,49
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _NATIVE_WAYLAND_BUFMGR_H_
#define _NATIVE_WAYLAND_BUFMGR_H_
 
struct native_display;
struct wl_display;
struct wl_buffer;
struct pipe_resource;
 
struct native_display_wayland_bufmgr {
boolean (*bind_display)(struct native_display *ndpy,
struct wl_display *wl_dpy);
 
boolean (*unbind_display)(struct native_display *ndpy,
struct wl_display *wl_dpy);
 
struct pipe_resource *(*buffer_get_resource)(struct native_display *ndpy,
struct wl_buffer *buffer);
 
boolean (*query_buffer)(struct native_display *ndpy,
struct wl_buffer *buffer,
int attribute, int *value);
};
 
#endif /* _NATIVE_WAYLAND_BUFMGR_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c
0,0 → 1,106
#include <stdint.h>
#include <string.h>
 
#include "native.h"
#include "util/u_inlines.h"
#include "state_tracker/drm_driver.h"
 
#ifdef HAVE_WAYLAND_BACKEND
 
#include <wayland-server.h>
#include <wayland-drm-server-protocol.h>
 
#include "native_wayland_drm_bufmgr_helper.h"
 
void
egl_g3d_wl_drm_helper_reference_buffer(void *user_data, uint32_t name, int fd,
struct wl_drm_buffer *buffer)
{
struct native_display *ndpy = user_data;
struct pipe_resource templ;
struct winsys_handle wsh;
enum pipe_format pf;
 
switch (buffer->format) {
case WL_DRM_FORMAT_ARGB8888:
pf = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case WL_DRM_FORMAT_XRGB8888:
pf = PIPE_FORMAT_B8G8R8X8_UNORM;
break;
default:
pf = PIPE_FORMAT_NONE;
break;
}
 
if (pf == PIPE_FORMAT_NONE)
return;
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = pf;
templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
templ.width0 = buffer->buffer.width;
templ.height0 = buffer->buffer.height;
templ.depth0 = 1;
templ.array_size = 1;
 
memset(&wsh, 0, sizeof(wsh));
wsh.handle = name;
wsh.stride = buffer->stride[0];
 
buffer->driver_buffer =
ndpy->screen->resource_from_handle(ndpy->screen, &templ, &wsh);
}
 
void
egl_g3d_wl_drm_helper_unreference_buffer(void *user_data,
struct wl_drm_buffer *buffer)
{
struct pipe_resource *resource = buffer->driver_buffer;
 
pipe_resource_reference(&resource, NULL);
}
 
struct pipe_resource *
egl_g3d_wl_drm_common_wl_buffer_get_resource(struct native_display *ndpy,
struct wl_buffer *buffer)
{
return wayland_drm_buffer_get_buffer(buffer);
}
 
EGLBoolean
egl_g3d_wl_drm_common_query_buffer(struct native_display *ndpy,
struct wl_buffer *_buffer,
EGLint attribute, EGLint *value)
{
struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer;
struct pipe_resource *resource = buffer->driver_buffer;
 
if (!wayland_buffer_is_drm(&buffer->buffer))
return EGL_FALSE;
 
switch (attribute) {
case EGL_TEXTURE_FORMAT:
switch (resource->format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
*value = EGL_TEXTURE_RGBA;
return EGL_TRUE;
case PIPE_FORMAT_B8G8R8X8_UNORM:
*value = EGL_TEXTURE_RGB;
return EGL_TRUE;
default:
return EGL_FALSE;
}
case EGL_WIDTH:
*value = buffer->buffer.width;
return EGL_TRUE;
case EGL_HEIGHT:
*value = buffer->buffer.height;
return EGL_TRUE;
default:
return EGL_FALSE;
}
}
 
#endif
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.h
0,0 → 1,47
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _NATIVE_WAYLAND_DRM_BUFMGR_HELPER_H_
#define _NATIVE_WAYLAND_DRM_BUFMGR_HELPER_H_
 
#include "wayland-drm.h"
 
void
egl_g3d_wl_drm_helper_reference_buffer(void *user_data, uint32_t name, int fd,
struct wl_drm_buffer *buffer);
 
void
egl_g3d_wl_drm_helper_unreference_buffer(void *user_data,
struct wl_drm_buffer *buffer);
 
struct pipe_resource *
egl_g3d_wl_drm_common_wl_buffer_get_resource(struct native_display *ndpy,
struct wl_buffer *buffer);
 
EGLBoolean
egl_g3d_wl_drm_common_query_buffer(struct native_display *ndpy,
struct wl_buffer *buffer,
EGLint attribute, EGLint *value);
 
#endif /* _NATIVE_WAYLAND_DRM_BUFMGR_HELPER_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/drm/modeset.c
0,0 → 1,707
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
* Copyright (C) 2011 VMware Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
* Thomas Hellstrom <thellstrom@vmware.com>
*/
 
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "egllog.h"
 
#include "native_drm.h"
 
static boolean
drm_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
 
if (!resource_surface_add_resources(drmsurf->rsurf, attachment_mask))
return FALSE;
if (textures)
resource_surface_get_resources(drmsurf->rsurf, textures, attachment_mask);
 
if (seq_num)
*seq_num = drmsurf->sequence_number;
if (width)
*width = drmsurf->width;
if (height)
*height = drmsurf->height;
 
return TRUE;
}
 
/**
* Add textures as DRM framebuffers.
*/
static boolean
drm_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
struct drm_display *drmdpy = drmsurf->drmdpy;
int num_framebuffers = (need_back) ? 2 : 1;
int i, err;
 
for (i = 0; i < num_framebuffers; i++) {
struct drm_framebuffer *fb;
enum native_attachment natt;
struct winsys_handle whandle;
uint block_bits;
 
if (i == 0) {
fb = &drmsurf->front_fb;
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
}
else {
fb = &drmsurf->back_fb;
natt = NATIVE_ATTACHMENT_BACK_LEFT;
}
 
if (!fb->texture) {
/* make sure the texture has been allocated */
resource_surface_add_resources(drmsurf->rsurf, 1 << natt);
fb->texture =
resource_surface_get_single_resource(drmsurf->rsurf, natt);
if (!fb->texture)
return FALSE;
}
 
/* already initialized */
if (fb->buffer_id)
continue;
 
/* TODO detect the real value */
fb->is_passive = TRUE;
 
memset(&whandle, 0, sizeof(whandle));
whandle.type = DRM_API_HANDLE_TYPE_KMS;
 
if (!drmdpy->base.screen->resource_get_handle(drmdpy->base.screen,
fb->texture, &whandle))
return FALSE;
 
block_bits = util_format_get_blocksizebits(drmsurf->color_format);
err = drmModeAddFB(drmdpy->fd, drmsurf->width, drmsurf->height,
block_bits, block_bits, whandle.stride, whandle.handle,
&fb->buffer_id);
if (err) {
fb->buffer_id = 0;
return FALSE;
}
}
 
return TRUE;
}
 
static boolean
drm_surface_flush_frontbuffer(struct native_surface *nsurf)
{
#ifdef DRM_MODE_FEATURE_DIRTYFB
struct drm_surface *drmsurf = drm_surface(nsurf);
struct drm_display *drmdpy = drmsurf->drmdpy;
 
if (drmsurf->front_fb.is_passive)
drmModeDirtyFB(drmdpy->fd, drmsurf->front_fb.buffer_id, NULL, 0);
#endif
 
return TRUE;
}
 
static boolean
drm_surface_copy_swap(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
struct drm_display *drmdpy = drmsurf->drmdpy;
 
(void) resource_surface_throttle(drmsurf->rsurf);
if (!resource_surface_copy_swap(drmsurf->rsurf, &drmdpy->base))
return FALSE;
 
(void) resource_surface_flush(drmsurf->rsurf, &drmdpy->base);
if (!drm_surface_flush_frontbuffer(nsurf))
return FALSE;
 
drmsurf->sequence_number++;
 
return TRUE;
}
 
static boolean
drm_surface_swap_buffers(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
struct drm_crtc *drmcrtc = &drmsurf->current_crtc;
struct drm_display *drmdpy = drmsurf->drmdpy;
struct drm_framebuffer tmp_fb;
int err;
 
if (!drmsurf->have_pageflip)
return drm_surface_copy_swap(nsurf);
 
if (!drmsurf->back_fb.buffer_id) {
if (!drm_surface_init_framebuffers(&drmsurf->base, TRUE))
return FALSE;
}
 
if (drmsurf->is_shown && drmcrtc->crtc) {
err = drmModePageFlip(drmdpy->fd, drmcrtc->crtc->crtc_id,
drmsurf->back_fb.buffer_id, 0, NULL);
if (err) {
drmsurf->have_pageflip = FALSE;
return drm_surface_copy_swap(nsurf);
}
}
 
/* swap the buffers */
tmp_fb = drmsurf->front_fb;
drmsurf->front_fb = drmsurf->back_fb;
drmsurf->back_fb = tmp_fb;
 
resource_surface_swap_buffers(drmsurf->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
/* the front/back textures are swapped */
drmsurf->sequence_number++;
drmdpy->event_handler->invalid_surface(&drmdpy->base,
&drmsurf->base, drmsurf->sequence_number);
 
return TRUE;
}
 
static boolean
drm_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
boolean ret;
 
if (ctrl->swap_interval)
return FALSE;
 
switch (ctrl->natt) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
ret = drm_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
if (ctrl->preserve)
ret = drm_surface_copy_swap(nsurf);
else
ret = drm_surface_swap_buffers(nsurf);
break;
default:
ret = FALSE;
break;
}
 
return ret;
}
 
static void
drm_surface_wait(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
 
resource_surface_wait(drmsurf->rsurf);
}
 
static void
drm_surface_destroy(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
 
resource_surface_wait(drmsurf->rsurf);
if (drmsurf->current_crtc.crtc)
drmModeFreeCrtc(drmsurf->current_crtc.crtc);
 
if (drmsurf->front_fb.buffer_id)
drmModeRmFB(drmsurf->drmdpy->fd, drmsurf->front_fb.buffer_id);
pipe_resource_reference(&drmsurf->front_fb.texture, NULL);
 
if (drmsurf->back_fb.buffer_id)
drmModeRmFB(drmsurf->drmdpy->fd, drmsurf->back_fb.buffer_id);
pipe_resource_reference(&drmsurf->back_fb.texture, NULL);
 
resource_surface_destroy(drmsurf->rsurf);
FREE(drmsurf);
}
 
static struct drm_surface *
drm_display_create_surface(struct native_display *ndpy,
const struct native_config *nconf,
uint width, uint height)
{
struct drm_display *drmdpy = drm_display(ndpy);
struct drm_config *drmconf = drm_config(nconf);
struct drm_surface *drmsurf;
 
drmsurf = CALLOC_STRUCT(drm_surface);
if (!drmsurf)
return NULL;
 
drmsurf->drmdpy = drmdpy;
drmsurf->color_format = drmconf->base.color_format;
drmsurf->width = width;
drmsurf->height = height;
drmsurf->have_pageflip = TRUE;
 
drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
drmsurf->color_format,
PIPE_BIND_RENDER_TARGET |
PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT);
if (!drmsurf->rsurf) {
FREE(drmsurf);
return NULL;
}
 
resource_surface_set_size(drmsurf->rsurf, drmsurf->width, drmsurf->height);
 
drmsurf->base.destroy = drm_surface_destroy;
drmsurf->base.present = drm_surface_present;
drmsurf->base.validate = drm_surface_validate;
drmsurf->base.wait = drm_surface_wait;
 
return drmsurf;
}
 
struct native_surface *
drm_display_create_surface_from_resource(struct native_display *ndpy,
struct pipe_resource *resource)
{
struct drm_display *drmdpy = drm_display(ndpy);
struct drm_surface *drmsurf;
enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
 
drmsurf = CALLOC_STRUCT(drm_surface);
if (!drmsurf)
return NULL;
 
drmsurf->drmdpy = drmdpy;
drmsurf->color_format = resource->format;
drmsurf->width = resource->width0;
drmsurf->height = resource->height0;
drmsurf->have_pageflip = FALSE;
 
drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
drmsurf->color_format,
PIPE_BIND_RENDER_TARGET |
PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT);
resource_surface_import_resource(drmsurf->rsurf, natt, resource);
 
drmsurf->base.destroy = drm_surface_destroy;
drmsurf->base.present = drm_surface_present;
drmsurf->base.validate = drm_surface_validate;
drmsurf->base.wait = drm_surface_wait;
 
return &drmsurf->base;
}
 
/**
* Choose a CRTC that supports all given connectors.
*/
static uint32_t
drm_display_choose_crtc(struct native_display *ndpy,
uint32_t *connectors, int num_connectors)
{
struct drm_display *drmdpy = drm_display(ndpy);
int idx;
 
for (idx = 0; idx < drmdpy->resources->count_crtcs; idx++) {
boolean found_crtc = TRUE;
int i, j;
 
for (i = 0; i < num_connectors; i++) {
drmModeConnectorPtr connector;
int encoder_idx = -1;
 
connector = drmModeGetConnector(drmdpy->fd, connectors[i]);
if (!connector) {
found_crtc = FALSE;
break;
}
 
/* find an encoder the CRTC supports */
for (j = 0; j < connector->count_encoders; j++) {
drmModeEncoderPtr encoder =
drmModeGetEncoder(drmdpy->fd, connector->encoders[j]);
if (encoder->possible_crtcs & (1 << idx)) {
encoder_idx = j;
break;
}
drmModeFreeEncoder(encoder);
}
 
drmModeFreeConnector(connector);
if (encoder_idx < 0) {
found_crtc = FALSE;
break;
}
}
 
if (found_crtc)
break;
}
 
if (idx >= drmdpy->resources->count_crtcs) {
_eglLog(_EGL_WARNING,
"failed to find a CRTC that supports the given %d connectors",
num_connectors);
return 0;
}
 
return drmdpy->resources->crtcs[idx];
}
 
/**
* Remember the original CRTC status and set the CRTC
*/
static boolean
drm_display_set_crtc(struct native_display *ndpy, int crtc_idx,
uint32_t buffer_id, uint32_t x, uint32_t y,
uint32_t *connectors, int num_connectors,
drmModeModeInfoPtr mode)
{
struct drm_display *drmdpy = drm_display(ndpy);
struct drm_crtc *drmcrtc = &drmdpy->saved_crtcs[crtc_idx];
uint32_t crtc_id;
int err;
 
if (drmcrtc->crtc) {
crtc_id = drmcrtc->crtc->crtc_id;
}
else {
int count = 0, i;
 
/*
* Choose the CRTC once. It could be more dynamic, but let's keep it
* simple for now.
*/
crtc_id = drm_display_choose_crtc(&drmdpy->base,
connectors, num_connectors);
 
/* save the original CRTC status */
drmcrtc->crtc = drmModeGetCrtc(drmdpy->fd, crtc_id);
if (!drmcrtc->crtc)
return FALSE;
 
for (i = 0; i < drmdpy->num_connectors; i++) {
struct drm_connector *drmconn = &drmdpy->connectors[i];
drmModeConnectorPtr connector = drmconn->connector;
drmModeEncoderPtr encoder;
 
encoder = drmModeGetEncoder(drmdpy->fd, connector->encoder_id);
if (encoder) {
if (encoder->crtc_id == crtc_id) {
drmcrtc->connectors[count++] = connector->connector_id;
if (count >= Elements(drmcrtc->connectors))
break;
}
drmModeFreeEncoder(encoder);
}
}
 
drmcrtc->num_connectors = count;
}
 
err = drmModeSetCrtc(drmdpy->fd, crtc_id, buffer_id, x, y,
connectors, num_connectors, mode);
if (err) {
drmModeFreeCrtc(drmcrtc->crtc);
drmcrtc->crtc = NULL;
drmcrtc->num_connectors = 0;
 
return FALSE;
}
 
return TRUE;
}
 
static boolean
drm_display_program(struct native_display *ndpy, int crtc_idx,
struct native_surface *nsurf, uint x, uint y,
const struct native_connector **nconns, int num_nconns,
const struct native_mode *nmode)
{
struct drm_display *drmdpy = drm_display(ndpy);
struct drm_surface *drmsurf = drm_surface(nsurf);
const struct drm_mode *drmmode = drm_mode(nmode);
uint32_t connector_ids[32];
uint32_t buffer_id;
drmModeModeInfo mode_tmp, *mode;
int i;
 
if (num_nconns > Elements(connector_ids)) {
_eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns);
num_nconns = Elements(connector_ids);
}
 
if (drmsurf) {
if (!drm_surface_init_framebuffers(&drmsurf->base, FALSE))
return FALSE;
 
buffer_id = drmsurf->front_fb.buffer_id;
/* the mode argument of drmModeSetCrtc is not constified */
mode_tmp = drmmode->mode;
mode = &mode_tmp;
}
else {
/* disable the CRTC */
buffer_id = 0;
mode = NULL;
num_nconns = 0;
}
 
for (i = 0; i < num_nconns; i++) {
struct drm_connector *drmconn = drm_connector(nconns[i]);
connector_ids[i] = drmconn->connector->connector_id;
}
 
if (!drm_display_set_crtc(&drmdpy->base, crtc_idx, buffer_id, x, y,
connector_ids, num_nconns, mode)) {
_eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx);
 
return FALSE;
}
 
if (drmdpy->shown_surfaces[crtc_idx])
drmdpy->shown_surfaces[crtc_idx]->is_shown = FALSE;
drmdpy->shown_surfaces[crtc_idx] = drmsurf;
 
/* remember the settings for buffer swapping */
if (drmsurf) {
uint32_t crtc_id = drmdpy->saved_crtcs[crtc_idx].crtc->crtc_id;
struct drm_crtc *drmcrtc = &drmsurf->current_crtc;
 
if (drmcrtc->crtc)
drmModeFreeCrtc(drmcrtc->crtc);
drmcrtc->crtc = drmModeGetCrtc(drmdpy->fd, crtc_id);
 
assert(num_nconns < Elements(drmcrtc->connectors));
memcpy(drmcrtc->connectors, connector_ids,
sizeof(*connector_ids) * num_nconns);
drmcrtc->num_connectors = num_nconns;
 
drmsurf->is_shown = TRUE;
}
 
return TRUE;
}
 
static const struct native_mode **
drm_display_get_modes(struct native_display *ndpy,
const struct native_connector *nconn,
int *num_modes)
{
struct drm_display *drmdpy = drm_display(ndpy);
struct drm_connector *drmconn = drm_connector(nconn);
const struct native_mode **nmodes_return;
int count, i;
 
/* delete old data */
if (drmconn->connector) {
drmModeFreeConnector(drmconn->connector);
FREE(drmconn->drm_modes);
 
drmconn->connector = NULL;
drmconn->drm_modes = NULL;
drmconn->num_modes = 0;
}
 
/* detect again */
drmconn->connector = drmModeGetConnector(drmdpy->fd, drmconn->connector_id);
if (!drmconn->connector)
return NULL;
 
count = drmconn->connector->count_modes;
drmconn->drm_modes = CALLOC(count, sizeof(*drmconn->drm_modes));
if (!drmconn->drm_modes) {
drmModeFreeConnector(drmconn->connector);
drmconn->connector = NULL;
 
return NULL;
}
 
for (i = 0; i < count; i++) {
struct drm_mode *drmmode = &drmconn->drm_modes[i];
drmModeModeInfoPtr mode = &drmconn->connector->modes[i];
 
drmmode->mode = *mode;
 
drmmode->base.desc = drmmode->mode.name;
drmmode->base.width = drmmode->mode.hdisplay;
drmmode->base.height = drmmode->mode.vdisplay;
drmmode->base.refresh_rate = drmmode->mode.vrefresh;
/* not all kernels have vrefresh = refresh_rate * 1000 */
if (drmmode->base.refresh_rate < 1000)
drmmode->base.refresh_rate *= 1000;
}
 
nmodes_return = MALLOC(count * sizeof(*nmodes_return));
if (nmodes_return) {
for (i = 0; i < count; i++)
nmodes_return[i] = &drmconn->drm_modes[i].base;
if (num_modes)
*num_modes = count;
}
 
return nmodes_return;
}
 
static const struct native_connector **
drm_display_get_connectors(struct native_display *ndpy, int *num_connectors,
int *num_crtc)
{
struct drm_display *drmdpy = drm_display(ndpy);
const struct native_connector **connectors;
int i;
 
if (!drmdpy->connectors) {
drmdpy->connectors =
CALLOC(drmdpy->resources->count_connectors, sizeof(*drmdpy->connectors));
if (!drmdpy->connectors)
return NULL;
 
for (i = 0; i < drmdpy->resources->count_connectors; i++) {
struct drm_connector *drmconn = &drmdpy->connectors[i];
 
drmconn->connector_id = drmdpy->resources->connectors[i];
/* drmconn->connector is allocated when the modes are asked */
}
 
drmdpy->num_connectors = drmdpy->resources->count_connectors;
}
 
connectors = MALLOC(drmdpy->num_connectors * sizeof(*connectors));
if (connectors) {
for (i = 0; i < drmdpy->num_connectors; i++)
connectors[i] = &drmdpy->connectors[i].base;
if (num_connectors)
*num_connectors = drmdpy->num_connectors;
}
 
if (num_crtc)
*num_crtc = drmdpy->resources->count_crtcs;
 
return connectors;
}
 
static struct native_surface *
drm_display_create_scanout_surface(struct native_display *ndpy,
const struct native_config *nconf,
uint width, uint height)
{
struct drm_surface *drmsurf;
 
drmsurf = drm_display_create_surface(ndpy, nconf, width, height);
return &drmsurf->base;
}
 
static struct native_display_modeset drm_display_modeset = {
.get_connectors = drm_display_get_connectors,
.get_modes = drm_display_get_modes,
.create_scanout_surface = drm_display_create_scanout_surface,
.program = drm_display_program
};
 
void
drm_display_fini_modeset(struct native_display *ndpy)
{
struct drm_display *drmdpy = drm_display(ndpy);
int i;
 
if (drmdpy->connectors) {
for (i = 0; i < drmdpy->num_connectors; i++) {
struct drm_connector *drmconn = &drmdpy->connectors[i];
if (drmconn->connector) {
drmModeFreeConnector(drmconn->connector);
FREE(drmconn->drm_modes);
}
}
FREE(drmdpy->connectors);
}
 
FREE(drmdpy->shown_surfaces);
drmdpy->shown_surfaces = NULL;
 
if (drmdpy->saved_crtcs) {
for (i = 0; i < drmdpy->resources->count_crtcs; i++) {
struct drm_crtc *drmcrtc = &drmdpy->saved_crtcs[i];
 
if (drmcrtc->crtc) {
/* restore crtc */
drmModeSetCrtc(drmdpy->fd, drmcrtc->crtc->crtc_id,
drmcrtc->crtc->buffer_id, drmcrtc->crtc->x, drmcrtc->crtc->y,
drmcrtc->connectors, drmcrtc->num_connectors,
&drmcrtc->crtc->mode);
 
drmModeFreeCrtc(drmcrtc->crtc);
}
}
FREE(drmdpy->saved_crtcs);
}
 
if (drmdpy->resources) {
drmModeFreeResources(drmdpy->resources);
drmdpy->resources = NULL;
}
 
drmdpy->base.modeset = NULL;
}
 
boolean
drm_display_init_modeset(struct native_display *ndpy)
{
struct drm_display *drmdpy = drm_display(ndpy);
 
/* resources are fixed, unlike crtc, connector, or encoder */
drmdpy->resources = drmModeGetResources(drmdpy->fd);
if (!drmdpy->resources) {
_eglLog(_EGL_DEBUG, "Failed to get KMS resources. Disable modeset.");
return FALSE;
}
 
drmdpy->saved_crtcs =
CALLOC(drmdpy->resources->count_crtcs, sizeof(*drmdpy->saved_crtcs));
if (!drmdpy->saved_crtcs) {
drm_display_fini_modeset(&drmdpy->base);
return FALSE;
}
 
drmdpy->shown_surfaces =
CALLOC(drmdpy->resources->count_crtcs, sizeof(*drmdpy->shown_surfaces));
if (!drmdpy->shown_surfaces) {
drm_display_fini_modeset(&drmdpy->base);
return FALSE;
}
 
drmdpy->base.modeset = &drm_display_modeset;
 
return TRUE;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/drm/native_drm.c
0,0 → 1,355
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
 
#include "util/u_memory.h"
#include "egllog.h"
 
#include "native_drm.h"
 
#include "gbm_gallium_drmint.h"
 
#ifdef HAVE_LIBUDEV
#include <libudev.h>
#endif
 
static boolean
drm_display_is_format_supported(struct native_display *ndpy,
enum pipe_format fmt, boolean is_color)
{
return ndpy->screen->is_format_supported(ndpy->screen,
fmt, PIPE_TEXTURE_2D, 0,
(is_color) ? PIPE_BIND_RENDER_TARGET :
PIPE_BIND_DEPTH_STENCIL);
}
 
static const struct native_config **
drm_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct drm_display *drmdpy = drm_display(ndpy);
const struct native_config **configs;
 
/* first time */
if (!drmdpy->config) {
struct native_config *nconf;
enum pipe_format format;
 
drmdpy->config = CALLOC(1, sizeof(*drmdpy->config));
if (!drmdpy->config)
return NULL;
 
nconf = &drmdpy->config->base;
 
nconf->buffer_mask =
(1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
(1 << NATIVE_ATTACHMENT_BACK_LEFT);
 
format = PIPE_FORMAT_B8G8R8A8_UNORM;
if (!drm_display_is_format_supported(&drmdpy->base, format, TRUE)) {
format = PIPE_FORMAT_A8R8G8B8_UNORM;
if (!drm_display_is_format_supported(&drmdpy->base, format, TRUE))
format = PIPE_FORMAT_NONE;
}
if (format == PIPE_FORMAT_NONE) {
FREE(drmdpy->config);
drmdpy->config = NULL;
return NULL;
}
 
nconf->color_format = format;
 
/* support KMS */
if (drmdpy->resources)
nconf->scanout_bit = TRUE;
}
 
configs = MALLOC(sizeof(*configs));
if (configs) {
configs[0] = &drmdpy->config->base;
if (num_configs)
*num_configs = 1;
}
 
return configs;
}
 
static int
drm_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_USE_NATIVE_BUFFER:
case NATIVE_PARAM_PRESERVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
drm_display_destroy(struct native_display *ndpy)
{
struct drm_display *drmdpy = drm_display(ndpy);
 
FREE(drmdpy->config);
 
drm_display_fini_modeset(&drmdpy->base);
 
/* gbm owns screen */
ndpy->screen = NULL;
ndpy_uninit(ndpy);
 
FREE(drmdpy->device_name);
 
if (drmdpy->own_gbm) {
gbm_device_destroy(&drmdpy->gbmdrm->base.base);
if (drmdpy->fd >= 0)
close(drmdpy->fd);
}
 
FREE(drmdpy);
}
 
static struct native_display_buffer drm_display_buffer = {
/* use the helpers */
drm_display_import_native_buffer,
drm_display_export_native_buffer
};
 
static char *
drm_get_device_name(int fd)
{
char *device_name = NULL;
#ifdef HAVE_LIBUDEV
struct udev *udev;
struct udev_device *device;
struct stat buf;
const char *tmp;
 
udev = udev_new();
if (fstat(fd, &buf) < 0) {
_eglLog(_EGL_WARNING, "failed to stat fd %d", fd);
goto outudev;
}
 
device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
if (device == NULL) {
_eglLog(_EGL_WARNING,
"could not create udev device for fd %d", fd);
goto outdevice;
}
 
tmp = udev_device_get_devnode(device);
if (!tmp)
goto outdevice;
device_name = strdup(tmp);
 
outdevice:
udev_device_unref(device);
outudev:
udev_unref(udev);
 
#endif
return device_name;
}
 
#ifdef HAVE_WAYLAND_BACKEND
 
static int
drm_display_authenticate(void *user_data, uint32_t magic)
{
struct native_display *ndpy = user_data;
struct drm_display *drmdpy = drm_display(ndpy);
 
return drmAuthMagic(drmdpy->fd, magic);
}
 
static struct wayland_drm_callbacks wl_drm_callbacks = {
drm_display_authenticate,
egl_g3d_wl_drm_helper_reference_buffer,
egl_g3d_wl_drm_helper_unreference_buffer
};
 
static boolean
drm_display_bind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct drm_display *drmdpy = drm_display(ndpy);
 
if (drmdpy->wl_server_drm)
return FALSE;
 
drmdpy->wl_server_drm = wayland_drm_init(wl_dpy,
drmdpy->device_name,
&wl_drm_callbacks, ndpy, 0);
 
if (!drmdpy->wl_server_drm)
return FALSE;
return TRUE;
}
 
static boolean
drm_display_unbind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct drm_display *drmdpy = drm_display(ndpy);
 
if (!drmdpy->wl_server_drm)
return FALSE;
 
wayland_drm_uninit(drmdpy->wl_server_drm);
drmdpy->wl_server_drm = NULL;
 
return TRUE;
}
 
static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = {
drm_display_bind_wayland_display,
drm_display_unbind_wayland_display,
egl_g3d_wl_drm_common_wl_buffer_get_resource,
egl_g3d_wl_drm_common_query_buffer
};
 
#endif /* HAVE_WAYLAND_BACKEND */
 
static struct native_surface *
drm_create_pixmap_surface(struct native_display *ndpy,
EGLNativePixmapType pix,
const struct native_config *nconf)
{
struct gbm_gallium_drm_bo *bo = (void *) pix;
 
return drm_display_create_surface_from_resource(ndpy, bo->resource);
}
 
static boolean
drm_display_init_screen(struct native_display *ndpy)
{
return TRUE;
}
 
static struct native_display *
drm_create_display(struct gbm_gallium_drm_device *gbmdrm, int own_gbm,
const struct native_event_handler *event_handler)
{
struct drm_display *drmdpy;
 
drmdpy = CALLOC_STRUCT(drm_display);
if (!drmdpy)
return NULL;
 
drmdpy->gbmdrm = gbmdrm;
drmdpy->own_gbm = own_gbm;
drmdpy->fd = gbmdrm->base.base.fd;
drmdpy->device_name = drm_get_device_name(drmdpy->fd);
 
gbmdrm->lookup_egl_image = (struct pipe_resource *(*)(void *, void *))
event_handler->lookup_egl_image;
gbmdrm->lookup_egl_image_data = &drmdpy->base;
 
drmdpy->event_handler = event_handler;
 
drmdpy->base.screen = gbmdrm->screen;
 
drmdpy->base.init_screen = drm_display_init_screen;
drmdpy->base.destroy = drm_display_destroy;
drmdpy->base.get_param = drm_display_get_param;
drmdpy->base.get_configs = drm_display_get_configs;
 
drmdpy->base.create_pixmap_surface = drm_create_pixmap_surface;
 
drmdpy->base.buffer = &drm_display_buffer;
#ifdef HAVE_WAYLAND_BACKEND
if (drmdpy->device_name)
drmdpy->base.wayland_bufmgr = &drm_display_wayland_bufmgr;
#endif
drm_display_init_modeset(&drmdpy->base);
 
return &drmdpy->base;
}
 
static const struct native_event_handler *drm_event_handler;
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
struct gbm_gallium_drm_device *gbm;
int fd;
int own_gbm = 0;
 
gbm = dpy;
 
if (gbm == NULL) {
const char *device_name="/dev/dri/card0";
#ifdef O_CLOEXEC
fd = open(device_name, O_RDWR | O_CLOEXEC);
if (fd == -1 && errno == EINVAL)
#endif
{
fd = open(device_name, O_RDWR);
if (fd != -1)
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
}
/* FIXME: Use an internal constructor to create a gbm
* device with gallium backend directly, without setenv */
setenv("GBM_BACKEND", "gbm_gallium_drm.so", 1);
gbm = gbm_gallium_drm_device(gbm_create_device(fd));
own_gbm = 1;
}
 
if (gbm == NULL)
return NULL;
if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 ||
gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM) {
if (own_gbm)
gbm_device_destroy(&gbm->base.base);
return NULL;
}
 
return drm_create_display(gbm, own_gbm, drm_event_handler);
}
 
static const struct native_platform drm_platform = {
"DRM", /* name */
native_create_display
};
 
const struct native_platform *
native_get_drm_platform(const struct native_event_handler *event_handler)
{
drm_event_handler = event_handler;
return &drm_platform;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/drm/native_drm.h
0,0 → 1,164
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _NATIVE_DRM_H_
#define _NATIVE_DRM_H_
 
#include <xf86drm.h>
#include <xf86drmMode.h>
 
#include "pipe/p_compiler.h"
#include "util/u_format.h"
#include "pipe/p_state.h"
#include "state_tracker/drm_driver.h"
 
#include "common/native.h"
#include "common/native_helper.h"
 
#ifdef HAVE_WAYLAND_BACKEND
#include "common/native_wayland_drm_bufmgr_helper.h"
#endif
 
#include "gbm_gallium_drmint.h"
 
struct drm_config;
struct drm_crtc;
struct drm_connector;
struct drm_mode;
struct drm_surface;
 
struct drm_display {
struct native_display base;
 
const struct native_event_handler *event_handler;
 
struct gbm_gallium_drm_device *gbmdrm;
int own_gbm;
int fd;
char *device_name;
struct drm_config *config;
 
/* for modesetting */
drmModeResPtr resources;
struct drm_connector *connectors;
int num_connectors;
 
struct drm_surface **shown_surfaces;
/* save the original settings of the CRTCs */
struct drm_crtc *saved_crtcs;
 
#ifdef HAVE_WAYLAND_BACKEND
struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
#endif
};
 
struct drm_config {
struct native_config base;
};
 
struct drm_crtc {
drmModeCrtcPtr crtc;
uint32_t connectors[32];
int num_connectors;
};
 
struct drm_framebuffer {
struct pipe_resource *texture;
boolean is_passive;
 
uint32_t buffer_id;
};
 
struct drm_surface {
struct native_surface base;
struct drm_display *drmdpy;
 
struct resource_surface *rsurf;
enum pipe_format color_format;
int width, height;
 
unsigned int sequence_number;
struct drm_framebuffer front_fb, back_fb;
 
boolean is_shown;
struct drm_crtc current_crtc;
 
boolean have_pageflip;
};
 
struct drm_connector {
struct native_connector base;
 
uint32_t connector_id;
drmModeConnectorPtr connector;
struct drm_mode *drm_modes;
int num_modes;
};
 
struct drm_mode {
struct native_mode base;
drmModeModeInfo mode;
};
 
static INLINE struct drm_display *
drm_display(const struct native_display *ndpy)
{
return (struct drm_display *) ndpy;
}
 
static INLINE struct drm_config *
drm_config(const struct native_config *nconf)
{
return (struct drm_config *) nconf;
}
 
static INLINE struct drm_surface *
drm_surface(const struct native_surface *nsurf)
{
return (struct drm_surface *) nsurf;
}
 
static INLINE struct drm_connector *
drm_connector(const struct native_connector *nconn)
{
return (struct drm_connector *) nconn;
}
 
static INLINE struct drm_mode *
drm_mode(const struct native_mode *nmode)
{
return (struct drm_mode *) nmode;
}
 
boolean
drm_display_init_modeset(struct native_display *ndpy);
 
void
drm_display_fini_modeset(struct native_display *ndpy);
 
struct native_surface *
drm_display_create_surface_from_resource(struct native_display *ndpy,
struct pipe_resource *resource);
 
#endif /* _NATIVE_DRM_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
0,0 → 1,552
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
/**
* Considering fbdev as an in-kernel window system,
*
* - opening a device opens a connection
* - there is only one window: the framebuffer
* - fb_var_screeninfo decides window position, size, and even color format
* - there is no pixmap
*
* Now EGL is built on top of this window system. So we should have
*
* - the fd as the handle of the native display
* - reject all but one native window: NULL
* - no pixmap support
*/
 
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
 
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_pointer.h"
 
#include "common/native.h"
#include "common/native_helper.h"
#include "fbdev/fbdev_sw_winsys.h"
 
struct fbdev_display {
struct native_display base;
 
int fd;
const struct native_event_handler *event_handler;
 
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo config_vinfo;
struct native_config config;
 
boolean assume_fixed_vinfo;
};
 
struct fbdev_surface {
struct native_surface base;
 
struct fbdev_display *fbdpy;
struct resource_surface *rsurf;
int width, height;
 
unsigned int sequence_number;
 
struct fbdev_sw_drawable drawable;
};
 
static INLINE struct fbdev_display *
fbdev_display(const struct native_display *ndpy)
{
return (struct fbdev_display *) ndpy;
}
 
static INLINE struct fbdev_surface *
fbdev_surface(const struct native_surface *nsurf)
{
return (struct fbdev_surface *) nsurf;
}
 
static boolean
fbdev_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
 
if (!resource_surface_add_resources(fbsurf->rsurf, attachment_mask))
return FALSE;
if (textures)
resource_surface_get_resources(fbsurf->rsurf, textures, attachment_mask);
 
if (seq_num)
*seq_num = fbsurf->sequence_number;
if (width)
*width = fbsurf->width;
if (height)
*height = fbsurf->height;
 
return TRUE;
}
 
static enum pipe_format
vinfo_to_format(const struct fb_var_screeninfo *vinfo)
{
enum pipe_format format = PIPE_FORMAT_NONE;
 
/* should also check channel offsets... */
switch (vinfo->bits_per_pixel) {
case 32:
if (vinfo->red.length == 8 &&
vinfo->green.length == 8 &&
vinfo->blue.length == 8) {
format = (vinfo->transp.length == 8) ?
PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
}
break;
case 16:
if (vinfo->red.length == 5 &&
vinfo->green.length == 6 &&
vinfo->blue.length == 5 &&
vinfo->transp.length == 0)
format = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
break;
}
 
return format;
}
 
static boolean
fbdev_surface_update_drawable(struct native_surface *nsurf,
const struct fb_var_screeninfo *vinfo)
{
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
unsigned x, y, width, height;
 
x = vinfo->xoffset;
y = vinfo->yoffset;
width = MIN2(vinfo->xres, fbsurf->width);
height = MIN2(vinfo->yres, fbsurf->height);
 
/* sanitize the values */
if (x + width > vinfo->xres_virtual) {
if (x > vinfo->xres_virtual)
width = 0;
else
width = vinfo->xres_virtual - x;
}
if (y + height > vinfo->yres_virtual) {
if (y > vinfo->yres_virtual)
height = 0;
else
height = vinfo->yres_virtual - y;
}
 
fbsurf->drawable.format = vinfo_to_format(vinfo);
fbsurf->drawable.x = vinfo->xoffset;
fbsurf->drawable.y = vinfo->yoffset;
fbsurf->drawable.width = vinfo->xres;
fbsurf->drawable.height = vinfo->yres;
 
return (fbsurf->drawable.format != PIPE_FORMAT_NONE &&
fbsurf->drawable.width &&
fbsurf->drawable.height);
}
 
static boolean
fbdev_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
struct fbdev_display *fbdpy = fbsurf->fbdpy;
boolean ret = FALSE;
 
if (ctrl->swap_interval)
return FALSE;
if (ctrl->natt != NATIVE_ATTACHMENT_BACK_LEFT)
return FALSE;
 
if (!fbdpy->assume_fixed_vinfo) {
struct fb_var_screeninfo vinfo;
 
memset(&vinfo, 0, sizeof(vinfo));
if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo))
return FALSE;
 
/* present the surface */
if (fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
ret = resource_surface_present(fbsurf->rsurf,
ctrl->natt, (void *) &fbsurf->drawable);
}
 
fbsurf->width = vinfo.xres;
fbsurf->height = vinfo.yres;
 
if (resource_surface_set_size(fbsurf->rsurf,
fbsurf->width, fbsurf->height)) {
/* surface resized */
fbsurf->sequence_number++;
fbdpy->event_handler->invalid_surface(&fbdpy->base,
&fbsurf->base, fbsurf->sequence_number);
}
}
else {
/* the drawable never changes */
ret = resource_surface_present(fbsurf->rsurf,
ctrl->natt, (void *) &fbsurf->drawable);
}
 
return ret;
}
 
static void
fbdev_surface_wait(struct native_surface *nsurf)
{
/* no-op */
}
 
static void
fbdev_surface_destroy(struct native_surface *nsurf)
{
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
 
resource_surface_destroy(fbsurf->rsurf);
FREE(fbsurf);
}
 
static struct native_surface *
fbdev_display_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
struct fbdev_surface *fbsurf;
struct fb_var_screeninfo vinfo;
 
/* there is only one native window: NULL */
if (win)
return NULL;
 
fbsurf = CALLOC_STRUCT(fbdev_surface);
if (!fbsurf)
return NULL;
 
fbsurf->fbdpy = fbdpy;
 
/* get current vinfo */
if (fbdpy->assume_fixed_vinfo) {
vinfo = fbdpy->config_vinfo;
}
else {
memset(&vinfo, 0, sizeof(vinfo));
if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo)) {
FREE(fbsurf);
return NULL;
}
}
 
fbsurf->width = vinfo.xres;
fbsurf->height = vinfo.yres;
 
if (!fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
FREE(fbsurf);
return NULL;
}
 
fbsurf->rsurf = resource_surface_create(fbdpy->base.screen,
nconf->color_format,
PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DISPLAY_TARGET);
if (!fbsurf->rsurf) {
FREE(fbsurf);
return NULL;
}
 
resource_surface_set_size(fbsurf->rsurf, fbsurf->width, fbsurf->height);
 
fbsurf->base.destroy = fbdev_surface_destroy;
fbsurf->base.present = fbdev_surface_present;
fbsurf->base.validate = fbdev_surface_validate;
fbsurf->base.wait = fbdev_surface_wait;
 
return &fbsurf->base;
}
 
static struct native_surface *
fbdev_display_create_scanout_surface(struct native_display *ndpy,
const struct native_config *nconf,
uint width, uint height)
{
return fbdev_display_create_window_surface(ndpy,
(EGLNativeWindowType) NULL, nconf);
}
 
static boolean
fbdev_display_program(struct native_display *ndpy, int crtc_idx,
struct native_surface *nsurf, uint x, uint y,
const struct native_connector **nconns, int num_nconns,
const struct native_mode *nmode)
{
return TRUE;
}
 
static const struct native_mode **
fbdev_display_get_modes(struct native_display *ndpy,
const struct native_connector *nconn,
int *num_modes)
{
static struct native_mode mode;
const struct native_mode **modes;
 
if (!mode.desc) {
struct fbdev_display *fbdpy = fbdev_display(ndpy);
mode.desc = "Current Mode";
mode.width = fbdpy->config_vinfo.xres;
mode.height = fbdpy->config_vinfo.yres;
mode.refresh_rate = 60 * 1000; /* dummy */
}
 
modes = MALLOC(sizeof(*modes));
if (modes) {
modes[0] = &mode;
if (num_modes)
*num_modes = 1;
}
 
return modes;
}
 
static const struct native_connector **
fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
int *num_crtc)
{
static struct native_connector connector;
const struct native_connector **connectors;
 
connectors = MALLOC(sizeof(*connectors));
if (connectors) {
connectors[0] = &connector;
if (num_connectors)
*num_connectors = 1;
}
 
return connectors;
}
 
/* remove modeset support one day! */
static const struct native_display_modeset fbdev_display_modeset = {
.get_connectors = fbdev_display_get_connectors,
.get_modes = fbdev_display_get_modes,
.create_scanout_surface = fbdev_display_create_scanout_surface,
.program = fbdev_display_program
};
 
static const struct native_config **
fbdev_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
const struct native_config **configs;
 
configs = MALLOC(sizeof(*configs));
if (configs) {
configs[0] = &fbdpy->config;
if (num_configs)
*num_configs = 1;
}
 
return configs;
}
 
static int
fbdev_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_PRESERVE_BUFFER:
val = 1;
break;
case NATIVE_PARAM_USE_NATIVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
fbdev_display_destroy(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
ndpy_uninit(&fbdpy->base);
close(fbdpy->fd);
FREE(fbdpy);
}
 
static boolean
fbdev_display_init_screen(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
struct sw_winsys *ws;
 
ws = fbdev_create_sw_winsys(fbdpy->fd);
if (!ws)
return FALSE;
 
fbdpy->base.screen = fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
if (!fbdpy->base.screen) {
if (ws->destroy)
ws->destroy(ws);
return FALSE;
}
 
if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
fbdpy->config.color_format, PIPE_TEXTURE_2D, 0,
PIPE_BIND_RENDER_TARGET)) {
fbdpy->base.screen->destroy(fbdpy->base.screen);
fbdpy->base.screen = NULL;
return FALSE;
}
 
return TRUE;
}
 
static boolean
fbdev_display_init_config(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
struct native_config *nconf = &fbdpy->config;
 
if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->config_vinfo))
return FALSE;
 
nconf->color_format = vinfo_to_format(&fbdpy->config_vinfo);
if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
 
nconf->buffer_mask = (1 << NATIVE_ATTACHMENT_BACK_LEFT);
 
nconf->window_bit = TRUE;
 
return TRUE;
}
 
static struct native_display *
fbdev_display_create(int fd, const struct native_event_handler *event_handler)
{
struct fbdev_display *fbdpy;
 
fbdpy = CALLOC_STRUCT(fbdev_display);
if (!fbdpy)
return NULL;
 
fbdpy->fd = fd;
fbdpy->event_handler = event_handler;
 
if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo))
goto fail;
 
if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR ||
fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS)
goto fail;
 
if (!fbdev_display_init_config(&fbdpy->base))
goto fail;
 
fbdpy->assume_fixed_vinfo = TRUE;
 
fbdpy->base.init_screen = fbdev_display_init_screen;
fbdpy->base.destroy = fbdev_display_destroy;
fbdpy->base.get_param = fbdev_display_get_param;
fbdpy->base.get_configs = fbdev_display_get_configs;
 
fbdpy->base.create_window_surface = fbdev_display_create_window_surface;
 
/* we'd like to remove modeset support one day */
fbdpy->config.scanout_bit = TRUE;
fbdpy->base.modeset = &fbdev_display_modeset;
 
return &fbdpy->base;
 
fail:
FREE(fbdpy);
return NULL;
}
 
static const struct native_event_handler *fbdev_event_handler;
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy;
int fd;
 
/* well, this makes fd 0 being ignored */
if (!dpy) {
const char *device_name="/dev/fb0";
#ifdef O_CLOEXEC
fd = open(device_name, O_RDWR | O_CLOEXEC);
if (fd == -1 && errno == EINVAL)
#endif
{
fd = open(device_name, O_RDWR);
if (fd != -1)
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
}
}
else {
fd = dup((int) pointer_to_intptr(dpy));
}
if (fd < 0)
return NULL;
 
ndpy = fbdev_display_create(fd, fbdev_event_handler);
if (!ndpy)
close(fd);
 
return ndpy;
}
 
static const struct native_platform fbdev_platform = {
"FBDEV", /* name */
native_create_display
};
 
const struct native_platform *
native_get_fbdev_platform(const struct native_event_handler *event_handler)
{
fbdev_event_handler = event_handler;
return &fbdev_platform;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/gdi/native_gdi.c
0,0 → 1,427
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
#include <windows.h>
 
#include "pipe/p_compiler.h"
#include "util/u_memory.h"
#include "util/u_format.h"
#include "util/u_inlines.h"
#include "gdi/gdi_sw_winsys.h"
 
#include "common/native_helper.h"
#include "common/native.h"
 
struct gdi_display {
struct native_display base;
 
HDC hDC;
const struct native_event_handler *event_handler;
 
struct native_config *configs;
int num_configs;
};
 
struct gdi_surface {
struct native_surface base;
 
HWND hWnd;
enum pipe_format color_format;
 
struct gdi_display *gdpy;
 
unsigned int server_stamp;
unsigned int client_stamp;
 
struct resource_surface *rsurf;
};
 
static INLINE struct gdi_display *
gdi_display(const struct native_display *ndpy)
{
return (struct gdi_display *) ndpy;
}
 
static INLINE struct gdi_surface *
gdi_surface(const struct native_surface *nsurf)
{
return (struct gdi_surface *) nsurf;
}
 
/**
* Update the geometry of the surface. This is a slow functions.
*/
static void
gdi_surface_update_geometry(struct native_surface *nsurf)
{
struct gdi_surface *gsurf = gdi_surface(nsurf);
RECT rect;
uint w, h;
 
GetClientRect(gsurf->hWnd, &rect);
w = rect.right - rect.left;
h = rect.bottom - rect.top;
 
if (resource_surface_set_size(gsurf->rsurf, w, h))
gsurf->server_stamp++;
}
 
/**
* Update the buffers of the surface.
*/
static boolean
gdi_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct gdi_surface *gsurf = gdi_surface(nsurf);
 
if (gsurf->client_stamp != gsurf->server_stamp) {
gdi_surface_update_geometry(&gsurf->base);
gsurf->client_stamp = gsurf->server_stamp;
}
 
return resource_surface_add_resources(gsurf->rsurf, buffer_mask);
}
 
/**
* Emulate an invalidate event.
*/
static void
gdi_surface_invalidate(struct native_surface *nsurf)
{
struct gdi_surface *gsurf = gdi_surface(nsurf);
struct gdi_display *gdpy = gsurf->gdpy;
 
gsurf->server_stamp++;
gdpy->event_handler->invalid_surface(&gdpy->base,
&gsurf->base, gsurf->server_stamp);
}
 
static boolean
gdi_surface_flush_frontbuffer(struct native_surface *nsurf)
{
struct gdi_surface *gsurf = gdi_surface(nsurf);
HDC hDC;
boolean ret;
 
hDC = GetDC(gsurf->hWnd);
ret = resource_surface_present(gsurf->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT, (void *) hDC);
ReleaseDC(gsurf->hWnd, hDC);
 
/* force buffers to be updated in next validation call */
gdi_surface_invalidate(&gsurf->base);
 
return ret;
}
 
static boolean
gdi_surface_swap_buffers(struct native_surface *nsurf)
{
struct gdi_surface *gsurf = gdi_surface(nsurf);
HDC hDC;
boolean ret;
 
hDC = GetDC(gsurf->hWnd);
ret = resource_surface_present(gsurf->rsurf,
NATIVE_ATTACHMENT_BACK_LEFT, (void *) hDC);
ReleaseDC(gsurf->hWnd, hDC);
 
resource_surface_swap_buffers(gsurf->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
/* the front/back buffers have been swapped */
gdi_surface_invalidate(&gsurf->base);
 
return ret;
}
 
static boolean
gdi_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
boolean ret;
 
if (ctrl->preserve || ctrl->swap_interval)
return FALSE;
 
switch (ctrl->natt) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
ret = gdi_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
ret = gdi_surface_swap_buffers(nsurf);
break;
default:
ret = FALSE;
break;
}
 
return ret;
}
 
static boolean
gdi_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct gdi_surface *gsurf = gdi_surface(nsurf);
uint w, h;
 
if (!gdi_surface_update_buffers(&gsurf->base, attachment_mask))
return FALSE;
 
if (seq_num)
*seq_num = gsurf->client_stamp;
 
if (textures)
resource_surface_get_resources(gsurf->rsurf, textures, attachment_mask);
 
resource_surface_get_size(gsurf->rsurf, &w, &h);
if (width)
*width = w;
if (height)
*height = h;
 
return TRUE;
}
 
static void
gdi_surface_wait(struct native_surface *nsurf)
{
/* no-op */
}
 
static void
gdi_surface_destroy(struct native_surface *nsurf)
{
struct gdi_surface *gsurf = gdi_surface(nsurf);
 
resource_surface_destroy(gsurf->rsurf);
FREE(gsurf);
}
 
static struct native_surface *
gdi_display_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct gdi_display *gdpy = gdi_display(ndpy);
struct gdi_surface *gsurf;
 
gsurf = CALLOC_STRUCT(gdi_surface);
if (!gsurf)
return NULL;
 
gsurf->gdpy = gdpy;
gsurf->color_format = nconf->color_format;
gsurf->hWnd = (HWND) win;
 
gsurf->rsurf = resource_surface_create(gdpy->base.screen,
gsurf->color_format,
PIPE_BIND_RENDER_TARGET |
PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT);
if (!gsurf->rsurf) {
FREE(gsurf);
return NULL;
}
 
/* initialize the geometry */
gdi_surface_update_geometry(&gsurf->base);
 
gsurf->base.destroy = gdi_surface_destroy;
gsurf->base.present = gdi_surface_present;
gsurf->base.validate = gdi_surface_validate;
gsurf->base.wait = gdi_surface_wait;
 
return &gsurf->base;
}
 
static int
fill_color_formats(struct native_display *ndpy, enum pipe_format formats[8])
{
struct pipe_screen *screen = ndpy->screen;
int i, count = 0;
 
enum pipe_format candidates[] = {
/* 32-bit */
PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_FORMAT_A8R8G8B8_UNORM,
/* 24-bit */
PIPE_FORMAT_B8G8R8X8_UNORM,
PIPE_FORMAT_X8R8G8B8_UNORM,
/* 16-bit */
PIPE_FORMAT_B5G6R5_UNORM
};
 
assert(Elements(candidates) <= 8);
 
for (i = 0; i < Elements(candidates); i++) {
if (screen->is_format_supported(screen, candidates[i],
PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET))
formats[count++] = candidates[i];
}
 
return count;
}
 
static const struct native_config **
gdi_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct gdi_display *gdpy = gdi_display(ndpy);
const struct native_config **configs;
int i;
 
/* first time */
if (!gdpy->configs) {
enum pipe_format formats[8];
int i, count;
 
count = fill_color_formats(&gdpy->base, formats);
 
gdpy->configs = CALLOC(count, sizeof(*gdpy->configs));
if (!gdpy->configs)
return NULL;
 
for (i = 0; i < count; i++) {
struct native_config *nconf = &gdpy->configs[i];
 
nconf->buffer_mask =
(1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
(1 << NATIVE_ATTACHMENT_BACK_LEFT);
nconf->color_format = formats[i];
 
nconf->window_bit = TRUE;
}
 
gdpy->num_configs = count;
}
 
configs = MALLOC(gdpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < gdpy->num_configs; i++)
configs[i] = (const struct native_config *) &gdpy->configs[i];
if (num_configs)
*num_configs = gdpy->num_configs;
}
return configs;
}
 
static int
gdi_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_USE_NATIVE_BUFFER:
/* private buffers are allocated */
val = FALSE;
break;
case NATIVE_PARAM_PRESERVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
gdi_display_destroy(struct native_display *ndpy)
{
struct gdi_display *gdpy = gdi_display(ndpy);
 
FREE(gdpy->configs);
 
ndpy_uninit(ndpy);
 
FREE(gdpy);
}
 
static boolean
gdi_display_init_screen(struct native_display *ndpy)
{
struct gdi_display *gdpy = gdi_display(ndpy);
struct sw_winsys *winsys;
 
winsys = gdi_create_sw_winsys();
if (!winsys)
return FALSE;
 
gdpy->base.screen = gdpy->event_handler->new_sw_screen(&gdpy->base, winsys);
if (!gdpy->base.screen) {
if (winsys->destroy)
winsys->destroy(winsys);
return FALSE;
}
 
return TRUE;
}
 
static struct native_display *
gdi_create_display(HDC hDC, const struct native_event_handler *event_handler)
{
struct gdi_display *gdpy;
 
gdpy = CALLOC_STRUCT(gdi_display);
if (!gdpy)
return NULL;
 
gdpy->hDC = hDC;
gdpy->event_handler = event_handler;
 
gdpy->base.init_screen = gdi_display_init_screen;
gdpy->base.destroy = gdi_display_destroy;
gdpy->base.get_param = gdi_display_get_param;
 
gdpy->base.get_configs = gdi_display_get_configs;
gdpy->base.create_window_surface = gdi_display_create_window_surface;
 
return &gdpy->base;
}
 
static const struct native_event_handler *gdi_event_handler;
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
return gdi_create_display((HDC) dpy, gdi_event_handler);
}
 
static const struct native_platform gdi_platform = {
"GDI", /* name */
native_create_display
};
 
const struct native_platform *
native_get_gdi_platform(const struct native_event_handler *event_handler)
{
gdi_event_handler = event_handler;
return &gdi_platform;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/null/native_null.c
0,0 → 1,189
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2011 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
 
/**
* For NULL window system,
*
* - the only valid native display is EGL_DEFAULT_DISPLAY
* - there is no window or pixmap
*/
 
#include "util/u_memory.h"
#include "null/null_sw_winsys.h"
#include "common/native.h"
 
struct null_display {
struct native_display base;
 
const struct native_event_handler *event_handler;
 
struct native_config *configs;
int num_configs;
};
 
static INLINE struct null_display *
null_display(const struct native_display *ndpy)
{
return (struct null_display *) ndpy;
}
 
static const struct native_config **
null_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct null_display *null = null_display(ndpy);
const struct native_config **configs;
int i;
 
configs = MALLOC(sizeof(*configs) * null->num_configs);
if (configs) {
for (i = 0; i < null->num_configs; i++)
configs[i] = &null->configs[i];
if (num_configs)
*num_configs = null->num_configs;
}
 
return configs;
}
 
static int
null_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
return 0;
}
 
static void
null_display_destroy(struct native_display *ndpy)
{
struct null_display *null = null_display(ndpy);
 
FREE(null->configs);
ndpy_uninit(&null->base);
FREE(null);
}
 
static boolean
null_display_init_config(struct native_display *ndpy)
{
const enum pipe_format color_formats[] = {
PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_FORMAT_B8G8R8X8_UNORM,
PIPE_FORMAT_B5G6R5_UNORM,
PIPE_FORMAT_NONE
};
struct null_display *null = null_display(ndpy);
int i;
 
null->configs = CALLOC(Elements(color_formats) - 1, sizeof(*null->configs));
if (!null->configs)
return FALSE;
 
/* add configs */
for (i = 0; color_formats[i] != PIPE_FORMAT_NONE; i++) {
if (null->base.screen->is_format_supported(null->base.screen,
color_formats[i], PIPE_TEXTURE_2D, 0,
PIPE_BIND_RENDER_TARGET)) {
struct native_config *nconf = &null->configs[null->num_configs];
 
nconf->color_format = color_formats[i];
nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_BACK_LEFT;
null->num_configs++;
}
}
 
return TRUE;
}
 
static boolean
null_display_init_screen(struct native_display *ndpy)
{
struct null_display *null = null_display(ndpy);
struct sw_winsys *ws;
 
ws = null_sw_create();
if (!ws)
return FALSE;
 
null->base.screen = null->event_handler->new_sw_screen(&null->base, ws);
if (!null->base.screen) {
if (ws->destroy)
ws->destroy(ws);
return FALSE;
}
 
if (!null_display_init_config(&null->base)) {
ndpy_uninit(&null->base);
return FALSE;
}
 
return TRUE;
}
 
static struct native_display *
null_display_create(const struct native_event_handler *event_handler)
{
struct null_display *null;
 
null = CALLOC_STRUCT(null_display);
if (!null)
return NULL;
 
null->event_handler = event_handler;
 
null->base.init_screen = null_display_init_screen;
null->base.destroy = null_display_destroy;
null->base.get_param = null_display_get_param;
null->base.get_configs = null_display_get_configs;
 
return &null->base;
}
 
static const struct native_event_handler *null_event_handler;
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy = NULL;
 
/* the only valid display is NULL */
if (!dpy)
ndpy = null_display_create(null_event_handler);
 
return ndpy;
}
 
static const struct native_platform null_platform = {
"NULL", /* name */
native_create_display
};
 
const struct native_platform *
native_get_null_platform(const struct native_event_handler *event_handler)
{
null_event_handler = event_handler;
return &null_platform;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/wayland/native_drm.c
0,0 → 1,332
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include "util/u_memory.h"
#include "util/u_inlines.h"
 
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "state_tracker/drm_driver.h"
 
#include "egllog.h"
#include <errno.h>
 
#include "native_wayland.h"
 
#include <wayland-client.h>
#include "wayland-drm-client-protocol.h"
#include "wayland-egl-priv.h"
 
#include "common/native_wayland_drm_bufmgr_helper.h"
 
#include <xf86drm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
struct wayland_drm_display {
struct wayland_display base;
 
const struct native_event_handler *event_handler;
 
struct wl_drm *wl_drm;
struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
int fd;
char *device_name;
boolean authenticated;
};
 
static INLINE struct wayland_drm_display *
wayland_drm_display(const struct native_display *ndpy)
{
return (struct wayland_drm_display *) ndpy;
}
 
static void
wayland_drm_display_destroy(struct native_display *ndpy)
{
struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
 
if (drmdpy->wl_drm)
wl_drm_destroy(drmdpy->wl_drm);
FREE(drmdpy->device_name);
FREE(drmdpy->base.configs);
if (drmdpy->base.own_dpy)
wl_display_disconnect(drmdpy->base.dpy);
 
ndpy_uninit(ndpy);
 
if (drmdpy->fd)
close(drmdpy->fd);
 
FREE(drmdpy);
}
 
static struct wl_buffer *
wayland_create_drm_buffer(struct wayland_display *display,
struct wayland_surface *surface,
enum native_attachment attachment)
{
struct wayland_drm_display *drmdpy = (struct wayland_drm_display *) display;
struct pipe_screen *screen = drmdpy->base.base.screen;
struct pipe_resource *resource;
struct winsys_handle wsh;
uint width, height;
enum wl_drm_format format;
 
resource = resource_surface_get_single_resource(surface->rsurf, attachment);
resource_surface_get_size(surface->rsurf, &width, &height);
 
wsh.type = DRM_API_HANDLE_TYPE_SHARED;
screen->resource_get_handle(screen, resource, &wsh);
 
pipe_resource_reference(&resource, NULL);
 
switch (surface->color_format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
format = WL_DRM_FORMAT_ARGB8888;
break;
case PIPE_FORMAT_B8G8R8X8_UNORM:
format = WL_DRM_FORMAT_XRGB8888;
break;
default:
return NULL;
break;
}
 
return wl_drm_create_buffer(drmdpy->wl_drm, wsh.handle,
width, height, wsh.stride, format);
}
 
static void
drm_handle_device(void *data, struct wl_drm *drm, const char *device)
{
struct wayland_drm_display *drmdpy = data;
drm_magic_t magic;
 
drmdpy->device_name = strdup(device);
if (!drmdpy->device_name)
return;
 
#ifdef O_CLOEXEC
drmdpy->fd = open(drmdpy->device_name, O_RDWR | O_CLOEXEC);
if (drmdpy->fd == -1 && errno == EINVAL)
#endif
{
drmdpy->fd = open(drmdpy->device_name, O_RDWR);
if (drmdpy->fd != -1)
fcntl(drmdpy->fd, F_SETFD, fcntl(drmdpy->fd, F_GETFD) | FD_CLOEXEC);
}
if (drmdpy->fd == -1) {
_eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)",
drmdpy->device_name, strerror(errno));
return;
}
 
drmGetMagic(drmdpy->fd, &magic);
wl_drm_authenticate(drmdpy->wl_drm, magic);
}
 
static void
drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
{
struct wayland_drm_display *drmdpy = data;
 
switch (format) {
case WL_DRM_FORMAT_ARGB8888:
drmdpy->base.formats |= HAS_ARGB8888;
break;
case WL_DRM_FORMAT_XRGB8888:
drmdpy->base.formats |= HAS_XRGB8888;
break;
}
}
 
static void
drm_handle_authenticated(void *data, struct wl_drm *drm)
{
struct wayland_drm_display *drmdpy = data;
 
drmdpy->authenticated = true;
}
 
static const struct wl_drm_listener drm_listener = {
drm_handle_device,
drm_handle_format,
drm_handle_authenticated
};
 
static void
registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version)
{
struct wayland_drm_display *drmdpy = data;
 
if (strcmp(interface, "wl_drm") == 0) {
drmdpy->wl_drm = wl_registry_bind(registry, name, &wl_drm_interface, 1);
wl_drm_add_listener(drmdpy->wl_drm, &drm_listener, drmdpy);
}
}
 
static const struct wl_registry_listener registry_listener = {
registry_handle_global
};
 
static boolean
wayland_drm_display_init_screen(struct native_display *ndpy)
{
struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
 
drmdpy->base.queue = wl_display_create_queue(drmdpy->base.dpy);
drmdpy->base.registry = wl_display_get_registry(drmdpy->base.dpy);
wl_proxy_set_queue((struct wl_proxy *) drmdpy->base.registry,
drmdpy->base.queue);
wl_registry_add_listener(drmdpy->base.registry, &registry_listener, drmdpy);
if (wayland_roundtrip(&drmdpy->base) < 0 || drmdpy->wl_drm == NULL)
return FALSE;
 
wl_drm_add_listener(drmdpy->wl_drm, &drm_listener, drmdpy);
if (wayland_roundtrip(&drmdpy->base) < 0 || drmdpy->fd == -1)
return FALSE;
 
if (wayland_roundtrip(&drmdpy->base) < 0 || !drmdpy->authenticated)
return FALSE;
 
if (drmdpy->base.formats == 0)
return FALSE;
 
drmdpy->base.base.screen =
drmdpy->event_handler->new_drm_screen(&drmdpy->base.base,
NULL, drmdpy->fd);
if (!drmdpy->base.base.screen) {
_eglLog(_EGL_WARNING, "failed to create DRM screen");
return FALSE;
}
 
return TRUE;
}
 
static struct native_display_buffer wayland_drm_display_buffer = {
/* use the helpers */
drm_display_import_native_buffer,
drm_display_export_native_buffer
};
 
static int
wayland_drm_display_authenticate(void *user_data, uint32_t magic)
{
struct native_display *ndpy = user_data;
struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
boolean current_authenticate, authenticated;
 
current_authenticate = drmdpy->authenticated;
 
wl_drm_authenticate(drmdpy->wl_drm, magic);
wl_display_roundtrip(drmdpy->base.dpy);
authenticated = drmdpy->authenticated;
 
drmdpy->authenticated = current_authenticate;
 
return authenticated ? 0 : -1;
}
 
static struct wayland_drm_callbacks wl_drm_callbacks = {
wayland_drm_display_authenticate,
egl_g3d_wl_drm_helper_reference_buffer,
egl_g3d_wl_drm_helper_unreference_buffer
};
 
static boolean
wayland_drm_display_bind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
 
if (drmdpy->wl_server_drm)
return FALSE;
 
drmdpy->wl_server_drm =
wayland_drm_init(wl_dpy, drmdpy->device_name,
&wl_drm_callbacks, ndpy, 0);
 
if (!drmdpy->wl_server_drm)
return FALSE;
return TRUE;
}
 
static boolean
wayland_drm_display_unbind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy);
 
if (!drmdpy->wl_server_drm)
return FALSE;
 
wayland_drm_uninit(drmdpy->wl_server_drm);
drmdpy->wl_server_drm = NULL;
 
return TRUE;
}
 
static struct native_display_wayland_bufmgr wayland_drm_display_wayland_bufmgr = {
wayland_drm_display_bind_wayland_display,
wayland_drm_display_unbind_wayland_display,
egl_g3d_wl_drm_common_wl_buffer_get_resource,
egl_g3d_wl_drm_common_query_buffer
};
 
 
struct wayland_display *
wayland_create_drm_display(struct wl_display *dpy,
const struct native_event_handler *event_handler)
{
struct wayland_drm_display *drmdpy;
 
drmdpy = CALLOC_STRUCT(wayland_drm_display);
if (!drmdpy)
return NULL;
 
drmdpy->event_handler = event_handler;
 
drmdpy->base.dpy = dpy;
if (!drmdpy->base.dpy) {
wayland_drm_display_destroy(&drmdpy->base.base);
return NULL;
}
 
drmdpy->base.base.init_screen = wayland_drm_display_init_screen;
drmdpy->base.base.destroy = wayland_drm_display_destroy;
drmdpy->base.base.buffer = &wayland_drm_display_buffer;
drmdpy->base.base.wayland_bufmgr = &wayland_drm_display_wayland_bufmgr;
 
drmdpy->base.create_buffer = wayland_create_drm_buffer;
 
return &drmdpy->base;
}
 
/* vim: set sw=3 ts=8 sts=3 expandtab: */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/wayland/native_shm.c
0,0 → 1,209
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include "util/u_memory.h"
#include "util/u_inlines.h"
 
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
 
#include "sw/wayland/wayland_sw_winsys.h"
 
#include "egllog.h"
 
#include "native_wayland.h"
 
#include <wayland-client.h>
#include "wayland-egl-priv.h"
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
struct wayland_shm_display {
struct wayland_display base;
 
const struct native_event_handler *event_handler;
struct wl_shm *wl_shm;
};
 
static INLINE struct wayland_shm_display *
wayland_shm_display(const struct native_display *ndpy)
{
return (struct wayland_shm_display *) ndpy;
}
 
 
static void
wayland_shm_display_destroy(struct native_display *ndpy)
{
struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy);
 
FREE(shmdpy->base.configs);
if (shmdpy->base.own_dpy)
wl_display_disconnect(shmdpy->base.dpy);
 
ndpy_uninit(ndpy);
 
FREE(shmdpy);
}
 
static struct wl_buffer *
wayland_create_shm_buffer(struct wayland_display *display,
struct wayland_surface *surface,
enum native_attachment attachment)
{
struct wayland_shm_display *shmdpy = (struct wayland_shm_display *) display;
struct pipe_screen *screen = shmdpy->base.base.screen;
struct pipe_resource *resource;
struct winsys_handle wsh;
uint width, height;
enum wl_shm_format format;
struct wl_buffer *buffer;
struct wl_shm_pool *pool;
 
resource = resource_surface_get_single_resource(surface->rsurf, attachment);
resource_surface_get_size(surface->rsurf, &width, &height);
 
screen->resource_get_handle(screen, resource, &wsh);
 
pipe_resource_reference(&resource, NULL);
 
switch (surface->color_format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
format = WL_SHM_FORMAT_ARGB8888;
break;
case PIPE_FORMAT_B8G8R8X8_UNORM:
format = WL_SHM_FORMAT_XRGB8888;
break;
default:
return NULL;
break;
}
 
pool = wl_shm_create_pool(shmdpy->wl_shm, wsh.fd, wsh.size);
buffer = wl_shm_pool_create_buffer(pool, 0, width, height,
wsh.stride, format);
wl_shm_pool_destroy(pool);
 
return buffer;
}
 
static void
shm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
{
struct wayland_shm_display *shmdpy = data;
 
switch (format) {
case WL_SHM_FORMAT_ARGB8888:
shmdpy->base.formats |= HAS_ARGB8888;
break;
case WL_SHM_FORMAT_XRGB8888:
shmdpy->base.formats |= HAS_XRGB8888;
break;
}
}
 
static const struct wl_shm_listener shm_listener = {
shm_handle_format
};
 
static void
registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version)
{
struct wayland_shm_display *shmdpy = data;
 
if (strcmp(interface, "wl_shm") == 0) {
shmdpy->wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
wl_shm_add_listener(shmdpy->wl_shm, &shm_listener, shmdpy);
}
}
 
static const struct wl_registry_listener registry_listener = {
registry_handle_global
};
 
static boolean
wayland_shm_display_init_screen(struct native_display *ndpy)
{
struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy);
struct sw_winsys *winsys = NULL;
 
shmdpy->base.queue = wl_display_create_queue(shmdpy->base.dpy);
shmdpy->base.registry = wl_display_get_registry(shmdpy->base.dpy);
wl_proxy_set_queue((struct wl_proxy *) shmdpy->base.registry,
shmdpy->base.queue);
wl_registry_add_listener(shmdpy->base.registry, &registry_listener, shmdpy);
if (wayland_roundtrip(&shmdpy->base) < 0 || shmdpy->wl_shm == NULL)
return FALSE;
 
if (shmdpy->base.formats == 0)
wayland_roundtrip(&shmdpy->base);
if (shmdpy->base.formats == 0)
return FALSE;
 
winsys = wayland_create_sw_winsys(shmdpy->base.dpy);
if (!winsys)
return FALSE;
 
shmdpy->base.base.screen =
shmdpy->event_handler->new_sw_screen(&shmdpy->base.base, winsys);
 
if (!shmdpy->base.base.screen) {
_eglLog(_EGL_WARNING, "failed to create shm screen");
return FALSE;
}
 
return TRUE;
}
 
struct wayland_display *
wayland_create_shm_display(struct wl_display *dpy,
const struct native_event_handler *event_handler)
{
struct wayland_shm_display *shmdpy;
 
shmdpy = CALLOC_STRUCT(wayland_shm_display);
if (!shmdpy)
return NULL;
 
shmdpy->event_handler = event_handler;
 
shmdpy->base.dpy = dpy;
if (!shmdpy->base.dpy) {
wayland_shm_display_destroy(&shmdpy->base.base);
return NULL;
}
 
shmdpy->base.base.init_screen = wayland_shm_display_init_screen;
shmdpy->base.base.destroy = wayland_shm_display_destroy;
shmdpy->base.create_buffer = wayland_create_shm_buffer;
 
return &shmdpy->base;
}
 
/* vim: set sw=3 ts=8 sts=3 expandtab: */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/wayland/native_wayland.c
0,0 → 1,461
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include "util/u_memory.h"
#include "util/u_inlines.h"
 
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "state_tracker/drm_driver.h"
#include "egllog.h"
 
#include "native_wayland.h"
 
static void
sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
{
int *done = data;
 
*done = 1;
wl_callback_destroy(callback);
}
 
static const struct wl_callback_listener sync_listener = {
sync_callback
};
 
int
wayland_roundtrip(struct wayland_display *display)
{
struct wl_callback *callback;
int done = 0, ret = 0;
 
callback = wl_display_sync(display->dpy);
wl_callback_add_listener(callback, &sync_listener, &done);
wl_proxy_set_queue((struct wl_proxy *) callback, display->queue);
while (ret != -1 && !done)
ret = wl_display_dispatch_queue(display->dpy, display->queue);
 
if (!done)
wl_callback_destroy(callback);
 
return ret;
}
 
static const struct native_event_handler *wayland_event_handler;
 
const static struct {
enum pipe_format format;
enum wayland_format_flag flag;
} wayland_formats[] = {
{ PIPE_FORMAT_B8G8R8A8_UNORM, HAS_ARGB8888 },
{ PIPE_FORMAT_B8G8R8X8_UNORM, HAS_XRGB8888 },
};
 
static const struct native_config **
wayland_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct wayland_display *display = wayland_display(ndpy);
const struct native_config **configs;
int i;
 
if (!display->configs) {
struct native_config *nconf;
 
display->num_configs = 0;
display->configs = CALLOC(Elements(wayland_formats),
sizeof(*display->configs));
if (!display->configs)
return NULL;
 
for (i = 0; i < Elements(wayland_formats); ++i) {
if (!(display->formats & wayland_formats[i].flag))
continue;
 
nconf = &display->configs[display->num_configs].base;
nconf->buffer_mask =
(1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
(1 << NATIVE_ATTACHMENT_BACK_LEFT);
nconf->window_bit = TRUE;
nconf->color_format = wayland_formats[i].format;
display->num_configs++;
}
}
 
configs = MALLOC(display->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < display->num_configs; ++i)
configs[i] = &display->configs[i].base;
if (num_configs)
*num_configs = display->num_configs;
}
 
return configs;
}
 
static int
wayland_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_PREMULTIPLIED_ALPHA:
val = 1;
break;
case NATIVE_PARAM_USE_NATIVE_BUFFER:
case NATIVE_PARAM_PRESERVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
wayland_release_pending_resource(void *data,
struct wl_callback *callback,
uint32_t time)
{
struct wayland_surface *surface = data;
 
wl_callback_destroy(callback);
 
/* FIXME: print internal error */
if (!surface->pending_resource)
return;
 
pipe_resource_reference(&surface->pending_resource, NULL);
}
 
static const struct wl_callback_listener release_buffer_listener = {
wayland_release_pending_resource
};
 
static void
wayland_window_surface_handle_resize(struct wayland_surface *surface)
{
struct wayland_display *display = surface->display;
struct pipe_resource *front_resource;
const enum native_attachment front_natt = NATIVE_ATTACHMENT_FRONT_LEFT;
int i;
 
front_resource = resource_surface_get_single_resource(surface->rsurf,
front_natt);
if (resource_surface_set_size(surface->rsurf,
surface->win->width, surface->win->height)) {
 
if (surface->pending_resource)
wayland_roundtrip(display);
 
if (front_resource) {
struct wl_callback *callback;
 
surface->pending_resource = front_resource;
front_resource = NULL;
 
callback = wl_display_sync(display->dpy);
wl_callback_add_listener(callback, &release_buffer_listener, surface);
wl_proxy_set_queue((struct wl_proxy *) callback, display->queue);
}
 
for (i = 0; i < WL_BUFFER_COUNT; ++i) {
if (surface->buffer[i])
wl_buffer_destroy(surface->buffer[i]);
surface->buffer[i] = NULL;
}
 
surface->dx = surface->win->dx;
surface->dy = surface->win->dy;
}
pipe_resource_reference(&front_resource, NULL);
}
 
static boolean
wayland_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct wayland_surface *surface = wayland_surface(nsurf);
 
if (surface->type == WL_WINDOW_SURFACE)
wayland_window_surface_handle_resize(surface);
 
if (!resource_surface_add_resources(surface->rsurf, attachment_mask |
surface->attachment_mask))
return FALSE;
 
if (textures)
resource_surface_get_resources(surface->rsurf, textures, attachment_mask);
 
if (seq_num)
*seq_num = surface->sequence_number;
 
resource_surface_get_size(surface->rsurf, (uint *) width, (uint *) height);
 
return TRUE;
}
 
static void
wayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
{
struct wayland_surface *surface = data;
 
surface->frame_callback = NULL;
 
wl_callback_destroy(callback);
}
 
static const struct wl_callback_listener frame_listener = {
wayland_frame_callback
};
 
static INLINE void
wayland_buffers_swap(struct wl_buffer **buffer,
enum wayland_buffer_type buf1,
enum wayland_buffer_type buf2)
{
struct wl_buffer *tmp = buffer[buf1];
buffer[buf1] = buffer[buf2];
buffer[buf2] = tmp;
}
 
static boolean
wayland_surface_swap_buffers(struct native_surface *nsurf)
{
struct wayland_surface *surface = wayland_surface(nsurf);
struct wayland_display *display = surface->display;
int ret = 0;
 
while (surface->frame_callback && ret != -1)
ret = wl_display_dispatch_queue(display->dpy, display->queue);
if (ret == -1)
return EGL_FALSE;
 
surface->frame_callback = wl_surface_frame(surface->win->surface);
wl_callback_add_listener(surface->frame_callback, &frame_listener, surface);
wl_proxy_set_queue((struct wl_proxy *) surface->frame_callback,
display->queue);
 
if (surface->type == WL_WINDOW_SURFACE) {
resource_surface_swap_buffers(surface->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT,
NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
 
wayland_buffers_swap(surface->buffer, WL_BUFFER_FRONT, WL_BUFFER_BACK);
 
if (surface->buffer[WL_BUFFER_FRONT] == NULL)
surface->buffer[WL_BUFFER_FRONT] =
display->create_buffer(display, surface,
NATIVE_ATTACHMENT_FRONT_LEFT);
 
wl_surface_attach(surface->win->surface, surface->buffer[WL_BUFFER_FRONT],
surface->dx, surface->dy);
 
resource_surface_get_size(surface->rsurf,
(uint *) &surface->win->attached_width,
(uint *) &surface->win->attached_height);
surface->dx = 0;
surface->dy = 0;
}
 
surface->sequence_number++;
wayland_event_handler->invalid_surface(&display->base,
&surface->base,
surface->sequence_number);
 
return TRUE;
}
 
static boolean
wayland_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
struct wayland_surface *surface = wayland_surface(nsurf);
uint width, height;
boolean ret;
 
if (ctrl->preserve || ctrl->swap_interval)
return FALSE;
 
/* force buffers to be re-created if they will be presented differently */
if (surface->premultiplied_alpha != ctrl->premultiplied_alpha) {
enum wayland_buffer_type buffer;
 
for (buffer = 0; buffer < WL_BUFFER_COUNT; ++buffer) {
if (surface->buffer[buffer]) {
wl_buffer_destroy(surface->buffer[buffer]);
surface->buffer[buffer] = NULL;
}
}
 
surface->premultiplied_alpha = ctrl->premultiplied_alpha;
}
 
switch (ctrl->natt) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
ret = TRUE;
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
ret = wayland_surface_swap_buffers(nsurf);
break;
default:
ret = FALSE;
break;
}
 
if (surface->type == WL_WINDOW_SURFACE) {
resource_surface_get_size(surface->rsurf, &width, &height);
wl_surface_damage(surface->win->surface, 0, 0, width, height);
wl_surface_commit(surface->win->surface);
}
 
return ret;
}
 
static void
wayland_surface_wait(struct native_surface *nsurf)
{
/* no-op */
}
 
static void
wayland_surface_destroy(struct native_surface *nsurf)
{
struct wayland_surface *surface = wayland_surface(nsurf);
enum wayland_buffer_type buffer;
 
for (buffer = 0; buffer < WL_BUFFER_COUNT; ++buffer) {
if (surface->buffer[buffer])
wl_buffer_destroy(surface->buffer[buffer]);
}
 
if (surface->frame_callback)
wl_callback_destroy(surface->frame_callback);
 
resource_surface_destroy(surface->rsurf);
FREE(surface);
}
 
 
static struct native_surface *
wayland_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct wayland_display *display = wayland_display(ndpy);
struct wayland_config *config = wayland_config(nconf);
struct wayland_surface *surface;
uint bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT;
 
surface = CALLOC_STRUCT(wayland_surface);
if (!surface)
return NULL;
 
surface->display = display;
surface->color_format = config->base.color_format;
 
surface->win = (struct wl_egl_window *) win;
 
surface->pending_resource = NULL;
surface->frame_callback = NULL;
surface->type = WL_WINDOW_SURFACE;
 
surface->buffer[WL_BUFFER_FRONT] = NULL;
surface->buffer[WL_BUFFER_BACK] = NULL;
surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
(1 << NATIVE_ATTACHMENT_BACK_LEFT);
 
surface->rsurf = resource_surface_create(display->base.screen,
surface->color_format, bind);
 
if (!surface->rsurf) {
FREE(surface);
return NULL;
}
 
surface->base.destroy = wayland_surface_destroy;
surface->base.present = wayland_surface_present;
surface->base.validate = wayland_surface_validate;
surface->base.wait = wayland_surface_wait;
 
return &surface->base;
}
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
struct wayland_display *display = NULL;
boolean own_dpy = FALSE;
 
use_sw = use_sw || debug_get_bool_option("EGL_SOFTWARE", FALSE);
 
if (dpy == NULL) {
dpy = wl_display_connect(NULL);
if (dpy == NULL)
return NULL;
own_dpy = TRUE;
}
 
if (use_sw) {
_eglLog(_EGL_INFO, "use software fallback");
display = wayland_create_shm_display((struct wl_display *) dpy,
wayland_event_handler);
} else {
display = wayland_create_drm_display((struct wl_display *) dpy,
wayland_event_handler);
}
 
if (!display)
return NULL;
 
display->base.get_param = wayland_display_get_param;
display->base.get_configs = wayland_display_get_configs;
display->base.create_window_surface = wayland_create_window_surface;
 
display->own_dpy = own_dpy;
 
return &display->base;
}
 
static const struct native_platform wayland_platform = {
"wayland", /* name */
native_create_display
};
 
const struct native_platform *
native_get_wayland_platform(const struct native_event_handler *event_handler)
{
wayland_event_handler = event_handler;
return &wayland_platform;
}
 
/* vim: set sw=3 ts=8 sts=3 expandtab: */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/wayland/native_wayland.h
0,0 → 1,124
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _NATIVE_WAYLAND_H_
#define _NATIVE_WAYLAND_H_
 
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
 
#include "common/native.h"
#include "common/native_helper.h"
 
#include "wayland-egl-priv.h"
 
struct wayland_surface;
 
enum wayland_format_flag {
HAS_ARGB8888 = (1 << 0),
HAS_XRGB8888 = (1 << 1)
};
 
struct wayland_display {
struct native_display base;
 
struct wl_display *dpy;
struct wl_event_queue *queue;
struct wl_registry *registry;
boolean own_dpy;
/* supported formats */
uint32_t formats;
 
struct wayland_config *configs;
int num_configs;
 
struct wl_buffer *(*create_buffer)(struct wayland_display *display,
struct wayland_surface *surface,
enum native_attachment attachment);
};
 
enum wayland_buffer_type {
WL_BUFFER_FRONT,
WL_BUFFER_BACK,
WL_BUFFER_COUNT
};
 
enum wayland_surface_type {
WL_WINDOW_SURFACE,
WL_PBUFFER_SURFACE
};
 
struct wayland_surface {
struct native_surface base;
struct wayland_display *display;
 
struct wl_egl_window *win;
enum wayland_surface_type type;
int dx, dy;
struct resource_surface *rsurf;
struct pipe_resource *pending_resource;
enum pipe_format color_format;
 
unsigned int sequence_number;
struct wl_buffer *buffer[WL_BUFFER_COUNT];
unsigned int attachment_mask;
 
struct wl_callback *frame_callback;
boolean premultiplied_alpha;
};
 
struct wayland_config {
struct native_config base;
};
 
static INLINE struct wayland_display *
wayland_display(const struct native_display *ndpy)
{
return (struct wayland_display *) ndpy;
}
 
static INLINE struct wayland_surface *
wayland_surface(const struct native_surface *nsurf)
{
return (struct wayland_surface *) nsurf;
}
 
static INLINE struct wayland_config *
wayland_config(const struct native_config *nconf)
{
return (struct wayland_config *) nconf;
}
 
struct wayland_display *
wayland_create_shm_display(struct wl_display *display,
const struct native_event_handler *event_handler);
 
struct wayland_display *
wayland_create_drm_display(struct wl_display *display,
const struct native_event_handler *event_handler);
 
int
wayland_roundtrip(struct wayland_display *drmdpy);
 
#endif /* _NATIVE_WAYLAND_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/dri2.c
0,0 → 1,0
../../../../glx/dri2.c
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/glcore.h
0,0 → 1,181
#ifndef __gl_core_h_
#define __gl_core_h_
 
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice including the dates of first publication and
* either this permission notice or a reference to
* http://oss.sgi.com/projects/FreeB/
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of Silicon Graphics, Inc.
* shall not be used in advertising or otherwise to promote the sale, use or
* other dealings in this Software without prior written authorization from
* Silicon Graphics, Inc.
*/
 
#if !defined(_WIN32_WCE)
#include <sys/types.h>
#endif
 
#define GL_CORE_SGI 1
#define GL_CORE_MESA 2
#define GL_CORE_APPLE 4
#define GL_CORE_WINDOWS 8
 
typedef struct __GLcontextRec __GLcontext;
 
/*
** This file defines the interface between the GL core and the surrounding
** "operating system" that supports it (currently the GLX or WGL extensions).
**
** Members (data and function pointers) are documented as imported or
** exported according to how they are used by the core rendering functions.
** Imported members are initialized by the "operating system" and used by
** the core functions. Exported members are initialized by the core functions
** and used by the "operating system".
*/
 
/**
* Mode and limit information for a context. This information is
* kept around in the context so that values can be used during
* command execution, and for returning information about the
* context to the application.
*
* Instances of this structure are shared by the driver and the loader. To
* maintain binary compatability, new fields \b must be added only to the
* end of the structure.
*
* \sa _gl_context_modes_create
*/
typedef struct __GLcontextModesRec {
struct __GLcontextModesRec * next;
 
GLboolean rgbMode;
GLboolean floatMode;
GLboolean colorIndexMode;
GLuint doubleBufferMode;
GLuint stereoMode;
 
GLboolean haveAccumBuffer;
GLboolean haveDepthBuffer;
GLboolean haveStencilBuffer;
 
GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */
GLuint redMask, greenMask, blueMask, alphaMask;
GLint rgbBits; /* total bits for rgb */
GLint indexBits; /* total bits for colorindex */
 
GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
GLint depthBits;
GLint stencilBits;
 
GLint numAuxBuffers;
 
GLint level;
 
GLint pixmapMode;
 
/* GLX */
GLint visualID;
GLint visualType; /**< One of the GLX X visual types. (i.e.,
* \c GLX_TRUE_COLOR, etc.)
*/
 
/* EXT_visual_rating / GLX 1.2 */
GLint visualRating;
 
/* EXT_visual_info / GLX 1.2 */
GLint transparentPixel;
/* colors are floats scaled to ints */
GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha;
GLint transparentIndex;
 
/* ARB_multisample / SGIS_multisample */
GLint sampleBuffers;
GLint samples;
 
/* SGIX_fbconfig / GLX 1.3 */
GLint drawableType;
GLint renderType;
GLint xRenderable;
GLint fbconfigID;
 
/* SGIX_pbuffer / GLX 1.3 */
GLint maxPbufferWidth;
GLint maxPbufferHeight;
GLint maxPbufferPixels;
GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */
GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */
 
/* SGIX_visual_select_group */
GLint visualSelectGroup;
 
/* OML_swap_method */
GLint swapMethod;
 
GLint screen;
 
/* EXT_texture_from_pixmap */
GLint bindToTextureRgb;
GLint bindToTextureRgba;
GLint bindToMipmapTexture;
GLint bindToTextureTargets;
GLint yInverted;
} __GLcontextModes;
 
/* Several fields of __GLcontextModes can take these as values. Since
* GLX header files may not be available everywhere they need to be used,
* redefine them here.
*/
#define GLX_NONE 0x8000
#define GLX_SLOW_CONFIG 0x8001
#define GLX_TRUE_COLOR 0x8002
#define GLX_DIRECT_COLOR 0x8003
#define GLX_PSEUDO_COLOR 0x8004
#define GLX_STATIC_COLOR 0x8005
#define GLX_GRAY_SCALE 0x8006
#define GLX_STATIC_GRAY 0x8007
#define GLX_TRANSPARENT_RGB 0x8008
#define GLX_TRANSPARENT_INDEX 0x8009
#define GLX_NON_CONFORMANT_CONFIG 0x800D
#define GLX_SWAP_EXCHANGE_OML 0x8061
#define GLX_SWAP_COPY_OML 0x8062
#define GLX_SWAP_UNDEFINED_OML 0x8063
 
#define GLX_DONT_CARE 0xFFFFFFFF
 
#define GLX_RGBA_BIT 0x00000001
#define GLX_COLOR_INDEX_BIT 0x00000002
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PIXMAP_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
 
#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
#define GLX_Y_INVERTED_EXT 0x20D4
 
#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
 
#endif /* __gl_core_h_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/glxinit.c
0,0 → 1,656
/**
* GLX initialization. Code based on glxext.c, glx_query.c, and
* glcontextmodes.c under src/glx/. The major difference is that DRI
* related code is stripped out.
*
* If the maintenance of this file takes too much time, we should consider
* refactoring glxext.c.
*/
 
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/Xproto.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include <sys/time.h>
 
#include "GL/glxproto.h"
#include "GL/glxtokens.h"
#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
#include "glcore.h" /* for __GLcontextModes */
 
#include "glxinit.h"
 
#ifdef GLX_DIRECT_RENDERING
 
typedef struct GLXGenericGetString
{
CARD8 reqType;
CARD8 glxCode;
CARD16 length B16;
CARD32 for_whom B32;
CARD32 name B32;
} xGLXGenericGetStringReq;
 
#define sz_xGLXGenericGetStringReq 12
#define X_GLXGenericGetString 0
 
/* Extension required boiler plate */
 
static char *__glXExtensionName = GLX_EXTENSION_NAME;
static XExtensionInfo *__glXExtensionInfo = NULL;
 
static int
__glXCloseDisplay(Display * dpy, XExtCodes * codes)
{
return XextRemoveDisplay(__glXExtensionInfo, dpy);
}
 
static /* const */ XExtensionHooks __glXExtensionHooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
__glXCloseDisplay, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
 
static XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
__glXExtensionName, &__glXExtensionHooks,
__GLX_NUMBER_EVENTS, NULL)
 
static GLint
_gl_convert_from_x_visual_type(int visualType)
{
#define NUM_VISUAL_TYPES 6
static const int glx_visual_types[NUM_VISUAL_TYPES] = {
GLX_STATIC_GRAY, GLX_GRAY_SCALE,
GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
GLX_TRUE_COLOR, GLX_DIRECT_COLOR
};
 
return ((unsigned) visualType < NUM_VISUAL_TYPES)
? glx_visual_types[visualType] : GLX_NONE;
}
 
static void
_gl_context_modes_destroy(__GLcontextModes * modes)
{
while (modes != NULL) {
__GLcontextModes *const next = modes->next;
 
free(modes);
modes = next;
}
}
 
static __GLcontextModes *
_gl_context_modes_create(unsigned count, size_t minimum_size)
{
const size_t size = (minimum_size > sizeof(__GLcontextModes))
? minimum_size : sizeof(__GLcontextModes);
__GLcontextModes *base = NULL;
__GLcontextModes **next;
unsigned i;
 
next = &base;
for (i = 0; i < count; i++) {
*next = malloc(size);
if (*next == NULL) {
_gl_context_modes_destroy(base);
base = NULL;
break;
}
 
memset(*next, 0, size);
(*next)->visualID = GLX_DONT_CARE;
(*next)->visualType = GLX_DONT_CARE;
(*next)->visualRating = GLX_NONE;
(*next)->transparentPixel = GLX_NONE;
(*next)->transparentRed = GLX_DONT_CARE;
(*next)->transparentGreen = GLX_DONT_CARE;
(*next)->transparentBlue = GLX_DONT_CARE;
(*next)->transparentAlpha = GLX_DONT_CARE;
(*next)->transparentIndex = GLX_DONT_CARE;
(*next)->xRenderable = GLX_DONT_CARE;
(*next)->fbconfigID = GLX_DONT_CARE;
(*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
(*next)->bindToTextureRgb = GLX_DONT_CARE;
(*next)->bindToTextureRgba = GLX_DONT_CARE;
(*next)->bindToMipmapTexture = GLX_DONT_CARE;
(*next)->bindToTextureTargets = GLX_DONT_CARE;
(*next)->yInverted = GLX_DONT_CARE;
 
next = &((*next)->next);
}
 
return base;
}
 
static char *
__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
{
xGLXGenericGetStringReq *req;
xGLXSingleReply reply;
int length;
int numbytes;
char *buf;
CARD32 for_whom = screen;
CARD32 glxCode = X_GLXQueryServerString;
 
 
LockDisplay(dpy);
 
 
/* All of the GLX protocol requests for getting a string from the server
* look the same. The exact meaning of the for_whom field is usually
* either the screen number (for glXQueryServerString) or the context tag
* (for GLXSingle).
*/
 
GetReq(GLXGenericGetString, req);
req->reqType = opcode;
req->glxCode = glxCode;
req->for_whom = for_whom;
req->name = name;
 
_XReply(dpy, (xReply *) & reply, 0, False);
 
length = reply.length * 4;
numbytes = reply.size;
 
buf = malloc(numbytes);
if (buf != NULL) {
_XRead(dpy, buf, numbytes);
length -= numbytes;
}
 
_XEatData(dpy, length);
 
UnlockDisplay(dpy);
SyncHandle();
 
return buf;
}
 
/************************************************************************/
/*
** Free the per screen configs data as well as the array of
** __glXScreenConfigs.
*/
static void
FreeScreenConfigs(__GLXdisplayPrivate * priv)
{
__GLXscreenConfigs *psc;
GLint i, screens;
 
/* Free screen configuration information */
screens = ScreenCount(priv->dpy);
for (i = 0; i < screens; i++) {
psc = priv->screenConfigs[i];
if (!psc)
continue;
if (psc->configs) {
_gl_context_modes_destroy(psc->configs);
psc->configs = NULL; /* NOTE: just for paranoia */
}
free((char *) psc->serverGLXexts);
}
free((char *) priv->screenConfigs);
priv->screenConfigs = NULL;
}
 
/*
** Release the private memory referred to in a display private
** structure. The caller will free the extension structure.
*/
static int
__glXFreeDisplayPrivate(XExtData * extension)
{
__GLXdisplayPrivate *priv;
 
priv = (__GLXdisplayPrivate *) extension->private_data;
FreeScreenConfigs(priv);
free((char *) priv->serverGLXversion);
free((char *) priv);
return 0;
}
 
/************************************************************************/
 
/*
** Query the version of the GLX extension. This procedure works even if
** the client extension is not completely set up.
*/
 
#define GLX_MAJOR_VERSION 1 /* current version numbers */
#define GLX_MINOR_VERSION 4
 
static Bool
QueryVersion(Display * dpy, int opcode, int *major, int *minor)
{
xGLXQueryVersionReq *req;
xGLXQueryVersionReply reply;
 
/* Send the glXQueryVersion request */
LockDisplay(dpy);
GetReq(GLXQueryVersion, req);
req->reqType = opcode;
req->glxCode = X_GLXQueryVersion;
req->majorVersion = GLX_MAJOR_VERSION;
req->minorVersion = GLX_MINOR_VERSION;
_XReply(dpy, (xReply *) & reply, 0, False);
UnlockDisplay(dpy);
SyncHandle();
 
if (reply.majorVersion != GLX_MAJOR_VERSION) {
/*
** The server does not support the same major release as this
** client.
*/
return GL_FALSE;
}
*major = reply.majorVersion;
*minor = min(reply.minorVersion, GLX_MINOR_VERSION);
return GL_TRUE;
}
 
#define __GLX_MIN_CONFIG_PROPS 18
#define __GLX_MAX_CONFIG_PROPS 500
#define __GLX_EXT_CONFIG_PROPS 10
#define __GLX_TOTAL_CONFIG (__GLX_MIN_CONFIG_PROPS + \
2 * __GLX_EXT_CONFIG_PROPS)
 
static void
__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
const INT32 * bp, Bool tagged_only,
Bool fbconfig_style_tags)
{
int i;
 
if (!tagged_only) {
/* Copy in the first set of properties */
config->visualID = *bp++;
 
config->visualType = _gl_convert_from_x_visual_type(*bp++);
 
config->rgbMode = *bp++;
 
config->redBits = *bp++;
config->greenBits = *bp++;
config->blueBits = *bp++;
config->alphaBits = *bp++;
config->accumRedBits = *bp++;
config->accumGreenBits = *bp++;
config->accumBlueBits = *bp++;
config->accumAlphaBits = *bp++;
 
config->doubleBufferMode = *bp++;
config->stereoMode = *bp++;
 
config->rgbBits = *bp++;
config->depthBits = *bp++;
config->stencilBits = *bp++;
config->numAuxBuffers = *bp++;
config->level = *bp++;
 
count -= __GLX_MIN_CONFIG_PROPS;
}
 
/*
** Additional properties may be in a list at the end
** of the reply. They are in pairs of property type
** and property value.
*/
 
#define FETCH_OR_SET(tag) \
config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
 
for (i = 0; i < count; i += 2) {
switch (*bp++) {
case GLX_RGBA:
FETCH_OR_SET(rgbMode);
break;
case GLX_BUFFER_SIZE:
config->rgbBits = *bp++;
break;
case GLX_LEVEL:
config->level = *bp++;
break;
case GLX_DOUBLEBUFFER:
FETCH_OR_SET(doubleBufferMode);
break;
case GLX_STEREO:
FETCH_OR_SET(stereoMode);
break;
case GLX_AUX_BUFFERS:
config->numAuxBuffers = *bp++;
break;
case GLX_RED_SIZE:
config->redBits = *bp++;
break;
case GLX_GREEN_SIZE:
config->greenBits = *bp++;
break;
case GLX_BLUE_SIZE:
config->blueBits = *bp++;
break;
case GLX_ALPHA_SIZE:
config->alphaBits = *bp++;
break;
case GLX_DEPTH_SIZE:
config->depthBits = *bp++;
break;
case GLX_STENCIL_SIZE:
config->stencilBits = *bp++;
break;
case GLX_ACCUM_RED_SIZE:
config->accumRedBits = *bp++;
break;
case GLX_ACCUM_GREEN_SIZE:
config->accumGreenBits = *bp++;
break;
case GLX_ACCUM_BLUE_SIZE:
config->accumBlueBits = *bp++;
break;
case GLX_ACCUM_ALPHA_SIZE:
config->accumAlphaBits = *bp++;
break;
case GLX_VISUAL_CAVEAT_EXT:
config->visualRating = *bp++;
break;
case GLX_X_VISUAL_TYPE:
config->visualType = *bp++;
break;
case GLX_TRANSPARENT_TYPE:
config->transparentPixel = *bp++;
break;
case GLX_TRANSPARENT_INDEX_VALUE:
config->transparentIndex = *bp++;
break;
case GLX_TRANSPARENT_RED_VALUE:
config->transparentRed = *bp++;
break;
case GLX_TRANSPARENT_GREEN_VALUE:
config->transparentGreen = *bp++;
break;
case GLX_TRANSPARENT_BLUE_VALUE:
config->transparentBlue = *bp++;
break;
case GLX_TRANSPARENT_ALPHA_VALUE:
config->transparentAlpha = *bp++;
break;
case GLX_VISUAL_ID:
config->visualID = *bp++;
break;
case GLX_DRAWABLE_TYPE:
config->drawableType = *bp++;
break;
case GLX_RENDER_TYPE:
config->renderType = *bp++;
break;
case GLX_X_RENDERABLE:
config->xRenderable = *bp++;
break;
case GLX_FBCONFIG_ID:
config->fbconfigID = *bp++;
break;
case GLX_MAX_PBUFFER_WIDTH:
config->maxPbufferWidth = *bp++;
break;
case GLX_MAX_PBUFFER_HEIGHT:
config->maxPbufferHeight = *bp++;
break;
case GLX_MAX_PBUFFER_PIXELS:
config->maxPbufferPixels = *bp++;
break;
case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
config->optimalPbufferWidth = *bp++;
break;
case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
config->optimalPbufferHeight = *bp++;
break;
case GLX_VISUAL_SELECT_GROUP_SGIX:
config->visualSelectGroup = *bp++;
break;
case GLX_SWAP_METHOD_OML:
config->swapMethod = *bp++;
break;
case GLX_SAMPLE_BUFFERS_SGIS:
config->sampleBuffers = *bp++;
break;
case GLX_SAMPLES_SGIS:
config->samples = *bp++;
break;
case GLX_BIND_TO_TEXTURE_RGB_EXT:
config->bindToTextureRgb = *bp++;
break;
case GLX_BIND_TO_TEXTURE_RGBA_EXT:
config->bindToTextureRgba = *bp++;
break;
case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
config->bindToMipmapTexture = *bp++;
break;
case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
config->bindToTextureTargets = *bp++;
break;
case GLX_Y_INVERTED_EXT:
config->yInverted = *bp++;
break;
case None:
i = count;
break;
default:
break;
}
}
 
config->renderType =
(config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
 
config->haveAccumBuffer = ((config->accumRedBits +
config->accumGreenBits +
config->accumBlueBits +
config->accumAlphaBits) > 0);
config->haveDepthBuffer = (config->depthBits > 0);
config->haveStencilBuffer = (config->stencilBits > 0);
}
 
static __GLcontextModes *
createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
int screen, GLboolean tagged_only)
{
INT32 buf[__GLX_TOTAL_CONFIG], *props;
unsigned prop_size;
__GLcontextModes *modes, *m;
int i;
 
if (nprops == 0)
return NULL;
 
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
 
/* Check number of properties */
if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
return NULL;
 
/* Allocate memory for our config structure */
modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
if (!modes)
return NULL;
 
prop_size = nprops * __GLX_SIZE_INT32;
if (prop_size <= sizeof(buf))
props = buf;
else
props = malloc(prop_size);
 
/* Read each config structure and convert it into our format */
m = modes;
for (i = 0; i < nvisuals; i++) {
_XRead(dpy, (char *) props, prop_size);
/* Older X servers don't send this so we default it here. */
m->drawableType = GLX_WINDOW_BIT;
__glXInitializeVisualConfigFromTags(m, nprops, props,
tagged_only, GL_TRUE);
m->screen = screen;
m = m->next;
}
 
if (props != buf)
free(props);
 
return modes;
}
 
static GLboolean
getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
{
xGLXGetFBConfigsReq *fb_req;
xGLXGetFBConfigsSGIXReq *sgi_req;
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXGetFBConfigsReply reply;
Display *dpy = priv->dpy;
 
psc->serverGLXexts =
__glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
 
LockDisplay(dpy);
 
psc->configs = NULL;
if (atof(priv->serverGLXversion) >= 1.3) {
GetReq(GLXGetFBConfigs, fb_req);
fb_req->reqType = priv->majorOpcode;
fb_req->glxCode = X_GLXGetFBConfigs;
fb_req->screen = screen;
}
else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXGetFBConfigsSGIXReq +
sz_xGLXVendorPrivateWithReplyReq, vpreq);
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
sgi_req->reqType = priv->majorOpcode;
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
sgi_req->screen = screen;
}
else
goto out;
 
if (!_XReply(dpy, (xReply *) & reply, 0, False))
goto out;
 
psc->configs = createConfigsFromProperties(dpy,
reply.numFBConfigs,
reply.numAttribs * 2,
screen, GL_TRUE);
 
out:
UnlockDisplay(dpy);
return psc->configs != NULL;
}
 
static GLboolean
AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
{
__GLXscreenConfigs *psc;
GLint i, screens;
 
/*
** First allocate memory for the array of per screen configs.
*/
screens = ScreenCount(dpy);
priv->screenConfigs = malloc(screens * sizeof *priv->screenConfigs);
if (!priv->screenConfigs) {
return GL_FALSE;
}
 
priv->serverGLXversion =
__glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
if (priv->serverGLXversion == NULL) {
FreeScreenConfigs(priv);
return GL_FALSE;
}
 
for (i = 0; i < screens; i++) {
psc = calloc(1, sizeof *psc);
if (!psc)
return GL_FALSE;
getFBConfigs(psc, priv, i);
priv->screenConfigs[i] = psc;
}
 
SyncHandle();
 
return GL_TRUE;
}
 
_X_HIDDEN __GLXdisplayPrivate *
__glXInitialize(Display * dpy)
{
XExtDisplayInfo *info = __glXFindDisplay(dpy);
XExtData **privList, *private, *found;
__GLXdisplayPrivate *dpyPriv;
XEDataObject dataObj;
int major, minor;
 
if (!XextHasExtension(info))
return NULL;
 
/* See if a display private already exists. If so, return it */
dataObj.display = dpy;
privList = XEHeadOfExtensionList(dataObj);
found = XFindOnExtensionList(privList, info->codes->extension);
if (found)
return (__GLXdisplayPrivate *) found->private_data;
 
/* See if the versions are compatible */
if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
return NULL;
 
/*
** Allocate memory for all the pieces needed for this buffer.
*/
private = malloc(sizeof(XExtData));
if (!private)
return NULL;
dpyPriv = calloc(1, sizeof(__GLXdisplayPrivate));
if (!dpyPriv) {
free(private);
return NULL;
}
 
/*
** Init the display private and then read in the screen config
** structures from the server.
*/
dpyPriv->majorOpcode = info->codes->major_opcode;
dpyPriv->dpy = dpy;
 
if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
free(dpyPriv);
free(private);
return NULL;
}
 
/*
** Fill in the private structure. This is the actual structure that
** hangs off of the Display structure. Our private structure is
** referred to by this structure. Got that?
*/
private->number = info->codes->extension;
private->next = 0;
private->free_private = __glXFreeDisplayPrivate;
private->private_data = (char *) dpyPriv;
XAddToExtensionList(privList, private);
 
return dpyPriv;
}
 
#endif /* GLX_DIRECT_RENDERING */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/glxinit.h
0,0 → 1,22
#ifndef GLXINIT_INCLUDED
#define GLXINIT_INCLUDED
 
#include <X11/Xlib.h>
#include <GL/gl.h>
 
typedef struct {
__GLcontextModes *configs;
char *serverGLXexts;
} __GLXscreenConfigs;
 
typedef struct {
Display *dpy;
__GLXscreenConfigs **screenConfigs;
char *serverGLXversion;
int majorOpcode;
struct x11_screen *xscr;
} __GLXdisplayPrivate;
 
extern __GLXdisplayPrivate *__glXInitialize(Display * dpy);
 
#endif /* GLXINIT_INCLUDED */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_dri2.c
0,0 → 1,955
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_inlines.h"
#include "util/u_hash_table.h"
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "state_tracker/drm_driver.h"
#include "egllog.h"
 
#include "native_x11.h"
#include "x11_screen.h"
 
#include "common/native_helper.h"
#ifdef HAVE_WAYLAND_BACKEND
#include "common/native_wayland_drm_bufmgr_helper.h"
#endif
 
#ifdef GLX_DIRECT_RENDERING
 
struct dri2_display {
struct native_display base;
Display *dpy;
boolean own_dpy;
 
const struct native_event_handler *event_handler;
 
struct x11_screen *xscr;
int xscr_number;
const char *dri_driver;
int dri_major, dri_minor;
 
struct dri2_config *configs;
int num_configs;
 
struct util_hash_table *surfaces;
#ifdef HAVE_WAYLAND_BACKEND
struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
#endif
};
 
struct dri2_surface {
struct native_surface base;
Drawable drawable;
enum pipe_format color_format;
struct dri2_display *dri2dpy;
 
unsigned int server_stamp;
unsigned int client_stamp;
int width, height;
struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
uint valid_mask;
 
boolean have_back, have_fake;
 
struct x11_drawable_buffer *last_xbufs;
int last_num_xbufs;
};
 
struct dri2_config {
struct native_config base;
};
 
static INLINE struct dri2_display *
dri2_display(const struct native_display *ndpy)
{
return (struct dri2_display *) ndpy;
}
 
static INLINE struct dri2_surface *
dri2_surface(const struct native_surface *nsurf)
{
return (struct dri2_surface *) nsurf;
}
 
static INLINE struct dri2_config *
dri2_config(const struct native_config *nconf)
{
return (struct dri2_config *) nconf;
}
 
/**
* Process the buffers returned by the server.
*/
static void
dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
struct x11_drawable_buffer *xbufs,
int num_xbufs)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
struct pipe_resource templ;
struct winsys_handle whandle;
uint valid_mask;
int i;
 
/* free the old textures */
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
pipe_resource_reference(&dri2surf->textures[i], NULL);
dri2surf->valid_mask = 0x0;
 
dri2surf->have_back = FALSE;
dri2surf->have_fake = FALSE;
 
if (!xbufs)
return;
 
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
templ.width0 = dri2surf->width;
templ.height0 = dri2surf->height;
templ.depth0 = 1;
templ.array_size = 1;
templ.format = dri2surf->color_format;
templ.bind = PIPE_BIND_RENDER_TARGET;
 
valid_mask = 0x0;
for (i = 0; i < num_xbufs; i++) {
struct x11_drawable_buffer *xbuf = &xbufs[i];
const char *desc;
enum native_attachment natt;
 
switch (xbuf->attachment) {
case DRI2BufferFrontLeft:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
desc = "DRI2 Front Buffer";
break;
case DRI2BufferFakeFrontLeft:
natt = NATIVE_ATTACHMENT_FRONT_LEFT;
desc = "DRI2 Fake Front Buffer";
dri2surf->have_fake = TRUE;
break;
case DRI2BufferBackLeft:
natt = NATIVE_ATTACHMENT_BACK_LEFT;
desc = "DRI2 Back Buffer";
dri2surf->have_back = TRUE;
break;
default:
desc = NULL;
break;
}
 
if (!desc || dri2surf->textures[natt]) {
if (!desc)
_eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
else
_eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
continue;
}
 
memset(&whandle, 0, sizeof(whandle));
whandle.stride = xbuf->pitch;
whandle.handle = xbuf->name;
dri2surf->textures[natt] = dri2dpy->base.screen->resource_from_handle(
dri2dpy->base.screen, &templ, &whandle);
if (dri2surf->textures[natt])
valid_mask |= 1 << natt;
}
 
dri2surf->valid_mask = valid_mask;
}
 
/**
* Get the buffers from the server.
*/
static void
dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS * 2];
int num_ins, num_outs, att;
struct x11_drawable_buffer *xbufs;
uint bpp = util_format_get_blocksizebits(dri2surf->color_format);
boolean with_format = FALSE; /* never ask for depth/stencil */
 
/* We must get the front on servers which doesn't support with format
* due to a silly bug in core dri2. You can't copy to/from a buffer
* that you haven't requested and you recive BadValue errors */
if (dri2surf->dri2dpy->dri_minor < 1) {
with_format = FALSE;
buffer_mask |= (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
}
 
/* prepare the attachments */
num_ins = 0;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(buffer_mask, att)) {
unsigned int dri2att;
 
switch (att) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
dri2att = DRI2BufferFrontLeft;
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
dri2att = DRI2BufferBackLeft;
break;
case NATIVE_ATTACHMENT_FRONT_RIGHT:
dri2att = DRI2BufferFrontRight;
break;
case NATIVE_ATTACHMENT_BACK_RIGHT:
dri2att = DRI2BufferBackRight;
break;
default:
assert(0);
dri2att = 0;
break;
}
 
dri2atts[num_ins++] = dri2att;
if (with_format)
dri2atts[num_ins++] = bpp;
}
}
if (with_format)
num_ins /= 2;
 
xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
&dri2surf->width, &dri2surf->height,
dri2atts, with_format, num_ins, &num_outs);
 
/* we should be able to do better... */
if (xbufs && dri2surf->last_num_xbufs == num_outs &&
memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) {
FREE(xbufs);
dri2surf->client_stamp = dri2surf->server_stamp;
return;
}
 
dri2_surface_process_drawable_buffers(&dri2surf->base, xbufs, num_outs);
 
dri2surf->server_stamp++;
dri2surf->client_stamp = dri2surf->server_stamp;
 
FREE(dri2surf->last_xbufs);
dri2surf->last_xbufs = xbufs;
dri2surf->last_num_xbufs = num_outs;
}
 
/**
* Update the buffers of the surface. This is a slow function due to the
* round-trip to the server.
*/
static boolean
dri2_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
 
dri2_surface_get_buffers(&dri2surf->base, buffer_mask);
 
return ((dri2surf->valid_mask & buffer_mask) == buffer_mask);
}
 
/**
* Return TRUE if the surface receives DRI2_InvalidateBuffers events.
*/
static INLINE boolean
dri2_surface_receive_events(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
return (dri2surf->dri2dpy->dri_minor >= 3);
}
 
static boolean
dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
 
/* copy to real front buffer */
if (dri2surf->have_fake)
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
 
/* force buffers to be updated in next validation call */
if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
&dri2surf->base, dri2surf->server_stamp);
}
 
return TRUE;
}
 
static boolean
dri2_surface_swap_buffers(struct native_surface *nsurf, int num_rects,
const int *rects)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
 
/* copy to front buffer */
if (dri2surf->have_back) {
if (num_rects > 0)
x11_drawable_copy_buffers_region(dri2dpy->xscr, dri2surf->drawable,
num_rects, rects,
DRI2BufferBackLeft, DRI2BufferFrontLeft);
else
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferBackLeft, DRI2BufferFrontLeft);
}
 
/* and update fake front buffer */
if (dri2surf->have_fake) {
if (num_rects > 0)
x11_drawable_copy_buffers_region(dri2dpy->xscr, dri2surf->drawable,
num_rects, rects,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
else
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
}
 
/* force buffers to be updated in next validation call */
if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
&dri2surf->base, dri2surf->server_stamp);
}
 
return TRUE;
}
 
static boolean
dri2_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
boolean ret;
 
if (ctrl->swap_interval)
return FALSE;
 
switch (ctrl->natt) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
ret = dri2_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
ret = dri2_surface_swap_buffers(nsurf, ctrl->num_rects, ctrl->rects);
break;
default:
ret = FALSE;
break;
}
 
return ret;
}
 
static boolean
dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
 
if (dri2surf->server_stamp != dri2surf->client_stamp ||
(dri2surf->valid_mask & attachment_mask) != attachment_mask) {
if (!dri2_surface_update_buffers(&dri2surf->base, attachment_mask))
return FALSE;
}
 
if (seq_num)
*seq_num = dri2surf->client_stamp;
 
if (textures) {
int att;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(attachment_mask, att)) {
struct pipe_resource *ptex = dri2surf->textures[att];
 
textures[att] = NULL;
pipe_resource_reference(&textures[att], ptex);
}
}
}
 
if (width)
*width = dri2surf->width;
if (height)
*height = dri2surf->height;
 
return TRUE;
}
 
static void
dri2_surface_wait(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
 
if (dri2surf->have_fake) {
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
0, 0, dri2surf->width, dri2surf->height,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
}
}
 
static void
dri2_surface_destroy(struct native_surface *nsurf)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
int i;
 
FREE(dri2surf->last_xbufs);
 
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
struct pipe_resource *ptex = dri2surf->textures[i];
pipe_resource_reference(&ptex, NULL);
}
 
if (dri2surf->drawable) {
x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
dri2surf->drawable, FALSE);
 
util_hash_table_remove(dri2surf->dri2dpy->surfaces,
(void *) dri2surf->drawable);
}
FREE(dri2surf);
}
 
static struct dri2_surface *
dri2_display_create_surface(struct native_display *ndpy,
Drawable drawable,
enum pipe_format color_format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
struct dri2_surface *dri2surf;
 
dri2surf = CALLOC_STRUCT(dri2_surface);
if (!dri2surf)
return NULL;
 
dri2surf->dri2dpy = dri2dpy;
dri2surf->drawable = drawable;
dri2surf->color_format = color_format;
 
dri2surf->base.destroy = dri2_surface_destroy;
dri2surf->base.present = dri2_surface_present;
dri2surf->base.validate = dri2_surface_validate;
dri2surf->base.wait = dri2_surface_wait;
 
if (drawable) {
x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
/* initialize the geometry */
dri2_surface_update_buffers(&dri2surf->base, 0x0);
 
util_hash_table_set(dri2surf->dri2dpy->surfaces,
(void *) dri2surf->drawable, (void *) &dri2surf->base);
}
 
return dri2surf;
}
 
static struct native_surface *
dri2_display_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct dri2_surface *dri2surf;
 
dri2surf = dri2_display_create_surface(ndpy,
(Drawable) win, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
 
static struct native_surface *
dri2_display_create_pixmap_surface(struct native_display *ndpy,
EGLNativePixmapType pix,
const struct native_config *nconf)
{
struct dri2_surface *dri2surf;
 
if (!nconf) {
struct dri2_display *dri2dpy = dri2_display(ndpy);
uint depth, nconf_depth;
int i;
 
depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
for (i = 0; i < dri2dpy->num_configs; i++) {
nconf_depth = util_format_get_blocksizebits(
dri2dpy->configs[i].base.color_format);
/* simple depth match for now */
if (depth == nconf_depth ||
(depth == 24 && depth + 8 == nconf_depth)) {
nconf = &dri2dpy->configs[i].base;
break;
}
}
 
if (!nconf)
return NULL;
}
 
dri2surf = dri2_display_create_surface(ndpy,
(Drawable) pix, nconf->color_format);
return (dri2surf) ? &dri2surf->base : NULL;
}
 
static int
choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
{
int count = 0;
 
switch (mode->rgbBits) {
case 32:
formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case 24:
formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case 16:
formats[count++] = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
break;
}
 
return count;
}
 
static boolean
is_format_supported(struct pipe_screen *screen,
enum pipe_format fmt, unsigned sample_count, boolean is_color)
{
return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count,
(is_color) ? PIPE_BIND_RENDER_TARGET :
PIPE_BIND_DEPTH_STENCIL);
}
 
static boolean
dri2_display_convert_config(struct native_display *ndpy,
const __GLcontextModes *mode,
struct native_config *nconf)
{
enum pipe_format formats[32];
int num_formats, i;
int sample_count = 0;
 
if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode)
return FALSE;
 
/* only interested in native renderable configs */
if (!mode->xRenderable || !mode->drawableType)
return FALSE;
 
/* fast/slow configs are probably not relevant */
if (mode->visualRating == GLX_SLOW_CONFIG)
return FALSE;
 
nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
if (mode->doubleBufferMode)
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_LEFT;
if (mode->stereoMode) {
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_FRONT_RIGHT;
if (mode->doubleBufferMode)
nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_RIGHT;
}
 
/* choose color format */
num_formats = choose_color_format(mode, formats);
for (i = 0; i < num_formats; i++) {
if (is_format_supported(ndpy->screen, formats[i], sample_count, TRUE)) {
nconf->color_format = formats[i];
break;
}
}
if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
 
if ((mode->drawableType & GLX_WINDOW_BIT) && mode->visualID)
nconf->window_bit = TRUE;
if (mode->drawableType & GLX_PIXMAP_BIT)
nconf->pixmap_bit = TRUE;
 
nconf->native_visual_id = mode->visualID;
switch (mode->visualType) {
case GLX_TRUE_COLOR:
nconf->native_visual_type = TrueColor;
break;
case GLX_DIRECT_COLOR:
nconf->native_visual_type = DirectColor;
break;
case GLX_PSEUDO_COLOR:
nconf->native_visual_type = PseudoColor;
break;
case GLX_STATIC_COLOR:
nconf->native_visual_type = StaticColor;
break;
case GLX_GRAY_SCALE:
nconf->native_visual_type = GrayScale;
break;
case GLX_STATIC_GRAY:
nconf->native_visual_type = StaticGray;
break;
}
nconf->level = mode->level;
 
if (mode->transparentPixel == GLX_TRANSPARENT_RGB) {
nconf->transparent_rgb = TRUE;
nconf->transparent_rgb_values[0] = mode->transparentRed;
nconf->transparent_rgb_values[1] = mode->transparentGreen;
nconf->transparent_rgb_values[2] = mode->transparentBlue;
}
 
return TRUE;
}
 
static const struct native_config **
dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
const struct native_config **configs;
int i;
 
/* first time */
if (!dri2dpy->configs) {
const __GLcontextModes *modes;
int num_modes, count;
 
modes = x11_screen_get_glx_configs(dri2dpy->xscr);
if (!modes)
return NULL;
num_modes = x11_context_modes_count(modes);
 
dri2dpy->configs = CALLOC(num_modes, sizeof(*dri2dpy->configs));
if (!dri2dpy->configs)
return NULL;
 
count = 0;
for (i = 0; i < num_modes; i++) {
struct native_config *nconf = &dri2dpy->configs[count].base;
 
if (dri2_display_convert_config(&dri2dpy->base, modes, nconf)) {
int j;
/* look for duplicates */
for (j = 0; j < count; j++) {
if (memcmp(&dri2dpy->configs[j], nconf, sizeof(*nconf)) == 0)
break;
}
if (j == count)
count++;
}
modes = modes->next;
}
 
dri2dpy->num_configs = count;
}
 
configs = MALLOC(dri2dpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < dri2dpy->num_configs; i++)
configs[i] = (const struct native_config *) &dri2dpy->configs[i];
if (num_configs)
*num_configs = dri2dpy->num_configs;
}
 
return configs;
}
 
static boolean
dri2_display_get_pixmap_format(struct native_display *ndpy,
EGLNativePixmapType pix,
enum pipe_format *format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
boolean ret = EGL_TRUE;
uint depth;
 
depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
switch (depth) {
case 32:
case 24:
*format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 16:
*format = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
*format = PIPE_FORMAT_NONE;
ret = EGL_FALSE;
break;
}
 
return ret;
}
 
static int
dri2_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_USE_NATIVE_BUFFER:
/* DRI2GetBuffers uses the native buffers */
val = TRUE;
break;
case NATIVE_PARAM_PRESERVE_BUFFER:
/* DRI2CopyRegion is used */
val = TRUE;
break;
case NATIVE_PARAM_PRESENT_REGION:
val = TRUE;
break;
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
dri2_display_destroy(struct native_display *ndpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
FREE(dri2dpy->configs);
 
if (dri2dpy->base.screen)
dri2dpy->base.screen->destroy(dri2dpy->base.screen);
 
if (dri2dpy->surfaces)
util_hash_table_destroy(dri2dpy->surfaces);
 
if (dri2dpy->xscr)
x11_screen_destroy(dri2dpy->xscr);
if (dri2dpy->own_dpy)
XCloseDisplay(dri2dpy->dpy);
FREE(dri2dpy);
}
 
static void
dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
void *user_data)
{
struct native_display *ndpy = (struct native_display* ) user_data;
struct dri2_display *dri2dpy = dri2_display(ndpy);
struct native_surface *nsurf;
struct dri2_surface *dri2surf;
 
nsurf = (struct native_surface *)
util_hash_table_get(dri2dpy->surfaces, (void *) drawable);
if (!nsurf)
return;
 
dri2surf = dri2_surface(nsurf);
 
dri2surf->server_stamp++;
dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
&dri2surf->base, dri2surf->server_stamp);
}
 
/**
* Initialize DRI2 and pipe screen.
*/
static boolean
dri2_display_init_screen(struct native_display *ndpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
int fd;
 
if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) {
_eglLog(_EGL_WARNING, "GLX/DRI2 is not supported");
return FALSE;
}
 
dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr,
&dri2dpy->dri_major, &dri2dpy->dri_minor);
 
fd = x11_screen_enable_dri2(dri2dpy->xscr,
dri2_display_invalidate_buffers, &dri2dpy->base);
if (fd < 0)
return FALSE;
 
dri2dpy->base.screen =
dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
dri2dpy->dri_driver, fd);
if (!dri2dpy->base.screen) {
_eglLog(_EGL_DEBUG, "failed to create DRM screen");
return FALSE;
}
 
return TRUE;
}
 
static unsigned
dri2_display_hash_table_hash(void *key)
{
XID drawable = pointer_to_uintptr(key);
return (unsigned) drawable;
}
 
static int
dri2_display_hash_table_compare(void *key1, void *key2)
{
return ((char *) key1 - (char *) key2);
}
 
#ifdef HAVE_WAYLAND_BACKEND
 
static int
dri2_display_authenticate(void *user_data, uint32_t magic)
{
struct native_display *ndpy = user_data;
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
return x11_screen_authenticate(dri2dpy->xscr, magic);
}
 
static struct wayland_drm_callbacks wl_drm_callbacks = {
dri2_display_authenticate,
egl_g3d_wl_drm_helper_reference_buffer,
egl_g3d_wl_drm_helper_unreference_buffer
};
 
static boolean
dri2_display_bind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
if (dri2dpy->wl_server_drm)
return FALSE;
 
dri2dpy->wl_server_drm = wayland_drm_init(wl_dpy,
x11_screen_get_device_name(dri2dpy->xscr),
&wl_drm_callbacks, ndpy, 0);
 
if (!dri2dpy->wl_server_drm)
return FALSE;
return TRUE;
}
 
static boolean
dri2_display_unbind_wayland_display(struct native_display *ndpy,
struct wl_display *wl_dpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
 
if (!dri2dpy->wl_server_drm)
return FALSE;
 
wayland_drm_uninit(dri2dpy->wl_server_drm);
dri2dpy->wl_server_drm = NULL;
 
return TRUE;
}
 
static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = {
dri2_display_bind_wayland_display,
dri2_display_unbind_wayland_display,
egl_g3d_wl_drm_common_wl_buffer_get_resource,
egl_g3d_wl_drm_common_query_buffer
};
 
#endif /* HAVE_WAYLAND_BACKEND */
 
struct native_display *
x11_create_dri2_display(Display *dpy,
const struct native_event_handler *event_handler)
{
struct dri2_display *dri2dpy;
 
dri2dpy = CALLOC_STRUCT(dri2_display);
if (!dri2dpy)
return NULL;
 
dri2dpy->event_handler = event_handler;
 
dri2dpy->dpy = dpy;
if (!dri2dpy->dpy) {
dri2dpy->dpy = XOpenDisplay(NULL);
if (!dri2dpy->dpy) {
dri2_display_destroy(&dri2dpy->base);
return NULL;
}
dri2dpy->own_dpy = TRUE;
}
 
dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy);
dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number);
if (!dri2dpy->xscr) {
dri2_display_destroy(&dri2dpy->base);
return NULL;
}
 
dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
dri2_display_hash_table_compare);
if (!dri2dpy->surfaces) {
dri2_display_destroy(&dri2dpy->base);
return NULL;
}
 
dri2dpy->base.init_screen = dri2_display_init_screen;
dri2dpy->base.destroy = dri2_display_destroy;
dri2dpy->base.get_param = dri2_display_get_param;
dri2dpy->base.get_configs = dri2_display_get_configs;
dri2dpy->base.get_pixmap_format = dri2_display_get_pixmap_format;
dri2dpy->base.copy_to_pixmap = native_display_copy_to_pixmap;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
#ifdef HAVE_WAYLAND_BACKEND
dri2dpy->base.wayland_bufmgr = &dri2_display_wayland_bufmgr;
#endif
 
return &dri2dpy->base;
}
 
#else /* GLX_DIRECT_RENDERING */
 
struct native_display *
x11_create_dri2_display(Display *dpy,
const struct native_event_handler *event_handler)
{
return NULL;
}
 
#endif /* GLX_DIRECT_RENDERING */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_x11.c
0,0 → 1,63
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_string.h"
#include "egllog.h"
 
#include "native_x11.h"
 
static const struct native_event_handler *x11_event_handler;
 
static struct native_display *
native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy = NULL;
boolean force_sw;
 
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
 
if (force_sw || use_sw) {
_eglLog(_EGL_INFO, "use software fallback");
ndpy = x11_create_ximage_display((Display *) dpy, x11_event_handler);
}
else {
ndpy = x11_create_dri2_display((Display *) dpy, x11_event_handler);
}
 
return ndpy;
}
 
static const struct native_platform x11_platform = {
"X11", /* name */
native_create_display
};
 
const struct native_platform *
native_get_x11_platform(const struct native_event_handler *event_handler)
{
x11_event_handler = event_handler;
return &x11_platform;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_x11.h
0,0 → 1,39
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _NATIVE_X11_H_
#define _NATIVE_X11_H_
 
#include "common/native.h"
#include <X11/Xlib.h>
 
struct native_display *
x11_create_ximage_display(Display *dpy,
const struct native_event_handler *event_handler);
 
struct native_display *
x11_create_dri2_display(Display *dpy,
const struct native_event_handler *event_handler);
 
#endif /* _NATIVE_X11_H_ */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/native_ximage.c
0,0 → 1,586
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "pipe/p_compiler.h"
#include "util/u_inlines.h"
#include "state_tracker/xlib_sw_winsys.h"
#include "util/u_debug.h"
#include "egllog.h"
 
#include "common/native_helper.h"
#include "native_x11.h"
#include "x11_screen.h"
 
struct ximage_display {
struct native_display base;
Display *dpy;
boolean own_dpy;
 
const struct native_event_handler *event_handler;
 
struct x11_screen *xscr;
int xscr_number;
 
struct ximage_config *configs;
int num_configs;
};
 
struct ximage_surface {
struct native_surface base;
Drawable drawable;
enum pipe_format color_format;
XVisualInfo visual;
struct ximage_display *xdpy;
 
unsigned int server_stamp;
unsigned int client_stamp;
 
struct resource_surface *rsurf;
struct xlib_drawable xdraw;
};
 
struct ximage_config {
struct native_config base;
const XVisualInfo *visual;
};
 
static INLINE struct ximage_display *
ximage_display(const struct native_display *ndpy)
{
return (struct ximage_display *) ndpy;
}
 
static INLINE struct ximage_surface *
ximage_surface(const struct native_surface *nsurf)
{
return (struct ximage_surface *) nsurf;
}
 
static INLINE struct ximage_config *
ximage_config(const struct native_config *nconf)
{
return (struct ximage_config *) nconf;
}
 
/**
* Update the geometry of the surface. This is a slow functions.
*/
static void
ximage_surface_update_geometry(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
Status ok;
Window root;
int x, y;
unsigned int w, h, border, depth;
 
ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
&root, &x, &y, &w, &h, &border, &depth);
if (ok && resource_surface_set_size(xsurf->rsurf, w, h))
xsurf->server_stamp++;
}
 
/**
* Update the buffers of the surface.
*/
static boolean
ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
 
if (xsurf->client_stamp != xsurf->server_stamp) {
ximage_surface_update_geometry(&xsurf->base);
xsurf->client_stamp = xsurf->server_stamp;
}
 
return resource_surface_add_resources(xsurf->rsurf, buffer_mask);
}
 
/**
* Emulate an invalidate event.
*/
static void
ximage_surface_invalidate(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_display *xdpy = xsurf->xdpy;
 
xsurf->server_stamp++;
xdpy->event_handler->invalid_surface(&xdpy->base,
&xsurf->base, xsurf->server_stamp);
}
 
static boolean
ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean ret;
 
ret = resource_surface_present(xsurf->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT, (void *) &xsurf->xdraw);
/* force buffers to be updated in next validation call */
ximage_surface_invalidate(&xsurf->base);
 
return ret;
}
 
static boolean
ximage_surface_swap_buffers(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean ret;
 
ret = resource_surface_present(xsurf->rsurf,
NATIVE_ATTACHMENT_BACK_LEFT, (void *) &xsurf->xdraw);
 
resource_surface_swap_buffers(xsurf->rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
/* the front/back buffers have been swapped */
ximage_surface_invalidate(&xsurf->base);
 
return ret;
}
 
static boolean
ximage_surface_present(struct native_surface *nsurf,
const struct native_present_control *ctrl)
{
boolean ret;
 
if (ctrl->preserve || ctrl->swap_interval)
return FALSE;
 
switch (ctrl->natt) {
case NATIVE_ATTACHMENT_FRONT_LEFT:
ret = ximage_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
ret = ximage_surface_swap_buffers(nsurf);
break;
default:
ret = FALSE;
break;
}
 
return ret;
}
 
static boolean
ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
uint w, h;
 
if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
return FALSE;
 
if (seq_num)
*seq_num = xsurf->client_stamp;
 
if (textures)
resource_surface_get_resources(xsurf->rsurf, textures, attachment_mask);
 
resource_surface_get_size(xsurf->rsurf, &w, &h);
if (width)
*width = w;
if (height)
*height = h;
 
return TRUE;
}
 
static void
ximage_surface_wait(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
XSync(xsurf->xdpy->dpy, FALSE);
/* TODO XGetImage and update the front texture */
}
 
static void
ximage_surface_destroy(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
 
resource_surface_destroy(xsurf->rsurf);
FREE(xsurf);
}
 
static struct ximage_surface *
ximage_display_create_surface(struct native_display *ndpy,
Drawable drawable,
const struct native_config *nconf)
{
struct ximage_display *xdpy = ximage_display(ndpy);
struct ximage_config *xconf = ximage_config(nconf);
struct ximage_surface *xsurf;
 
xsurf = CALLOC_STRUCT(ximage_surface);
if (!xsurf)
return NULL;
 
xsurf->xdpy = xdpy;
xsurf->color_format = xconf->base.color_format;
xsurf->drawable = drawable;
 
xsurf->rsurf = resource_surface_create(xdpy->base.screen,
xsurf->color_format,
PIPE_BIND_RENDER_TARGET |
PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT);
if (!xsurf->rsurf) {
FREE(xsurf);
return NULL;
}
 
xsurf->drawable = drawable;
xsurf->visual = *xconf->visual;
/* initialize the geometry */
ximage_surface_update_geometry(&xsurf->base);
 
xsurf->xdraw.visual = xsurf->visual.visual;
xsurf->xdraw.depth = xsurf->visual.depth;
xsurf->xdraw.drawable = xsurf->drawable;
 
xsurf->base.destroy = ximage_surface_destroy;
xsurf->base.present = ximage_surface_present;
xsurf->base.validate = ximage_surface_validate;
xsurf->base.wait = ximage_surface_wait;
 
return xsurf;
}
 
static struct native_surface *
ximage_display_create_window_surface(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf)
{
struct ximage_surface *xsurf;
 
xsurf = ximage_display_create_surface(ndpy, (Drawable) win, nconf);
return (xsurf) ? &xsurf->base : NULL;
}
 
static enum pipe_format
get_pixmap_format(struct native_display *ndpy, EGLNativePixmapType pix)
{
struct ximage_display *xdpy = ximage_display(ndpy);
enum pipe_format fmt;
uint depth;
 
depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
 
switch (depth) {
case 32:
fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 24:
fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
break;
case 16:
fmt = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
fmt = PIPE_FORMAT_NONE;
break;
}
 
return fmt;
}
 
static struct native_surface *
ximage_display_create_pixmap_surface(struct native_display *ndpy,
EGLNativePixmapType pix,
const struct native_config *nconf)
{
struct ximage_surface *xsurf;
 
/* find the config */
if (!nconf) {
struct ximage_display *xdpy = ximage_display(ndpy);
enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
int i;
 
if (fmt != PIPE_FORMAT_NONE) {
for (i = 0; i < xdpy->num_configs; i++) {
if (xdpy->configs[i].base.color_format == fmt) {
nconf = &xdpy->configs[i].base;
break;
}
}
}
 
if (!nconf)
return NULL;
}
 
xsurf = ximage_display_create_surface(ndpy, (Drawable) pix, nconf);
return (xsurf) ? &xsurf->base : NULL;
}
 
static enum pipe_format
choose_format(const XVisualInfo *vinfo)
{
enum pipe_format fmt;
/* TODO elaborate the formats */
switch (vinfo->depth) {
case 32:
fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 24:
fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
break;
case 16:
fmt = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
fmt = PIPE_FORMAT_NONE;
break;
}
 
return fmt;
}
 
static const struct native_config **
ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
{
struct ximage_display *xdpy = ximage_display(ndpy);
const struct native_config **configs;
int i;
 
/* first time */
if (!xdpy->configs) {
const XVisualInfo *visuals;
int num_visuals, count;
 
visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals);
if (!visuals)
return NULL;
 
/*
* Create two configs for each visual.
* One with depth/stencil buffer; one without
*/
xdpy->configs = CALLOC(num_visuals * 2, sizeof(*xdpy->configs));
if (!xdpy->configs)
return NULL;
 
count = 0;
for (i = 0; i < num_visuals; i++) {
struct ximage_config *xconf = &xdpy->configs[count];
 
xconf->visual = &visuals[i];
xconf->base.color_format = choose_format(xconf->visual);
if (xconf->base.color_format == PIPE_FORMAT_NONE)
continue;
 
xconf->base.buffer_mask =
(1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
(1 << NATIVE_ATTACHMENT_BACK_LEFT);
 
xconf->base.window_bit = TRUE;
xconf->base.pixmap_bit = TRUE;
 
xconf->base.native_visual_id = xconf->visual->visualid;
#if defined(__cplusplus) || defined(c_plusplus)
xconf->base.native_visual_type = xconf->visual->c_class;
#else
xconf->base.native_visual_type = xconf->visual->class;
#endif
 
count++;
}
 
xdpy->num_configs = count;
}
 
configs = MALLOC(xdpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < xdpy->num_configs; i++)
configs[i] = (const struct native_config *) &xdpy->configs[i];
if (num_configs)
*num_configs = xdpy->num_configs;
}
return configs;
}
 
static boolean
ximage_display_get_pixmap_format(struct native_display *ndpy,
EGLNativePixmapType pix,
enum pipe_format *format)
{
struct ximage_display *xdpy = ximage_display(ndpy);
 
*format = get_pixmap_format(&xdpy->base, pix);
 
return (*format != PIPE_FORMAT_NONE);
}
 
static boolean
ximage_display_copy_to_pixmap(struct native_display *ndpy,
EGLNativePixmapType pix,
struct pipe_resource *src)
{
/* fast path to avoid unnecessary allocation and resource_copy_region */
if (src->bind & PIPE_BIND_DISPLAY_TARGET) {
struct ximage_display *xdpy = ximage_display(ndpy);
enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
const struct ximage_config *xconf = NULL;
struct xlib_drawable xdraw;
int i;
 
if (fmt == PIPE_FORMAT_NONE || src->format != fmt)
return FALSE;
 
for (i = 0; i < xdpy->num_configs; i++) {
if (xdpy->configs[i].base.color_format == fmt) {
xconf = &xdpy->configs[i];
break;
}
}
if (!xconf)
return FALSE;
 
memset(&xdraw, 0, sizeof(xdraw));
xdraw.visual = xconf->visual->visual;
xdraw.depth = xconf->visual->depth;
xdraw.drawable = (Drawable) pix;
 
xdpy->base.screen->flush_frontbuffer(xdpy->base.screen,
src, 0, 0, &xdraw);
 
return TRUE;
}
 
return native_display_copy_to_pixmap(ndpy, pix, src);
}
 
static int
ximage_display_get_param(struct native_display *ndpy,
enum native_param_type param)
{
int val;
 
switch (param) {
case NATIVE_PARAM_USE_NATIVE_BUFFER:
/* private buffers are allocated */
val = FALSE;
break;
case NATIVE_PARAM_PRESERVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
break;
}
 
return val;
}
 
static void
ximage_display_destroy(struct native_display *ndpy)
{
struct ximage_display *xdpy = ximage_display(ndpy);
 
FREE(xdpy->configs);
 
ndpy_uninit(ndpy);
 
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)
XCloseDisplay(xdpy->dpy);
FREE(xdpy);
}
 
static boolean
ximage_display_init_screen(struct native_display *ndpy)
{
struct ximage_display *xdpy = ximage_display(ndpy);
struct sw_winsys *winsys;
 
winsys = xlib_create_sw_winsys(xdpy->dpy);
if (!winsys)
return FALSE;
 
xdpy->base.screen =
xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
if (!xdpy->base.screen) {
if (winsys->destroy)
winsys->destroy(winsys);
return FALSE;
}
 
return TRUE;
}
 
struct native_display *
x11_create_ximage_display(Display *dpy,
const struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
 
xdpy = CALLOC_STRUCT(ximage_display);
if (!xdpy)
return NULL;
 
xdpy->dpy = dpy;
if (!xdpy->dpy) {
xdpy->dpy = XOpenDisplay(NULL);
if (!xdpy->dpy) {
FREE(xdpy);
return NULL;
}
xdpy->own_dpy = TRUE;
}
 
xdpy->event_handler = event_handler;
 
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
if (!xdpy->xscr) {
if (xdpy->own_dpy)
XCloseDisplay(xdpy->dpy);
FREE(xdpy);
return NULL;
}
 
xdpy->base.init_screen = ximage_display_init_screen;
xdpy->base.destroy = ximage_display_destroy;
xdpy->base.get_param = ximage_display_get_param;
 
xdpy->base.get_configs = ximage_display_get_configs;
xdpy->base.get_pixmap_format = ximage_display_get_pixmap_format;
xdpy->base.copy_to_pixmap = ximage_display_copy_to_pixmap;
xdpy->base.create_window_surface = ximage_display_create_window_surface;
xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
 
return &xdpy->base;
}
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/x11_screen.c
0,0 → 1,488
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <xf86drm.h>
#include <X11/Xlibint.h>
#include <X11/extensions/XShm.h>
 
#include "util/u_memory.h"
#include "egllog.h"
 
#include "x11_screen.h"
#include "dri2.h"
#include "glxinit.h"
 
struct x11_screen {
Display *dpy;
int number;
 
/*
* This is used to fetch GLX visuals/fbconfigs. It steals code from GLX.
* It might be better to rewrite the part in Xlib or XCB.
*/
__GLXdisplayPrivate *glx_dpy;
 
int dri_major, dri_minor;
char *dri_driver;
char *dri_device;
int dri_fd;
 
x11_drawable_invalidate_buffers dri_invalidate_buffers;
void *dri_user_data;
 
XVisualInfo *visuals;
int num_visuals;
 
/* cached values for x11_drawable_get_depth */
Drawable last_drawable;
unsigned int last_depth;
};
 
 
/**
* Create a X11 screen.
*/
struct x11_screen *
x11_screen_create(Display *dpy, int screen)
{
struct x11_screen *xscr;
 
if (screen >= ScreenCount(dpy))
return NULL;
 
xscr = CALLOC_STRUCT(x11_screen);
if (xscr) {
xscr->dpy = dpy;
xscr->number = screen;
 
xscr->dri_major = -1;
xscr->dri_fd = -1;
}
return xscr;
}
 
/**
* Destroy a X11 screen.
*/
void
x11_screen_destroy(struct x11_screen *xscr)
{
if (xscr->dri_fd >= 0)
close(xscr->dri_fd);
free(xscr->dri_driver);
free(xscr->dri_device);
 
#ifdef GLX_DIRECT_RENDERING
/* xscr->glx_dpy will be destroyed with the X display */
if (xscr->glx_dpy)
xscr->glx_dpy->xscr = NULL;
#endif
 
free(xscr->visuals);
FREE(xscr);
}
 
#ifdef GLX_DIRECT_RENDERING
 
static boolean
x11_screen_init_dri2(struct x11_screen *xscr)
{
if (xscr->dri_major < 0) {
int eventBase, errorBase;
 
if (!DRI2QueryExtension(xscr->dpy, &eventBase, &errorBase) ||
!DRI2QueryVersion(xscr->dpy, &xscr->dri_major, &xscr->dri_minor))
xscr->dri_major = -1;
}
return (xscr->dri_major >= 0);
}
 
static boolean
x11_screen_init_glx(struct x11_screen *xscr)
{
if (!xscr->glx_dpy)
xscr->glx_dpy = __glXInitialize(xscr->dpy);
return (xscr->glx_dpy != NULL);
}
 
#endif /* GLX_DIRECT_RENDERING */
 
/**
* Return true if the screen supports the extension.
*/
boolean
x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext)
{
boolean supported = FALSE;
 
switch (ext) {
case X11_SCREEN_EXTENSION_XSHM:
supported = XShmQueryExtension(xscr->dpy);
break;
#ifdef GLX_DIRECT_RENDERING
case X11_SCREEN_EXTENSION_GLX:
supported = x11_screen_init_glx(xscr);
break;
case X11_SCREEN_EXTENSION_DRI2:
supported = x11_screen_init_dri2(xscr);
break;
#endif
default:
break;
}
 
return supported;
}
 
/**
* Return the X visuals.
*/
const XVisualInfo *
x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals)
{
if (!xscr->visuals) {
XVisualInfo vinfo_template;
vinfo_template.screen = xscr->number;
xscr->visuals = XGetVisualInfo(xscr->dpy, VisualScreenMask,
&vinfo_template, &xscr->num_visuals);
}
 
if (num_visuals)
*num_visuals = xscr->num_visuals;
return xscr->visuals;
}
 
/**
* Return the depth of a drawable.
*
* Unlike other drawable functions, the drawable needs not be a DRI2 drawable.
*/
uint
x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable)
{
unsigned int depth;
 
if (drawable != xscr->last_drawable) {
Window root;
int x, y;
unsigned int w, h, border;
Status ok;
 
ok = XGetGeometry(xscr->dpy, drawable, &root,
&x, &y, &w, &h, &border, &depth);
if (!ok)
depth = 0;
 
xscr->last_drawable = drawable;
xscr->last_depth = depth;
}
else {
depth = xscr->last_depth;
}
 
return depth;
}
 
#ifdef GLX_DIRECT_RENDERING
 
/**
* Return the GLX fbconfigs.
*/
const __GLcontextModes *
x11_screen_get_glx_configs(struct x11_screen *xscr)
{
return (x11_screen_init_glx(xscr))
? xscr->glx_dpy->screenConfigs[xscr->number]->configs
: NULL;
}
 
/**
* Probe the screen for the DRI2 driver name.
*/
const char *
x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor)
{
if (!x11_screen_init_dri2(xscr))
return NULL;
 
/* get the driver name and the device name */
if (!xscr->dri_driver) {
if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
&xscr->dri_driver, &xscr->dri_device))
xscr->dri_driver = xscr->dri_device = NULL;
}
if (major)
*major = xscr->dri_major;
if (minor)
*minor = xscr->dri_minor;
 
return xscr->dri_driver;
}
 
/**
* Enable DRI2 and returns the file descriptor of the DRM device. The file
* descriptor will be closed automatically when the screen is destoryed.
*/
int
x11_screen_enable_dri2(struct x11_screen *xscr,
x11_drawable_invalidate_buffers invalidate_buffers,
void *user_data)
{
if (xscr->dri_fd < 0) {
int fd;
drm_magic_t magic;
 
/* get the driver name and the device name first */
if (!x11_screen_probe_dri2(xscr, NULL, NULL))
return -1;
 
#ifdef O_CLOEXEC
fd = open(xscr->dri_device, O_RDWR | O_CLOEXEC);
if (fd == -1 && errno == EINVAL)
#endif
{
fd = open(xscr->dri_device, O_RDWR);
if (fd != -1)
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
}
if (fd < 0) {
_eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device);
return -1;
}
 
memset(&magic, 0, sizeof(magic));
if (drmGetMagic(fd, &magic)) {
_eglLog(_EGL_WARNING, "failed to get magic");
close(fd);
return -1;
}
 
if (!DRI2Authenticate(xscr->dpy,
RootWindow(xscr->dpy, xscr->number), magic)) {
_eglLog(_EGL_WARNING, "failed to authenticate magic");
close(fd);
return -1;
}
 
if (!x11_screen_init_glx(xscr)) {
_eglLog(_EGL_WARNING, "failed to initialize GLX");
close(fd);
return -1;
}
if (xscr->glx_dpy->xscr) {
_eglLog(_EGL_WARNING,
"display is already managed by another x11 screen");
close(fd);
return -1;
}
 
xscr->glx_dpy->xscr = xscr;
xscr->dri_invalidate_buffers = invalidate_buffers;
xscr->dri_user_data = user_data;
 
xscr->dri_fd = fd;
}
 
return xscr->dri_fd;
}
 
char *
x11_screen_get_device_name(struct x11_screen *xscr)
{
return xscr->dri_device;
}
 
int
x11_screen_authenticate(struct x11_screen *xscr, uint32_t id)
{
boolean authenticated;
 
authenticated = DRI2Authenticate(xscr->dpy,
RootWindow(xscr->dpy, xscr->number), id);
return authenticated ? 0 : -1;
}
 
/**
* Create/Destroy the DRI drawable.
*/
void
x11_drawable_enable_dri2(struct x11_screen *xscr,
Drawable drawable, boolean on)
{
if (on)
DRI2CreateDrawable(xscr->dpy, drawable);
else
DRI2DestroyDrawable(xscr->dpy, drawable);
}
 
/**
* Copy between buffers of the DRI2 drawable.
*/
void
x11_drawable_copy_buffers_region(struct x11_screen *xscr, Drawable drawable,
int num_rects, const int *rects,
int src_buf, int dst_buf)
{
XserverRegion region;
XRectangle *rectangles = CALLOC(num_rects, sizeof(XRectangle));
 
for (int i = 0; i < num_rects; i++) {
rectangles[i].x = rects[i * 4 + 0];
rectangles[i].y = rects[i * 4 + 1];
rectangles[i].width = rects[i * 4 + 2];
rectangles[i].height = rects[i * 4 + 3];
}
 
region = XFixesCreateRegion(xscr->dpy, rectangles, num_rects);
DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf);
XFixesDestroyRegion(xscr->dpy, region);
FREE(rectangles);
}
 
/**
* Get the buffers of the DRI2 drawable. The returned array should be freed.
*/
struct x11_drawable_buffer *
x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
int *width, int *height, unsigned int *attachments,
boolean with_format, int num_ins, int *num_outs)
{
DRI2Buffer *dri2bufs;
 
if (with_format)
dri2bufs = DRI2GetBuffersWithFormat(xscr->dpy, drawable, width, height,
attachments, num_ins, num_outs);
else
dri2bufs = DRI2GetBuffers(xscr->dpy, drawable, width, height,
attachments, num_ins, num_outs);
 
return (struct x11_drawable_buffer *) dri2bufs;
}
 
/**
* Create a mode list of the given size.
*/
__GLcontextModes *
x11_context_modes_create(unsigned count)
{
const size_t size = sizeof(__GLcontextModes);
__GLcontextModes *base = NULL;
__GLcontextModes **next;
unsigned i;
 
next = &base;
for (i = 0; i < count; i++) {
*next = (__GLcontextModes *) CALLOC(1, size);
if (*next == NULL) {
x11_context_modes_destroy(base);
base = NULL;
break;
}
next = &((*next)->next);
}
 
return base;
}
 
/**
* Destroy a mode list.
*/
void
x11_context_modes_destroy(__GLcontextModes *modes)
{
while (modes != NULL) {
__GLcontextModes *next = modes->next;
FREE(modes);
modes = next;
}
}
 
/**
* Return the number of the modes in the mode list.
*/
unsigned
x11_context_modes_count(const __GLcontextModes *modes)
{
const __GLcontextModes *mode;
int count = 0;
for (mode = modes; mode; mode = mode->next)
count++;
return count;
}
 
extern void
dri2InvalidateBuffers(Display *dpy, XID drawable);
 
/**
* This is called from src/glx/dri2.c.
*/
void
dri2InvalidateBuffers(Display *dpy, XID drawable)
{
__GLXdisplayPrivate *priv = __glXInitialize(dpy);
struct x11_screen *xscr = NULL;
 
if (priv && priv->xscr)
xscr = priv->xscr;
if (!xscr || !xscr->dri_invalidate_buffers)
return;
 
xscr->dri_invalidate_buffers(xscr, drawable, xscr->dri_user_data);
}
 
extern unsigned
dri2GetSwapEventType(Display *dpy, XID drawable);
 
extern void *
dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id);
 
extern void *
GetGLXDrawable(Display *dpy, XID drawable);
 
/**
* This is also called from src/glx/dri2.c.
*/
unsigned dri2GetSwapEventType(Display *dpy, XID drawable)
{
return 0;
}
 
void *
dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
{
return NULL;
}
 
void *
GetGLXDrawable(Display *dpy, XID drawable)
{
return NULL;
}
 
#endif /* GLX_DIRECT_RENDERING */
/contrib/sdk/sources/Mesa/src/gallium/state_trackers/egl/x11/x11_screen.h
0,0 → 1,133
/*
* Mesa 3-D graphics library
*
* Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
 
#ifndef _X11_SCREEN_H_
#define _X11_SCREEN_H_
 
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/dri2tokens.h>
#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
#include "glcore.h" /* for __GLcontextModes */
#include "pipe/p_compiler.h"
#include "common/native.h"
 
enum x11_screen_extension {
X11_SCREEN_EXTENSION_XSHM,
X11_SCREEN_EXTENSION_GLX,
X11_SCREEN_EXTENSION_DRI2,
};
 
/* the same as DRI2Buffer */
struct x11_drawable_buffer {
unsigned int attachment;
unsigned int name;
unsigned int pitch;
unsigned int cpp;
unsigned int flags;
};
 
struct x11_screen;
 
typedef void (*x11_drawable_invalidate_buffers)(struct x11_screen *xscr,
Drawable drawable,
void *user_data);
 
struct x11_screen *
x11_screen_create(Display *dpy, int screen);
 
void
x11_screen_destroy(struct x11_screen *xscr);
 
boolean
x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext);
 
const XVisualInfo *
x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals);
 
uint
x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable);
 
#ifdef GLX_DIRECT_RENDERING
 
/* GLX */
const __GLcontextModes *
x11_screen_get_glx_configs(struct x11_screen *xscr);
 
const __GLcontextModes *
x11_screen_get_glx_visuals(struct x11_screen *xscr);
 
__GLcontextModes *
x11_context_modes_create(unsigned count);
 
void
x11_context_modes_destroy(__GLcontextModes *modes);
 
unsigned
x11_context_modes_count(const __GLcontextModes *modes);
 
/* DRI2 */
const char *
x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor);
 
int
x11_screen_enable_dri2(struct x11_screen *xscr,
x11_drawable_invalidate_buffers invalidate_buffers,
void *user_data);
 
char *
x11_screen_get_device_name(struct x11_screen *xscr);
 
int
x11_screen_authenticate(struct x11_screen *xscr, uint32_t id);
 
void
x11_drawable_enable_dri2(struct x11_screen *xscr,
Drawable drawable, boolean on);
 
void
x11_drawable_copy_buffers_region(struct x11_screen *xscr, Drawable drawable,
int num_rects, const int *rects,
int src_buf, int dst_buf);
 
/**
* Copy between buffers of the DRI2 drawable.
*/
static INLINE void
x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
int x, int y, int width, int height,
int src_buf, int dst_buf)
{
int rect[4] = { x, y, width, height };
x11_drawable_copy_buffers_region(xscr, drawable, 1, rect, src_buf, dst_buf);
}
 
struct x11_drawable_buffer *
x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
int *width, int *height, unsigned int *attachments,
boolean with_format, int num_ins, int *num_outs);
 
#endif /* GLX_DIRECT_RENDERING */
 
#endif /* _X11_SCREEN_H_ */