/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, ®istry_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, ®istry_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_ */ |