Merge remote-tracking branch 'origin/5.4.0' into 5.4
Change-Id: I95f235a66ce2e9b1fa435c0f911c6f7e811755f0
This commit is contained in:
commit
245acbf6e8
7
configure
vendored
7
configure
vendored
@ -3157,6 +3157,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then
|
||||
CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples"
|
||||
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
|
||||
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qtwebkit qtwebkit-examples"
|
||||
CFG_PRECOMPILE="no" # Precompiled headers not supported with multiple -arch arguments
|
||||
|
||||
# If the user passes -sdk on the command line we build a SDK-specific Qt build.
|
||||
# Otherwise we build a joined simulator and device build, which is the default.
|
||||
@ -5788,7 +5789,11 @@ fi
|
||||
[ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES"
|
||||
[ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS"
|
||||
|
||||
if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
|
||||
if [ "$XPLATFORM_MAC" = "yes" ] && [ "$QT_CROSS_COMPILE" = "no" ]; then
|
||||
if [ "$CFG_RPATH" = "yes" ]; then
|
||||
QMAKE_CONFIG="$QMAKE_CONFIG absolute_library_soname"
|
||||
fi
|
||||
elif [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
|
||||
if [ -n "$RPATH_FLAGS" ]; then
|
||||
echo
|
||||
echo "ERROR: -R cannot be used on this platform as \$QMAKE_LFLAGS_RPATH is"
|
||||
|
43
dist/changes-5.4.0
vendored
43
dist/changes-5.4.0
vendored
@ -47,3 +47,46 @@ OS X
|
||||
- OS X 10.10 is now supported.
|
||||
- QMacStyle has been updated with better OS 10.10 support.
|
||||
- The Qt binary packages are now configured with C++11 enabled.
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
- [QTBUG-38259] Changed configure defaults so that Qt5Core does not
|
||||
link against ICU libraries anymore. Pass '-icu' to enable it.
|
||||
|
||||
****************************************************************************
|
||||
* Tools *
|
||||
****************************************************************************
|
||||
|
||||
configure & build system
|
||||
------------------------
|
||||
|
||||
- The -process/-fully-process/-dont-process configure options have been
|
||||
removed due to being unnecessary and counterproductive.
|
||||
- [QTBUG-36955] The -vcproj configure option was removed. Use "qmake -r -tp vc"
|
||||
_after_ building Qt in case you want to use Visual Studio to work on Qt.
|
||||
- [QTBUG-37961] Qt plugins contain version info again.
|
||||
- [QTBUG-39216] Fixed more cases where the Qt build would pick up headers
|
||||
from a pre-existing Qt installation.
|
||||
- [QTBUG-41267] Fixed parallelized (jom) -debug-and-release builds.
|
||||
|
||||
qmake
|
||||
-----
|
||||
|
||||
- [QTBUG-21910][Unix] Added 'make dist' target for SUBDIRS projects.
|
||||
- [QTBUG-32895][iOS] Fixed structure of bundles. They can be signed now.
|
||||
- [QTBUG-26782][VS] Fixed handling of TARGET_EXT.
|
||||
- [QTBUG-30712][VS] Fixed handling of QMAKE_LIBFLAGS.
|
||||
- [QTBUG-30373][VS] Using different RESOURCES in different build variants
|
||||
no longer produces invalid vcxproj files.
|
||||
- [QTBUG-37520][VS] Made it possible to suppress qmake warnings about
|
||||
unknown compiler options. CONFIG+=suppress_vcproj_warnings.
|
||||
- [QTBUG-37363][MSVC2012+] embed_manifest_exe is now properly supported.
|
||||
- [QTBUG-41504][MSVC2012+] Building DLLs targeting Windows XP is now
|
||||
supported. As a side effect, Windows CE makespecs must not add /ENTRY: to
|
||||
QMAKE_LFLAGS_CONSOLE any more. The flag is hard-coded in console.prf now.
|
||||
- [QTBUG-35318][Xcode] Fixed QMAKE_BUNDLE_DATA's path resolution.
|
||||
- [QTBUG-39527] Fixed qtCompile() when used with jom -jN.
|
||||
- QMAKE_EXTRA_COMPILERS' commands and depend_command are no longer mangled.
|
||||
Use $$shell_path() and $$shell_quote() to prepare the commands correctly.
|
||||
- Added link-time optimization support for Clang, GCC and ICC. CONFIG+=ltgc.
|
||||
|
@ -359,7 +359,9 @@ h3.fn, span.fn {
|
||||
margin: 0px;
|
||||
margin-top: 45px;
|
||||
}
|
||||
|
||||
h3.fn code {
|
||||
float: right;
|
||||
}
|
||||
h3.fn:target {
|
||||
background-color: #F6F6D6;
|
||||
}
|
||||
@ -705,8 +707,21 @@ Landing page
|
||||
float: left;
|
||||
}
|
||||
|
||||
.icons1of3 h2 {
|
||||
.icons1of3 h2, .doc-column h2 {
|
||||
font-size: 15px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div.multi-column {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.multi-column div {
|
||||
display: -moz-inline-box;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-top: 1em;
|
||||
margin-right: 4em;
|
||||
width: 24em;
|
||||
}
|
||||
|
@ -7,6 +7,9 @@ QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc
|
||||
QMAKE_CC = clang
|
||||
QMAKE_CXX = clang++
|
||||
|
||||
QMAKE_LINK_C = $$QMAKE_CC
|
||||
QMAKE_LINK_C_SHLIB = $$QMAKE_CC
|
||||
|
||||
QMAKE_LINK = $$QMAKE_CXX
|
||||
QMAKE_LINK_SHLIB = $$QMAKE_CXX
|
||||
|
||||
|
@ -52,6 +52,12 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR
|
||||
unset(modpath)
|
||||
}
|
||||
|
||||
mac {
|
||||
!isEmpty(QMAKE_RPATHDIR){
|
||||
CONFIG += absolute_library_soname
|
||||
}
|
||||
}
|
||||
|
||||
cross_compile: \
|
||||
CONFIG += force_bootstrap
|
||||
|
||||
|
@ -94,6 +94,8 @@ else: \
|
||||
|
||||
# OS X and iOS frameworks
|
||||
mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
|
||||
# Set the CFBundleIdentifier prefix for Qt frameworks
|
||||
QMAKE_TARGET_BUNDLE_PREFIX = org.qt-project
|
||||
#QMAKE_FRAMEWORK_VERSION = 4.0
|
||||
CONFIG += lib_bundle sliced_bundle qt_framework
|
||||
CONFIG -= qt_install_headers #no need to install these as well
|
||||
@ -111,9 +113,6 @@ mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
|
||||
}
|
||||
}
|
||||
|
||||
mac:contains(QT_CONFIG, rpath): \
|
||||
QMAKE_SONAME_PREFIX = @rpath
|
||||
|
||||
mac {
|
||||
CONFIG += explicitlib
|
||||
macx-g++ {
|
||||
|
@ -11,7 +11,7 @@ rcc.name = RCC ${QMAKE_FILE_IN}
|
||||
rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
|
||||
rcc.CONFIG += add_inputs_as_makefile_deps
|
||||
|
||||
resources_small|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") {
|
||||
!resources_big|ltcg|macx-xcode|contains(TEMPLATE, "vc.*") {
|
||||
|
||||
rcc.output = $$RCC_DIR/$${first(QMAKE_MOD_RCC)}_${QMAKE_FILE_BASE}$${first(QMAKE_EXT_CPP)}
|
||||
rcc.commands = $$QMAKE_RCC $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -24,6 +24,8 @@
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
|
45
mkspecs/macx-ios-clang/LaunchScreen.xib
Normal file
45
mkspecs/macx-ios-clang/LaunchScreen.xib
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
|
||||
<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"6250\" systemVersion=\"14A343f\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\">
|
||||
<dependencies>
|
||||
<plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"6244\"/>
|
||||
<capability name=\"Constraints with non-1.0 multipliers\" minToolsVersion=\"5.1\"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File\'s Owner\"/>
|
||||
<placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>
|
||||
<view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">
|
||||
<rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"480\"/>
|
||||
<autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>
|
||||
<subviews>
|
||||
<label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" misplaced=\"YES\" text=\"\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"9\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8ie-xW-0ye\">
|
||||
<rect key=\"frame\" x=\"20\" y=\"439\" width=\"441\" height=\"21\"/>
|
||||
<fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>
|
||||
<color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>
|
||||
<nil key=\"highlightedColor\"/>
|
||||
<variation key=\"widthClass=compact\">
|
||||
<fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"11\"/>
|
||||
</variation>
|
||||
</label>
|
||||
<label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"$$TARGET\"
|
||||
textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"kId-c2-rCX\">
|
||||
<rect key=\"frame\" x=\"20\" y=\"140\" width=\"441\" height=\"43\"/>
|
||||
<fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"36\"/>
|
||||
<color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>
|
||||
<nil key=\"highlightedColor\"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>
|
||||
<constraints>
|
||||
<constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"centerY\" secondItem=\"iN0-l3-epB\" secondAttribute=\"bottom\" multiplier=\"1/3\" constant=\"1\" id=\"Kid-kn-2rF\"/>
|
||||
<constraint firstAttribute=\"centerX\" secondItem=\"kId-c2-rCX\" secondAttribute=\"centerX\" id=\"Koa-jz-hwk\"/>
|
||||
<constraint firstAttribute=\"bottom\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"bottom\" constant=\"20\" id=\"Kzo-t9-V3l\"/>
|
||||
<constraint firstItem=\"8ie-xW-0ye\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"MfP-vx-nX0\"/>
|
||||
<constraint firstAttribute=\"centerX\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"centerX\" id=\"ZEH-qu-HZ9\"/>
|
||||
<constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"fvb-Df-36g\"/>
|
||||
</constraints>
|
||||
<nil key=\"simulatedStatusBarMetrics\"/>
|
||||
<freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>
|
||||
<point key=\"canvasLocation\" x=\"404\" y=\"445\"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
@ -184,6 +184,14 @@ macx-xcode {
|
||||
QMAKE_SUBSTITUTES += copy_image
|
||||
launch_images.files = $$copy_image.output
|
||||
QMAKE_BUNDLE_DATA += launch_images
|
||||
|
||||
# Set up default LaunchScreen to support iPhone6/6+
|
||||
launch_screen = LaunchScreen.xib
|
||||
copy_launch_screen.input = $$QMAKESPEC/$$launch_screen
|
||||
copy_launch_screen.output = $$OUT_PWD/$${TARGET}.xcodeproj/$$launch_screen
|
||||
QMAKE_SUBSTITUTES += copy_launch_screen
|
||||
launch_screens.files = $$copy_launch_screen.output
|
||||
QMAKE_BUNDLE_DATA += launch_screens
|
||||
}
|
||||
|
||||
macx-xcode {
|
||||
@ -193,22 +201,32 @@ macx-xcode {
|
||||
arch_iphonesimulator.value = $$QMAKE_IOS_SIMULATOR_ARCHS
|
||||
|
||||
QMAKE_MAC_XCODE_SETTINGS += arch_iphoneos arch_iphonesimulator
|
||||
unset(QMAKE_XCODE_ARCHS)
|
||||
QMAKE_XCODE_ARCHS = $$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS
|
||||
|
||||
only_active_arch.name = ONLY_ACTIVE_ARCH
|
||||
only_active_arch.value = YES
|
||||
only_active_arch.build = debug
|
||||
QMAKE_MAC_XCODE_SETTINGS += only_active_arch
|
||||
} else {
|
||||
# Be more specific about which architecture we're targeting
|
||||
contains(QT_ARCH, arm.*): \
|
||||
actual_archs = $$QMAKE_IOS_DEVICE_ARCHS
|
||||
VALID_ARCHS = $$QMAKE_IOS_DEVICE_ARCHS
|
||||
else: \
|
||||
actual_archs = $$QMAKE_IOS_SIMULATOR_ARCHS
|
||||
VALID_ARCHS = $$QMAKE_IOS_SIMULATOR_ARCHS
|
||||
|
||||
for(arch, actual_archs): \
|
||||
arch_flags += -arch $$arch
|
||||
single_arch: VALID_ARCHS = $$first(VALID_ARCHS)
|
||||
|
||||
ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS))
|
||||
ARCH_ARGS = $(foreach arch, $(if $(EXPORT_ACTIVE_ARCHS), $(EXPORT_ACTIVE_ARCHS), $(EXPORT_VALID_ARCHS)), -arch $(arch))
|
||||
|
||||
QMAKE_EXTRA_VARIABLES += VALID_ARCHS ACTIVE_ARCHS ARCH_ARGS
|
||||
|
||||
arch_flags = $(EXPORT_ARCH_ARGS)
|
||||
|
||||
QMAKE_CFLAGS += $$arch_flags
|
||||
QMAKE_CXXFLAGS += $$arch_flags
|
||||
QMAKE_OBJECTIVE_CFLAGS += $$arch_flags
|
||||
QMAKE_LFLAGS += $$arch_flags
|
||||
}
|
||||
unset(actual_archs)
|
||||
|
||||
load(default_post)
|
||||
|
@ -32,17 +32,19 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) {
|
||||
# called 'qt_main' now.
|
||||
|
||||
macx-xcode {
|
||||
objects_dir = "${OBJECT_FILE_DIR}-${CURRENT_VARIANT}/${CURRENT_ARCH}"
|
||||
objects_dir = "${OBJECT_FILE_DIR}-${CURRENT_VARIANT}"
|
||||
archs = "${ARCHS}"
|
||||
} else {
|
||||
objects_dir = $$OBJECTS_DIR
|
||||
isEmpty(objects_dir): \
|
||||
objects_dir = .
|
||||
archs = "$$QMAKE_IOS_DEVICE_ARCHS $$QMAKE_IOS_SIMULATOR_ARCHS"
|
||||
}
|
||||
|
||||
!isEmpty(QMAKE_PRE_LINK): \
|
||||
QMAKE_PRE_LINK += ";"
|
||||
|
||||
QMAKE_PRE_LINK += $$QMAKESPEC/rename_main.sh $${objects_dir}
|
||||
QMAKE_PRE_LINK += $$QMAKESPEC/rename_main.sh $${objects_dir} \"$${archs}\"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,4 +9,8 @@ isEmpty(QT_ARCH) {
|
||||
QT_ARCH = arm
|
||||
else: \ # Simulator
|
||||
QT_ARCH = i386
|
||||
|
||||
# Prevent the arch/config tests from building as multi-arch binaries,
|
||||
# as we only want the lowest common denominator features.
|
||||
CONFIG += single_arch
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG
|
||||
# Universal target (iPhone and iPad)
|
||||
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2
|
||||
|
||||
QMAKE_IOS_DEVICE_ARCHS = armv7
|
||||
QMAKE_IOS_SIMULATOR_ARCHS = i386
|
||||
QMAKE_IOS_DEVICE_ARCHS = armv7 arm64
|
||||
QMAKE_IOS_SIMULATOR_ARCHS = i386 x86_64
|
||||
|
||||
include(../common/ios.conf)
|
||||
include(../common/gcc-base-mac.conf)
|
||||
|
@ -41,10 +41,14 @@
|
||||
##
|
||||
#############################################################################
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "usage: $0 <path to object files>"
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "$0: wrong number of arguments for internal tool used by iOS mkspec"
|
||||
else
|
||||
for f in $(find $1 -name '*.o'); do
|
||||
arch_paths=""
|
||||
for a in $2; do
|
||||
arch_paths="$arch_paths $1/$a"
|
||||
done
|
||||
for f in $(find $arch_paths -name '*.o'); do
|
||||
# Skip object files without the _main symbol
|
||||
nm $f 2>/dev/null | grep -q 'T _main$' || continue
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
|
@ -13,6 +13,7 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
|
||||
QMAKE_INCDIR = /usr/local/include
|
||||
QMAKE_LIBDIR = /usr/local/lib
|
||||
|
||||
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
|
||||
QMAKE_LFLAGS_THREAD = -pthread
|
||||
|
||||
QMAKE_LIBS =
|
||||
@ -28,6 +29,5 @@ QMAKE_RANLIB =
|
||||
|
||||
include(../../common/unix.conf)
|
||||
include(../../common/gcc-base-unix.conf)
|
||||
include(../../common/g++-unix.conf)
|
||||
include(../../common/clang.conf)
|
||||
load(qt_config)
|
||||
|
@ -1029,6 +1029,21 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
if (!project->isEmpty("QMAKE_PRE_LINK")) {
|
||||
QString phase_key = keyFor("QMAKE_PBX_PRELINK_BUILDPHASE");
|
||||
project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
|
||||
|
||||
ProStringList inputPaths;
|
||||
ProStringList outputPaths;
|
||||
const ProStringList &archs = project->values("QMAKE_XCODE_ARCHS");
|
||||
if (!archs.isEmpty()) {
|
||||
for (int i = 0; i < archs.size(); ++i) {
|
||||
const ProString &arch = archs.at(i);
|
||||
inputPaths << "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/" + arch + "/";
|
||||
outputPaths << "$(LINK_FILE_LIST_$(CURRENT_VARIANT)_" + arch + ")";
|
||||
}
|
||||
} else {
|
||||
inputPaths << "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/";
|
||||
outputPaths << "$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))";
|
||||
}
|
||||
|
||||
t << "\t\t" << phase_key << " = {\n"
|
||||
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n"
|
||||
@ -1036,8 +1051,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
// resolved dependenices, so we have to ensure that this phase is run after the
|
||||
// compilation phase, and before the link phase. Making the phase depend on the
|
||||
// object file directory, and "write" to the list of files to link achieves that.
|
||||
<< "\t\t\t" << writeSettings("inputPaths", ProStringList("$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("outputPaths", ProStringList("$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))"), SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("inputPaths", inputPaths, SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("outputPaths", outputPaths, SettingsAsList, 4) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n"
|
||||
|
@ -814,22 +814,26 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
}
|
||||
commonSedArgs << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
|
||||
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" ";
|
||||
|
||||
QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
|
||||
if (bundlePrefix.isEmpty())
|
||||
bundlePrefix = "com.yourcompany";
|
||||
if (bundlePrefix.endsWith("."))
|
||||
bundlePrefix.chop(1);
|
||||
QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE");
|
||||
if (bundleIdentifier.endsWith(".app"))
|
||||
bundleIdentifier.chop(4);
|
||||
if (bundleIdentifier.endsWith(".framework"))
|
||||
bundleIdentifier.chop(10);
|
||||
commonSedArgs << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" ";
|
||||
|
||||
if (isApp) {
|
||||
QString icon = fileFixify(var("ICON"));
|
||||
QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
|
||||
if (bundlePrefix.isEmpty())
|
||||
bundlePrefix = "com.yourcompany";
|
||||
if (bundlePrefix.endsWith("."))
|
||||
bundlePrefix.chop(1);
|
||||
QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE");
|
||||
if (bundleIdentifier.endsWith(".app"))
|
||||
bundleIdentifier.chop(4);
|
||||
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
|
||||
<< "@sed ";
|
||||
foreach (const ProString &arg, commonSedArgs)
|
||||
t << arg;
|
||||
t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" "
|
||||
<< "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" "
|
||||
<< "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" "
|
||||
<< "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
|
||||
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
|
||||
|
@ -1915,10 +1915,10 @@ bool VCXProjectWriter::outputFileConfig(OutputFilterData *d, XmlOutput &xml, Xml
|
||||
}
|
||||
|
||||
// Actual XML output ----------------------------------
|
||||
if (hasCustomBuildStep || filter.useCompilerTool
|
||||
if (hasCustomBuildStep || filter.useCustomBuildTool || filter.useCompilerTool
|
||||
|| !d->inBuild || filter.Name.startsWith("Deployment Files")) {
|
||||
|
||||
if (hasCustomBuildStep)
|
||||
if (hasCustomBuildStep || filter.useCustomBuildTool)
|
||||
{
|
||||
if (!fileAdded) {
|
||||
fileAdded = true;
|
||||
|
2
src/3rdparty/angle/AUTHORS
vendored
2
src/3rdparty/angle/AUTHORS
vendored
@ -21,10 +21,12 @@ Mozilla Corporation
|
||||
Turbulenz
|
||||
Klarälvdalens Datakonsult AB
|
||||
Microsoft Open Technologies, Inc.
|
||||
NVIDIA Corporation
|
||||
|
||||
Jacek Caban
|
||||
Mark Callow
|
||||
Ginn Chen
|
||||
Tibor den Ouden
|
||||
James Hauxwell
|
||||
Sam Hocevar
|
||||
Pierre Leveille
|
||||
|
5
src/3rdparty/angle/CONTRIBUTORS
vendored
5
src/3rdparty/angle/CONTRIBUTORS
vendored
@ -78,7 +78,12 @@ Turbulenz
|
||||
Ulrik Persson (ddefrostt)
|
||||
Mark Banner (standard8mbp)
|
||||
David Kilzer
|
||||
Jacek Caban
|
||||
Tibor den Ouden
|
||||
|
||||
Microsoft Open Technologies, Inc.
|
||||
Cooper Partin
|
||||
Austin Kinross
|
||||
|
||||
NVIDIA Corporation
|
||||
Olli Etuaho
|
||||
|
2
src/3rdparty/angle/include/EGL/egl.h
vendored
2
src/3rdparty/angle/include/EGL/egl.h
vendored
@ -238,7 +238,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
|
||||
#ifndef EGL_VERSION_1_5
|
||||
#define EGL_VERSION_1_5 1
|
||||
typedef void *EGLSync;
|
||||
typedef khronos_intptr_t EGLAttrib;
|
||||
typedef intptr_t EGLAttrib;
|
||||
typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
|
||||
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
|
||||
|
16
src/3rdparty/angle/include/EGL/eglext.h
vendored
16
src/3rdparty/angle/include/EGL/eglext.h
vendored
@ -59,7 +59,7 @@ extern "C" {
|
||||
#ifndef EGL_KHR_cl_event2
|
||||
#define EGL_KHR_cl_event2 1
|
||||
typedef void *EGLSyncKHR;
|
||||
typedef khronos_intptr_t EGLAttribKHR;
|
||||
typedef intptr_t EGLAttribKHR;
|
||||
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
|
||||
@ -442,20 +442,22 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
|
||||
#define EGL_ANGLE_platform_angle 1
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3205
|
||||
#endif /* EGL_ANGLE_platform_angle */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_d3d
|
||||
#define EGL_ANGLE_platform_angle_d3d 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
|
||||
#endif /* EGL_ANGLE_platform_angle_d3d */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_opengl
|
||||
#define EGL_ANGLE_platform_angle_opengl 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3209
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A
|
||||
#endif /* EGL_ANGLE_platform_angle_opengl */
|
||||
|
||||
#ifndef EGL_ARM_pixmap_multisample_discard
|
||||
|
19
src/3rdparty/angle/include/EGL/eglplatform.h
vendored
19
src/3rdparty/angle/include/EGL/eglplatform.h
vendored
@ -67,23 +67,22 @@
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
|
||||
|
||||
struct IUnknown;
|
||||
|
||||
typedef IUnknown *EGLNativeDisplayType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
typedef IUnknown *EGLNativeWindowType;
|
||||
|
||||
#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */
|
||||
#include <inspectable.h>
|
||||
typedef IInspectable* EGLNativeDisplayType;
|
||||
typedef IInspectable* EGLNativeWindowType;
|
||||
#else
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
#endif
|
||||
|
||||
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
|
||||
|
210
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
210
src/3rdparty/angle/include/GLSLANG/ShaderLang.h
vendored
@ -27,6 +27,10 @@
|
||||
|
||||
#include "KHR/khrplatform.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
@ -42,18 +46,17 @@ typedef unsigned int GLenum;
|
||||
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
|
||||
#include "ShaderVars.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented every time the API changes.
|
||||
#define ANGLE_SH_VERSION 130
|
||||
#define ANGLE_SH_VERSION 132
|
||||
|
||||
typedef enum {
|
||||
SH_GLES2_SPEC = 0x8B40,
|
||||
SH_WEBGL_SPEC = 0x8B41,
|
||||
|
||||
SH_GLES3_SPEC = 0x8B86,
|
||||
SH_WEBGL2_SPEC = 0x8B87,
|
||||
|
||||
// The CSS Shaders spec is a subset of the WebGL spec.
|
||||
//
|
||||
// In both CSS vertex and fragment shaders, ANGLE:
|
||||
@ -85,31 +88,6 @@ typedef enum {
|
||||
SH_HLSL11_OUTPUT = 0x8B48
|
||||
} ShShaderOutput;
|
||||
|
||||
typedef enum {
|
||||
SH_PRECISION_HIGHP = 0x5001,
|
||||
SH_PRECISION_MEDIUMP = 0x5002,
|
||||
SH_PRECISION_LOWP = 0x5003,
|
||||
SH_PRECISION_UNDEFINED = 0
|
||||
} ShPrecisionType;
|
||||
|
||||
typedef enum {
|
||||
SH_INFO_LOG_LENGTH = 0x8B84,
|
||||
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
|
||||
SH_ACTIVE_UNIFORMS = 0x8B86,
|
||||
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
|
||||
SH_ACTIVE_ATTRIBUTES = 0x8B89,
|
||||
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
|
||||
SH_VARYINGS = 0x8BBB,
|
||||
SH_VARYING_MAX_LENGTH = 0x8BBC,
|
||||
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
|
||||
SH_NAME_MAX_LENGTH = 0x6001,
|
||||
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
|
||||
SH_HASHED_NAMES_COUNT = 0x6003,
|
||||
SH_SHADER_VERSION = 0x6004,
|
||||
SH_RESOURCES_STRING_LENGTH = 0x6005,
|
||||
SH_OUTPUT_TYPE = 0x6006
|
||||
} ShShaderInfo;
|
||||
|
||||
// Compile options.
|
||||
typedef enum {
|
||||
SH_VALIDATE = 0,
|
||||
@ -208,14 +186,14 @@ typedef enum {
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler operations.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
COMPILER_EXPORT int ShInitialize();
|
||||
COMPILER_EXPORT bool ShInitialize();
|
||||
//
|
||||
// Driver should call this at shutdown.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
COMPILER_EXPORT int ShFinalize();
|
||||
COMPILER_EXPORT bool ShFinalize();
|
||||
|
||||
// The 64 bits hash function. The first parameter is the input string; the
|
||||
// second parameter is the string length.
|
||||
@ -246,6 +224,12 @@ typedef struct
|
||||
int EXT_frag_depth;
|
||||
int EXT_shader_texture_lod;
|
||||
|
||||
// Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
|
||||
// with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
|
||||
// EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
|
||||
// function. This applies to Tegra K1 devices.
|
||||
int NV_draw_buffers;
|
||||
|
||||
// Set to 1 if highp precision is supported in the fragment language.
|
||||
// Default is 0.
|
||||
int FragmentPrecisionHigh;
|
||||
@ -274,8 +258,10 @@ typedef struct
|
||||
|
||||
//
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
// Parameters:
|
||||
// resources: The object to initialize. Will be comparable with memcmp.
|
||||
//
|
||||
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
|
||||
|
||||
//
|
||||
// ShHandle held by but opaque to the driver. It is allocated,
|
||||
@ -284,18 +270,15 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
|
||||
//
|
||||
// If handle creation fails, 0 will be returned.
|
||||
//
|
||||
typedef void* ShHandle;
|
||||
typedef void *ShHandle;
|
||||
|
||||
//
|
||||
// Returns the a concatenated list of the items in ShBuiltInResources as a string.
|
||||
// Returns the a concatenated list of the items in ShBuiltInResources as a
|
||||
// null-terminated string.
|
||||
// This function must be updated whenever ShBuiltInResources is changed.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of the compiler to be used.
|
||||
// outStringLen: Specifies the size of the buffer, in number of characters. The size
|
||||
// of the buffer required to store the resources string can be obtained
|
||||
// by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH.
|
||||
// outStr: Returns a null-terminated string representing all the built-in resources.
|
||||
COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr);
|
||||
COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
|
||||
|
||||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
@ -313,12 +296,12 @@ COMPILER_EXPORT ShHandle ShConstructCompiler(
|
||||
sh::GLenum type,
|
||||
ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources* resources);
|
||||
const ShBuiltInResources *resources);
|
||||
COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
|
||||
//
|
||||
// Compiles the given shader source.
|
||||
// If the function succeeds, the return value is nonzero, else zero.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
// Parameters:
|
||||
// handle: Specifies the handle of compiler to be used.
|
||||
// shaderStrings: Specifies an array of pointers to null-terminated strings
|
||||
@ -340,123 +323,36 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
|
||||
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
|
||||
// Can be queried by calling ShGetVariableInfo().
|
||||
//
|
||||
COMPILER_EXPORT int ShCompile(
|
||||
COMPILER_EXPORT bool ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const char * const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions
|
||||
);
|
||||
int compileOptions);
|
||||
|
||||
// Returns a parameter from a compiled shader.
|
||||
// Return the version of the shader language.
|
||||
COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
|
||||
|
||||
// Return the currently set language output type.
|
||||
COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
|
||||
const ShHandle handle);
|
||||
|
||||
// Returns null-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// pname: Specifies the parameter to query.
|
||||
// The following parameters are defined:
|
||||
// SH_INFO_LOG_LENGTH: the number of characters in the information log
|
||||
// including the null termination character.
|
||||
// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
|
||||
// including the null termination character.
|
||||
// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
|
||||
// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
|
||||
// variable name including the null
|
||||
// termination character.
|
||||
// SH_VARYINGS: the number of varying variables.
|
||||
// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
|
||||
// including the null termination character.
|
||||
// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
|
||||
// the null termination character.
|
||||
// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
|
||||
// null termination character.
|
||||
// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
|
||||
// null termination character.
|
||||
// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
|
||||
// SH_SHADER_VERSION: the version of the shader language
|
||||
// SH_OUTPUT_TYPE: the currently set language output type
|
||||
//
|
||||
// params: Requested parameter
|
||||
COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
|
||||
ShShaderInfo pname,
|
||||
size_t* params);
|
||||
|
||||
// Returns nul-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the information log. It is assumed that infoLog has enough memory
|
||||
// to accomodate the information log. The size of the buffer required
|
||||
// to store the returned information log can be obtained by calling
|
||||
// ShGetInfo with SH_INFO_LOG_LENGTH.
|
||||
COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
|
||||
COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
|
||||
|
||||
// Returns null-terminated object code for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// infoLog: Specifies an array of characters that is used to return
|
||||
// the object code. It is assumed that infoLog has enough memory to
|
||||
// accomodate the object code. The size of the buffer required to
|
||||
// store the returned object code can be obtained by calling
|
||||
// ShGetInfo with SH_OBJECT_CODE_LENGTH.
|
||||
COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
|
||||
COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
|
||||
|
||||
// Returns information about a shader variable.
|
||||
// Returns a (original_name, hash) map containing all the user defined
|
||||
// names in the shader, including variable names, function names, struct
|
||||
// names, and struct field names.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// variableType: Specifies the variable type; options include
|
||||
// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
|
||||
// index: Specifies the index of the variable to be queried.
|
||||
// length: Returns the number of characters actually written in the string
|
||||
// indicated by name (excluding the null terminator) if a value other
|
||||
// than NULL is passed.
|
||||
// size: Returns the size of the variable.
|
||||
// type: Returns the data type of the variable.
|
||||
// precision: Returns the precision of the variable.
|
||||
// staticUse: Returns 1 if the variable is accessed in a statement after
|
||||
// pre-processing, whether or not run-time flow of control will
|
||||
// cause that statement to be executed.
|
||||
// Returns 0 otherwise.
|
||||
// name: Returns a null terminated string containing the name of the
|
||||
// variable. It is assumed that name has enough memory to accormodate
|
||||
// the variable name. The size of the buffer required to store the
|
||||
// variable name can be obtained by calling ShGetInfo with
|
||||
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
|
||||
// SH_VARYING_MAX_LENGTH.
|
||||
// mappedName: Returns a null terminated string containing the mapped name of
|
||||
// the variable, It is assumed that mappedName has enough memory
|
||||
// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
|
||||
// mapped name. If the name is not mapped, then name and mappedName
|
||||
// are the same.
|
||||
COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
|
||||
ShShaderInfo variableType,
|
||||
int index,
|
||||
size_t* length,
|
||||
int* size,
|
||||
sh::GLenum* type,
|
||||
ShPrecisionType* precision,
|
||||
int* staticUse,
|
||||
char* name,
|
||||
char* mappedName);
|
||||
|
||||
// Returns information about a name hashing entry from the latest compile.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// index: Specifies the index of the name hashing entry to be queried.
|
||||
// name: Returns a null terminated string containing the user defined name.
|
||||
// It is assumed that name has enough memory to accomodate the name.
|
||||
// The size of the buffer required to store the user defined name can
|
||||
// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
|
||||
// hashedName: Returns a null terminated string containing the hashed name of
|
||||
// the uniform variable, It is assumed that hashedName has enough
|
||||
// memory to accomodate the name. The size of the buffer required
|
||||
// to store the name can be obtained by calling ShGetInfo with
|
||||
// SH_HASHED_NAME_MAX_LENGTH.
|
||||
COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
|
||||
int index,
|
||||
char* name,
|
||||
char* hashedName);
|
||||
COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
|
||||
const ShHandle handle);
|
||||
|
||||
// Shader variable inspection.
|
||||
// Returns a pointer to a list of variables of the designated type.
|
||||
@ -476,17 +372,17 @@ typedef struct
|
||||
int size;
|
||||
} ShVariableInfo;
|
||||
|
||||
// Returns 1 if the passed in variables pack in maxVectors following
|
||||
// Returns true if the passed in variables pack in maxVectors following
|
||||
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
|
||||
// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
||||
// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
||||
// flag above.
|
||||
// Parameters:
|
||||
// maxVectors: the available rows of registers.
|
||||
// varInfoArray: an array of variable info (types and sizes).
|
||||
// varInfoArraySize: the size of the variable array.
|
||||
COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
|
||||
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
|
||||
int maxVectors,
|
||||
ShVariableInfo* varInfoArray,
|
||||
ShVariableInfo *varInfoArray,
|
||||
size_t varInfoArraySize);
|
||||
|
||||
// Gives the compiler-assigned register for an interface block.
|
||||
@ -497,7 +393,7 @@ COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
|
||||
// interfaceBlockName: Specifies the interface block
|
||||
// indexOut: output variable that stores the assigned register
|
||||
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
const char *interfaceBlockName,
|
||||
const std::string &interfaceBlockName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
// Gives the compiler-assigned register for uniforms in the default
|
||||
@ -509,11 +405,7 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
// interfaceBlockName: Specifies the uniform
|
||||
// indexOut: output variable that stores the assigned register
|
||||
COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
|
||||
const char *uniformName,
|
||||
const std::string &uniformName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _COMPILER_INTERFACE_INCLUDED_
|
||||
|
64
src/3rdparty/angle/include/GLSLANG/ShaderVars.h
vendored
64
src/3rdparty/angle/include/GLSLANG/ShaderVars.h
vendored
@ -52,6 +52,21 @@ struct COMPILER_EXPORT ShaderVariable
|
||||
unsigned int elementCount() const { return std::max(1u, arraySize); }
|
||||
bool isStruct() const { return !fields.empty(); }
|
||||
|
||||
// All of the shader's variables are described using nested data
|
||||
// structures. This is needed in order to disambiguate similar looking
|
||||
// types, such as two structs containing the same fields, but in
|
||||
// different orders. "findInfoByMappedName" provides an easy query for
|
||||
// users to dive into the data structure and fetch the unique variable
|
||||
// instance corresponding to a dereferencing chain of the top-level
|
||||
// variable.
|
||||
// Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
|
||||
// that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
|
||||
// in |originalName|, based on the assumption that |this| defines 'a'.
|
||||
// If no match is found, return false.
|
||||
bool findInfoByMappedName(const std::string &mappedFullName,
|
||||
const ShaderVariable **leafVar,
|
||||
std::string* originalFullName) const;
|
||||
|
||||
GLenum type;
|
||||
GLenum precision;
|
||||
std::string name;
|
||||
@ -60,6 +75,16 @@ struct COMPILER_EXPORT ShaderVariable
|
||||
bool staticUse;
|
||||
std::vector<ShaderVariable> fields;
|
||||
std::string structName;
|
||||
|
||||
protected:
|
||||
bool isSameVariableAtLinkTime(const ShaderVariable &other,
|
||||
bool matchPrecision) const;
|
||||
|
||||
bool operator==(const ShaderVariable &other) const;
|
||||
bool operator!=(const ShaderVariable &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
struct COMPILER_EXPORT Uniform : public ShaderVariable
|
||||
@ -68,6 +93,16 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable
|
||||
~Uniform();
|
||||
Uniform(const Uniform &other);
|
||||
Uniform &operator=(const Uniform &other);
|
||||
bool operator==(const Uniform &other) const;
|
||||
bool operator!=(const Uniform &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// Decide whether two uniforms are the same at shader link time,
|
||||
// assuming one from vertex shader and the other from fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.5.
|
||||
bool isSameUniformAtLinkTime(const Uniform &other) const;
|
||||
};
|
||||
|
||||
struct COMPILER_EXPORT Attribute : public ShaderVariable
|
||||
@ -76,6 +111,11 @@ struct COMPILER_EXPORT Attribute : public ShaderVariable
|
||||
~Attribute();
|
||||
Attribute(const Attribute &other);
|
||||
Attribute &operator=(const Attribute &other);
|
||||
bool operator==(const Attribute &other) const;
|
||||
bool operator!=(const Attribute &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
int location;
|
||||
};
|
||||
@ -86,6 +126,18 @@ struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
|
||||
~InterfaceBlockField();
|
||||
InterfaceBlockField(const InterfaceBlockField &other);
|
||||
InterfaceBlockField &operator=(const InterfaceBlockField &other);
|
||||
bool operator==(const InterfaceBlockField &other) const;
|
||||
bool operator!=(const InterfaceBlockField &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// Decide whether two InterfaceBlock fields are the same at shader
|
||||
// link time, assuming one from vertex shader and the other from
|
||||
// fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.7.
|
||||
bool isSameInterfaceBlockFieldAtLinkTime(
|
||||
const InterfaceBlockField &other) const;
|
||||
|
||||
bool isRowMajorLayout;
|
||||
};
|
||||
@ -94,8 +146,18 @@ struct COMPILER_EXPORT Varying : public ShaderVariable
|
||||
{
|
||||
Varying();
|
||||
~Varying();
|
||||
Varying(const Varying &other);
|
||||
Varying(const Varying &otherg);
|
||||
Varying &operator=(const Varying &other);
|
||||
bool operator==(const Varying &other) const;
|
||||
bool operator!=(const Varying &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// Decide whether two varyings are the same at shader link time,
|
||||
// assuming one from vertex shader and the other from fragment shader.
|
||||
// See GLSL ES Spec 3.00.3, sec 4.3.9.
|
||||
bool isSameVaryingAtLinkTime(const Varying &other) const;
|
||||
|
||||
InterpolationType interpolation;
|
||||
bool isInvariant;
|
||||
|
37
src/3rdparty/angle/include/angle_windowsstore.h
vendored
Normal file
37
src/3rdparty/angle/include/angle_windowsstore.h
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// angle_windowsstore.h:
|
||||
|
||||
#ifndef ANGLE_WINDOWSSTORE_H_
|
||||
#define ANGLE_WINDOWSSTORE_H_
|
||||
|
||||
// The following properties can be set on the CoreApplication to support additional
|
||||
// ANGLE configuration options.
|
||||
//
|
||||
// The Visual Studio sample templates provided with this version of ANGLE have examples
|
||||
// of how to set these property values.
|
||||
|
||||
//
|
||||
// Property: EGLNativeWindowTypeProperty
|
||||
// Type: IInspectable
|
||||
// Description: Set this property to specify the window type to use for creating a surface.
|
||||
// If this property is missing, surface creation will fail.
|
||||
//
|
||||
const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
|
||||
|
||||
//
|
||||
// Property: EGLRenderSurfaceSizeProperty
|
||||
// Type: Size
|
||||
// Description: Set this property to specify a preferred size in pixels of the render surface.
|
||||
// The render surface size width and height must be greater than 0.
|
||||
// If this property is set, then the render surface size is fixed.
|
||||
// If this property is missing, a default behavior will be provided.
|
||||
// The default behavior uses the window size if a CoreWindow is specified or
|
||||
// the size of the SwapChainPanel control if one is specified.
|
||||
//
|
||||
const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty";
|
||||
|
||||
#endif // ANGLE_WINDOWSSTORE_H_
|
4
src/3rdparty/angle/src/commit.h
vendored
4
src/3rdparty/angle/src/commit.h
vendored
@ -7,6 +7,6 @@
|
||||
// This is a default commit hash header, when git is not available.
|
||||
//
|
||||
|
||||
#define ANGLE_COMMIT_HASH "abce76206141"
|
||||
#define ANGLE_COMMIT_HASH "30d6c255d238"
|
||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||
#define ANGLE_COMMIT_DATE "2014-09-23 19:37:05 +0000"
|
||||
#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
|
||||
|
82
src/3rdparty/angle/src/common/NativeWindow.h
vendored
Normal file
82
src/3rdparty/angle/src/common/NativeWindow.h
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// NativeWindow.h: Defines NativeWindow, a class for managing and
|
||||
// performing operations on an EGLNativeWindowType.
|
||||
// It is used for HWND (Desktop Windows) and IInspectable objects
|
||||
//(Windows Store Applications).
|
||||
|
||||
#ifndef COMMON_NATIVEWINDOW_H_
|
||||
#define COMMON_NATIVEWINDOW_H_
|
||||
|
||||
#include <EGL/eglplatform.h>
|
||||
#include "common/debug.h"
|
||||
#include "common/platform.h"
|
||||
|
||||
// DXGISwapChain and DXGIFactory are typedef'd to specific required
|
||||
// types. The HWND NativeWindow implementation requires IDXGISwapChain
|
||||
// and IDXGIFactory and the Windows Store NativeWindow
|
||||
// implementation requires IDXGISwapChain1 and IDXGIFactory2.
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
typedef IDXGISwapChain1 DXGISwapChain;
|
||||
typedef IDXGIFactory2 DXGIFactory;
|
||||
|
||||
#include <wrl.h>
|
||||
#include <wrl/wrappers/corewrappers.h>
|
||||
#include <windows.applicationmodel.core.h>
|
||||
#include <memory>
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class InspectableNativeWindow;
|
||||
}
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
|
||||
#else
|
||||
typedef IDXGISwapChain DXGISwapChain;
|
||||
typedef IDXGIFactory DXGIFactory;
|
||||
#endif
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
class NativeWindow
|
||||
{
|
||||
public:
|
||||
explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display);
|
||||
|
||||
bool initialize();
|
||||
bool getClientRect(LPRECT rect);
|
||||
bool isIconic();
|
||||
|
||||
# if defined(ANGLE_ENABLE_D3D11)
|
||||
typedef ID3D11Device Device;
|
||||
#else
|
||||
typedef IDirect3DDevice9 Device;
|
||||
#endif
|
||||
HRESULT createSwapChain(Device* device, DXGIFactory* factory,
|
||||
DXGI_FORMAT format, UINT width, UINT height,
|
||||
DXGISwapChain** swapChain);
|
||||
|
||||
inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
|
||||
inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; }
|
||||
|
||||
private:
|
||||
EGLNativeWindowType mWindow;
|
||||
EGLNativeDisplayType mDisplay;
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::shared_ptr<InspectableNativeWindow> mImpl;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
|
||||
}
|
||||
|
||||
#endif // COMMON_NATIVEWINDOW_H_
|
35
src/3rdparty/angle/src/common/angleutils.cpp
vendored
35
src/3rdparty/angle/src/common/angleutils.cpp
vendored
@ -5,26 +5,33 @@
|
||||
//
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
|
||||
{
|
||||
// Attempt to just print to the current buffer
|
||||
int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
|
||||
if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
|
||||
{
|
||||
// Buffer was not large enough, calculate the required size and resize the buffer
|
||||
len = vsnprintf(NULL, 0, fmt, vararg);
|
||||
outBuffer.resize(len + 1);
|
||||
|
||||
// Print again
|
||||
len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
|
||||
}
|
||||
ASSERT(len >= 0);
|
||||
return static_cast<size_t>(len);
|
||||
}
|
||||
|
||||
std::string FormatString(const char *fmt, va_list vararg)
|
||||
{
|
||||
static std::vector<char> buffer(512);
|
||||
|
||||
// Attempt to just print to the current buffer
|
||||
int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
|
||||
if (len < 0 || static_cast<size_t>(len) >= buffer.size())
|
||||
{
|
||||
// Buffer was not large enough, calculate the required size and resize the buffer
|
||||
len = vsnprintf(NULL, 0, fmt, vararg);
|
||||
buffer.resize(len + 1);
|
||||
|
||||
// Print again
|
||||
vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
|
||||
}
|
||||
|
||||
return std::string(buffer.data(), len);
|
||||
size_t len = FormatStringIntoVector(fmt, vararg, buffer);
|
||||
return std::string(&buffer[0], len);
|
||||
}
|
||||
|
||||
std::string FormatString(const char *fmt, ...)
|
||||
|
11
src/3rdparty/angle/src/common/angleutils.h
vendored
11
src/3rdparty/angle/src/common/angleutils.h
vendored
@ -17,6 +17,7 @@
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <cstdarg>
|
||||
#include <vector>
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions
|
||||
// This must be used in the private: declarations for a class
|
||||
@ -95,6 +96,13 @@ inline void StructZero(T *obj)
|
||||
memset(obj, 0, sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool IsMaskFlagSet(T mask, T flag)
|
||||
{
|
||||
// Handles multibit flags as well
|
||||
return (mask & flag) == flag;
|
||||
}
|
||||
|
||||
inline const char* MakeStaticString(const std::string &str)
|
||||
{
|
||||
static std::set<std::string> strings;
|
||||
@ -132,9 +140,12 @@ inline std::string Str(int i)
|
||||
return strstr.str();
|
||||
}
|
||||
|
||||
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
|
||||
|
||||
std::string FormatString(const char *fmt, va_list vararg);
|
||||
std::string FormatString(const char *fmt, ...);
|
||||
|
||||
// snprintf is not defined with MSVC prior to to msvc14
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
246
src/3rdparty/angle/src/common/debug.cpp
vendored
246
src/3rdparty/angle/src/common/debug.cpp
vendored
@ -17,41 +17,211 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
|
||||
#else
|
||||
typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
|
||||
#endif
|
||||
|
||||
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
// Wraps the D3D9/D3D11 debug annotation functions.
|
||||
class DebugAnnotationWrapper
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
|
||||
std::string formattedMessage = FormatString(format, vararg);
|
||||
public:
|
||||
DebugAnnotationWrapper() { };
|
||||
virtual ~DebugAnnotationWrapper() { };
|
||||
virtual void beginEvent(const std::wstring &eventName) = 0;
|
||||
virtual void endEvent() = 0;
|
||||
virtual void setMarker(const std::wstring &markerName) = 0;
|
||||
virtual bool getStatus() = 0;
|
||||
};
|
||||
|
||||
#if defined(ANGLE_ENABLE_D3D9)
|
||||
class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper
|
||||
{
|
||||
public:
|
||||
void beginEvent(const std::wstring &eventName)
|
||||
{
|
||||
D3DPERF_BeginEvent(0, eventName.c_str());
|
||||
}
|
||||
|
||||
void endEvent()
|
||||
{
|
||||
D3DPERF_EndEvent();
|
||||
}
|
||||
|
||||
void setMarker(const std::wstring &markerName)
|
||||
{
|
||||
D3DPERF_SetMarker(0, markerName.c_str());
|
||||
}
|
||||
|
||||
bool getStatus()
|
||||
{
|
||||
return !!D3DPERF_GetStatus();
|
||||
}
|
||||
};
|
||||
#endif // ANGLE_ENABLE_D3D9
|
||||
|
||||
#if defined(ANGLE_ENABLE_D3D11)
|
||||
class D3D11DebugAnnotationWrapper : public DebugAnnotationWrapper
|
||||
{
|
||||
public:
|
||||
|
||||
D3D11DebugAnnotationWrapper()
|
||||
: mInitialized(false),
|
||||
mD3d11Module(NULL),
|
||||
mUserDefinedAnnotation(NULL)
|
||||
{
|
||||
// D3D11 devices can't be created during DllMain.
|
||||
// We defer device creation until the object is actually used.
|
||||
}
|
||||
|
||||
~D3D11DebugAnnotationWrapper()
|
||||
{
|
||||
if (mInitialized)
|
||||
{
|
||||
SafeRelease(mUserDefinedAnnotation);
|
||||
FreeLibrary(mD3d11Module);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void beginEvent(const std::wstring &eventName)
|
||||
{
|
||||
initializeDevice();
|
||||
|
||||
mUserDefinedAnnotation->BeginEvent(eventName.c_str());
|
||||
}
|
||||
|
||||
virtual void endEvent()
|
||||
{
|
||||
initializeDevice();
|
||||
|
||||
mUserDefinedAnnotation->EndEvent();
|
||||
}
|
||||
|
||||
virtual void setMarker(const std::wstring &markerName)
|
||||
{
|
||||
initializeDevice();
|
||||
|
||||
mUserDefinedAnnotation->SetMarker(markerName.c_str());
|
||||
}
|
||||
|
||||
virtual bool getStatus()
|
||||
{
|
||||
// ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
|
||||
|
||||
#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
// In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
|
||||
// This should only be called in DEBUG mode.
|
||||
// If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
|
||||
IDXGraphicsAnalysis* graphicsAnalysis;
|
||||
DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
|
||||
bool underCapture = (graphicsAnalysis != NULL);
|
||||
SafeRelease(graphicsAnalysis);
|
||||
return underCapture;
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
// Otherwise, we have to return true here.
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void initializeDevice()
|
||||
{
|
||||
if (!mInitialized)
|
||||
{
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
|
||||
ASSERT(mD3d11Module);
|
||||
|
||||
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
|
||||
ASSERT(D3D11CreateDevice != NULL);
|
||||
#endif // !ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
||||
ID3D11Device* device = NULL;
|
||||
ID3D11DeviceContext* context = NULL;
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
// Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
|
||||
hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = context->QueryInterface(__uuidof(mUserDefinedAnnotation), reinterpret_cast<void**>(&mUserDefinedAnnotation));
|
||||
ASSERT(SUCCEEDED(hr) && mUserDefinedAnnotation != NULL);
|
||||
|
||||
SafeRelease(device);
|
||||
SafeRelease(context);
|
||||
|
||||
mInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool mInitialized;
|
||||
HMODULE mD3d11Module;
|
||||
ID3DUserDefinedAnnotation* mUserDefinedAnnotation;
|
||||
};
|
||||
#endif // ANGLE_ENABLE_D3D11
|
||||
|
||||
static DebugAnnotationWrapper* g_DebugAnnotationWrapper = NULL;
|
||||
|
||||
void InitializeDebugAnnotations()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_D3D9)
|
||||
g_DebugAnnotationWrapper = new D3D9DebugAnnotationWrapper();
|
||||
#elif defined(ANGLE_ENABLE_D3D11)
|
||||
// If the project uses D3D9 then we can use the D3D9 debug annotations, even with the D3D11 renderer.
|
||||
// However, if D3D9 is unavailable (e.g. in Windows Store), then we use D3D11 debug annotations.
|
||||
// The D3D11 debug annotations are methods on ID3DUserDefinedAnnotation, which is implemented by the DeviceContext.
|
||||
// This doesn't have to be the same DeviceContext that the renderer uses, though.
|
||||
g_DebugAnnotationWrapper = new D3D11DebugAnnotationWrapper();
|
||||
#endif
|
||||
}
|
||||
|
||||
void UninitializeDebugAnnotations()
|
||||
{
|
||||
if (g_DebugAnnotationWrapper != NULL)
|
||||
{
|
||||
SafeDelete(g_DebugAnnotationWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
|
||||
enum DebugTraceOutputType
|
||||
{
|
||||
DebugTraceOutputTypeNone,
|
||||
DebugTraceOutputTypeSetMarker,
|
||||
DebugTraceOutputTypeBeginEvent
|
||||
};
|
||||
|
||||
static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const char *format, va_list vararg)
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
static std::vector<char> buffer(512);
|
||||
|
||||
if (perfActive())
|
||||
{
|
||||
// The perf function only accepts wide strings, widen the ascii message
|
||||
static std::wstring wideMessage;
|
||||
if (wideMessage.capacity() < formattedMessage.length())
|
||||
size_t len = FormatStringIntoVector(format, vararg, buffer);
|
||||
std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
|
||||
|
||||
switch (outputType)
|
||||
{
|
||||
wideMessage.reserve(formattedMessage.size());
|
||||
case DebugTraceOutputTypeNone:
|
||||
break;
|
||||
case DebugTraceOutputTypeBeginEvent:
|
||||
g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
|
||||
break;
|
||||
case DebugTraceOutputTypeSetMarker:
|
||||
g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
|
||||
|
||||
perfFunc(0, wideMessage.c_str());
|
||||
}
|
||||
#endif // ANGLE_ENABLE_PERF
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
|
||||
#if defined(ANGLE_ENABLE_TRACE)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
#if defined(NDEBUG)
|
||||
if (traceFileDebugOnly)
|
||||
if (traceInDebugOnly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
std::string formattedMessage = FormatString(format, vararg);
|
||||
|
||||
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
|
||||
if (file)
|
||||
@ -60,25 +230,29 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c
|
||||
file.flush();
|
||||
}
|
||||
|
||||
#endif // ANGLE_ENABLE_TRACE
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
|
||||
OutputDebugStringA(formattedMessage.c_str());
|
||||
#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
|
||||
|
||||
#endif // ANGLE_ENABLE_DEBUG_TRACE
|
||||
}
|
||||
|
||||
void trace(bool traceFileDebugOnly, const char *format, ...)
|
||||
void trace(bool traceInDebugOnly, const char *format, ...)
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
|
||||
#else
|
||||
output(traceFileDebugOnly, NULL, format, vararg);
|
||||
output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
|
||||
#endif
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
bool perfActive()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
static bool active = D3DPERF_GetStatus() != 0;
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
static bool active = g_DebugAnnotationWrapper->getStatus();
|
||||
return active;
|
||||
#else
|
||||
return false;
|
||||
@ -87,26 +261,28 @@ bool perfActive()
|
||||
|
||||
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
#if !defined(ANGLE_ENABLE_TRACE)
|
||||
#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
if (!perfActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_TRACE
|
||||
#endif // !ANGLE_ENABLE_DEBUG_TRACE
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
|
||||
#else
|
||||
output(true, DebugTraceOutputTypeNone, format, vararg);
|
||||
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
va_end(vararg);
|
||||
#endif // ANGLE_ENABLE_PERF
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::~ScopedPerfEventHelper()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
if (perfActive())
|
||||
{
|
||||
D3DPERF_EndEvent();
|
||||
g_DebugAnnotationWrapper->endEvent();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
19
src/3rdparty/angle/src/common/debug.h
vendored
19
src/3rdparty/angle/src/common/debug.h
vendored
@ -20,8 +20,8 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
// Outputs text to the debugging log
|
||||
void trace(bool traceFileDebugOnly, const char *format, ...);
|
||||
// Outputs text to the debugging log, or the debugging window
|
||||
void trace(bool traceInDebugOnly, const char *format, ...);
|
||||
|
||||
// Returns whether D3DPERF is active.
|
||||
bool perfActive();
|
||||
@ -36,31 +36,34 @@ namespace gl
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
|
||||
};
|
||||
|
||||
void InitializeDebugAnnotations();
|
||||
void UninitializeDebugAnnotations();
|
||||
}
|
||||
|
||||
// A macro to output a trace of a function call and its arguments to the debugging log
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define TRACE(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define FIXME(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
// A macro to output a function call and its arguments to the debugging log, in case of error.
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define ERR(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
// A macro to log a performance event around a scope.
|
||||
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#if defined(_MSC_VER)
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
|
||||
#else
|
||||
@ -83,7 +86,7 @@ namespace gl
|
||||
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
|
||||
#endif
|
||||
|
||||
#ifndef ANGLE_ENABLE_TRACE
|
||||
#ifndef ANGLE_ENABLE_DEBUG_TRACE
|
||||
#define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
|
||||
#else
|
||||
#define UNUSED_TRACE_VARIABLE(variable)
|
||||
@ -128,7 +131,7 @@ namespace gl
|
||||
#endif
|
||||
|
||||
// A macro functioning as a compile-time assert to validate constant conditions
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
#if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GNUC__) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3))
|
||||
#define META_ASSERT_MSG(condition, msg) static_assert(condition, msg)
|
||||
#else
|
||||
#define META_ASSERT_CONCAT(a, b) a ## b
|
||||
|
35
src/3rdparty/angle/src/common/features.h
vendored
Normal file
35
src/3rdparty/angle/src/common/features.h
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#define ANGLE_DISABLED 0
|
||||
#define ANGLE_ENABLED 1
|
||||
|
||||
// Feature defaults
|
||||
|
||||
// Direct3D9EX
|
||||
// The "Debug This Pixel..." feature in PIX often fails when using the
|
||||
// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
|
||||
// machine, define "ANGLE_D3D9EX=0" in your project file.
|
||||
#if !defined(ANGLE_D3D9EX)
|
||||
#define ANGLE_D3D9EX ANGLE_ENABLED
|
||||
#endif
|
||||
|
||||
// Vsync
|
||||
// ENABLED allows Vsync to be configured at runtime
|
||||
// DISABLED disallows Vsync
|
||||
#if !defined(ANGLE_VSYNC)
|
||||
#define ANGLE_VSYNC ANGLE_ENABLED
|
||||
#endif
|
||||
|
||||
// Program binary loading
|
||||
#if !defined(ANGLE_PROGRAM_BINARY_LOAD)
|
||||
#define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED
|
||||
#endif
|
||||
|
||||
// Shader debug info
|
||||
#if !defined(ANGLE_SHADER_DEBUG_INFO)
|
||||
#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED
|
||||
#endif
|
4
src/3rdparty/angle/src/common/mathutil.h
vendored
4
src/3rdparty/angle/src/common/mathutil.h
vendored
@ -109,7 +109,7 @@ inline unsigned int unorm(float x)
|
||||
|
||||
inline bool supportsSSE2()
|
||||
{
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
|
||||
static bool checked = false;
|
||||
static bool supports = false;
|
||||
|
||||
@ -118,7 +118,6 @@ inline bool supportsSSE2()
|
||||
return supports;
|
||||
}
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid()
|
||||
int info[4];
|
||||
__cpuid(info, 0);
|
||||
|
||||
@ -128,7 +127,6 @@ inline bool supportsSSE2()
|
||||
|
||||
supports = (info[3] >> 26) & 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
checked = true;
|
||||
|
||||
|
90
src/3rdparty/angle/src/common/platform.h
vendored
90
src/3rdparty/angle/src/common/platform.h
vendored
@ -11,9 +11,6 @@
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define ANGLE_PLATFORM_WINDOWS 1
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
||||
# define ANGLE_PLATFORM_WINRT 1
|
||||
# endif
|
||||
#elif defined(__APPLE__)
|
||||
# define ANGLE_PLATFORM_APPLE 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
@ -37,6 +34,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
# define ANGLE_ENABLE_WINDOWS_STORE 1
|
||||
# endif
|
||||
# ifndef STRICT
|
||||
# define STRICT 1
|
||||
# endif
|
||||
@ -50,8 +50,9 @@
|
||||
# include <windows.h>
|
||||
# include <intrin.h>
|
||||
|
||||
# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
|
||||
# if defined(ANGLE_ENABLE_D3D9)
|
||||
# include <d3d9.h>
|
||||
# include <dxgi.h>
|
||||
# if !defined(COMPILER_IMPLEMENTATION)
|
||||
# include <d3dcompiler.h>
|
||||
# endif
|
||||
@ -62,13 +63,26 @@
|
||||
# include <d3d10.h>
|
||||
# include <d3d11.h>
|
||||
# include <dxgi.h>
|
||||
# if _MSC_VER >= 1700
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1700)
|
||||
# include <d3d11_1.h>
|
||||
# include <dxgi1_2.h>
|
||||
# endif
|
||||
# if !defined(COMPILER_IMPLEMENTATION)
|
||||
# include <d3dcompiler.h>
|
||||
# endif
|
||||
# if defined(__MINGW32__)
|
||||
# endif
|
||||
|
||||
# if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
# include <dxgi1_3.h>
|
||||
# if defined(_DEBUG)
|
||||
# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
|
||||
# include <DXProgrammableCapture.h>
|
||||
# endif
|
||||
# include <dxgidebug.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(__MINGW32__) // Missing defines on MinGW
|
||||
typedef enum D3D11_MAP_FLAG
|
||||
{
|
||||
D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
|
||||
@ -78,8 +92,68 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS
|
||||
UINT64 NumPrimitivesWritten;
|
||||
UINT64 PrimitivesStorageNeeded;
|
||||
} D3D11_QUERY_DATA_SO_STATISTICS;
|
||||
# endif
|
||||
# endif
|
||||
typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)(
|
||||
IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *,
|
||||
UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
|
||||
#define D3D11_MESSAGE_CATEGORY UINT
|
||||
#define D3D11_MESSAGE_SEVERITY UINT
|
||||
#define D3D11_MESSAGE_ID UINT
|
||||
struct D3D11_MESSAGE;
|
||||
typedef struct D3D11_INFO_QUEUE_FILTER_DESC
|
||||
{
|
||||
UINT NumCategories;
|
||||
D3D11_MESSAGE_CATEGORY *pCategoryList;
|
||||
UINT NumSeverities;
|
||||
D3D11_MESSAGE_SEVERITY *pSeverityList;
|
||||
UINT NumIDs;
|
||||
D3D11_MESSAGE_ID *pIDList;
|
||||
} D3D11_INFO_QUEUE_FILTER_DESC;
|
||||
typedef struct D3D11_INFO_QUEUE_FILTER
|
||||
{
|
||||
D3D11_INFO_QUEUE_FILTER_DESC AllowList;
|
||||
D3D11_INFO_QUEUE_FILTER_DESC DenyList;
|
||||
} D3D11_INFO_QUEUE_FILTER;
|
||||
static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
|
||||
MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
|
||||
virtual void __stdcall ClearStoredMessages() = 0;
|
||||
virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
|
||||
virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
|
||||
virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
|
||||
virtual UINT64 __stdcall GetNumStoredMessages() = 0;
|
||||
virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
|
||||
virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
|
||||
virtual UINT64 __stdcall GetMessageCountLimit() = 0;
|
||||
virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
|
||||
virtual void __stdcall ClearStorageFilter() = 0;
|
||||
virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
|
||||
virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
|
||||
virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual void __stdcall PopStorageFilter() = 0;
|
||||
virtual UINT __stdcall GetStorageFilterStackSize() = 0;
|
||||
virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
|
||||
virtual void __stdcall ClearRetrievalFilter() = 0;
|
||||
virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
|
||||
virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
|
||||
virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
|
||||
virtual void __stdcall PopRetrievalFilter() = 0;
|
||||
virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
|
||||
virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
|
||||
virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
|
||||
virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
|
||||
virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
|
||||
virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
|
||||
virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
|
||||
virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
|
||||
virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
|
||||
virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
|
||||
virtual BOOL __stdcall GetMuteDebugOutput() = 0;
|
||||
};
|
||||
#endif // __MINGW32__
|
||||
|
||||
# undef near
|
||||
# undef far
|
||||
|
107
src/3rdparty/angle/src/common/tls.cpp
vendored
107
src/3rdparty/angle/src/common/tls.cpp
vendored
@ -10,29 +10,50 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
#include <vector>
|
||||
std::vector<void *> *tls = nullptr;
|
||||
std::vector<TLSIndex> *freeIndices = nullptr;
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#include <wrl/client.h>
|
||||
#include <wrl/async.h>
|
||||
#include <Windows.System.Threading.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace ABI::Windows::System::Threading;
|
||||
|
||||
// Thread local storage for Windows Store support
|
||||
typedef vector<void*> ThreadLocalData;
|
||||
|
||||
static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
|
||||
static set<ThreadLocalData*> allThreadData;
|
||||
static DWORD nextTlsIndex = 0;
|
||||
static vector<DWORD> freeTlsIndices;
|
||||
|
||||
#endif
|
||||
|
||||
TLSIndex CreateTLSIndex()
|
||||
{
|
||||
TLSIndex index;
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!tls)
|
||||
tls = new std::vector<void *>;
|
||||
if (freeIndices && !freeIndices->empty()) {
|
||||
index = freeIndices->back();
|
||||
freeIndices->pop_back();
|
||||
return index;
|
||||
} else {
|
||||
tls->push_back(nullptr);
|
||||
return tls->size() - 1;
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
if (!freeTlsIndices.empty())
|
||||
{
|
||||
DWORD result = freeTlsIndices.back();
|
||||
freeTlsIndices.pop_back();
|
||||
index = result;
|
||||
}
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
else
|
||||
{
|
||||
index = nextTlsIndex++;
|
||||
}
|
||||
#else
|
||||
index = TlsAlloc();
|
||||
#endif
|
||||
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
// Create global pool key
|
||||
if ((pthread_key_create(&index, NULL)) != 0)
|
||||
@ -53,13 +74,23 @@ bool DestroyTLSIndex(TLSIndex index)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!freeIndices)
|
||||
freeIndices = new std::vector<TLSIndex>;
|
||||
freeIndices->push_back(index);
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
assert(index < nextTlsIndex);
|
||||
assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
|
||||
|
||||
freeTlsIndices.push_back(index);
|
||||
for (auto threadData : allThreadData)
|
||||
{
|
||||
if (threadData->size() > index)
|
||||
{
|
||||
threadData->at(index) = nullptr;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#elif ANGLE_PLATFORM_WINDOWS
|
||||
#else
|
||||
return (TlsFree(index) == TRUE);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return (pthread_key_delete(index) == 0);
|
||||
#endif
|
||||
@ -73,11 +104,25 @@ bool SetTLSValue(TLSIndex index, void *value)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
tls->at(index) = value;
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
ThreadLocalData* threadData = currentThreadData;
|
||||
if (!threadData)
|
||||
{
|
||||
threadData = new ThreadLocalData(index + 1, nullptr);
|
||||
allThreadData.insert(threadData);
|
||||
currentThreadData = threadData;
|
||||
}
|
||||
else if (threadData->size() <= index)
|
||||
{
|
||||
threadData->resize(index + 1, nullptr);
|
||||
}
|
||||
|
||||
threadData->at(index) = value;
|
||||
return true;
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#else
|
||||
return (TlsSetValue(index, value) == TRUE);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return (pthread_setspecific(index, value) == 0);
|
||||
#endif
|
||||
@ -85,18 +130,26 @@ bool SetTLSValue(TLSIndex index, void *value)
|
||||
|
||||
void *GetTLSValue(TLSIndex index)
|
||||
{
|
||||
#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation
|
||||
assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
|
||||
#endif
|
||||
if (index == TLS_INVALID_INDEX)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
return tls->at(index);
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
ThreadLocalData* threadData = currentThreadData;
|
||||
if (threadData && threadData->size() > index)
|
||||
{
|
||||
return threadData->at(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
return TlsGetValue(index);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return pthread_getspecific(index);
|
||||
#endif
|
||||
|
17
src/3rdparty/angle/src/common/tls.h
vendored
17
src/3rdparty/angle/src/common/tls.h
vendored
@ -11,11 +11,15 @@
|
||||
|
||||
#include "common/platform.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
typedef size_t TLSIndex;
|
||||
# define TLS_OUT_OF_INDEXES (static_cast<TLSIndex>(-1))
|
||||
# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
|
||||
// TLS does not exist for Windows Store and needs to be emulated
|
||||
# ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
# define TLS_OUT_OF_INDEXES -1
|
||||
# ifndef CREATE_SUSPENDED
|
||||
# define CREATE_SUSPENDED 0x00000004
|
||||
# endif
|
||||
# endif
|
||||
typedef DWORD TLSIndex;
|
||||
# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
@ -28,6 +32,9 @@
|
||||
# error Unsupported platform.
|
||||
#endif
|
||||
|
||||
// TODO(kbr): for POSIX platforms this will have to be changed to take
|
||||
// in a destructor function pointer, to allow the thread-local storage
|
||||
// to be properly deallocated upon thread exit.
|
||||
TLSIndex CreateTLSIndex();
|
||||
bool DestroyTLSIndex(TLSIndex index);
|
||||
|
||||
|
89
src/3rdparty/angle/src/common/utilities.cpp
vendored
89
src/3rdparty/angle/src/common/utilities.cpp
vendored
@ -9,17 +9,16 @@
|
||||
#include "common/utilities.h"
|
||||
#include "common/mathutil.h"
|
||||
#include "common/platform.h"
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
# include <locale>
|
||||
# include <codecvt>
|
||||
# include <wrl.h>
|
||||
# include <windows.storage.h>
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace ABI::Windows::Storage;
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
# include <wrl.h>
|
||||
# include <wrl/wrappers/corewrappers.h>
|
||||
# include <windows.applicationmodel.core.h>
|
||||
# include <windows.graphics.display.h>
|
||||
#endif
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
@ -447,50 +446,10 @@ int VariableSortOrder(GLenum type)
|
||||
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::string getTempPath()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
static std::string path;
|
||||
|
||||
while (path.empty())
|
||||
{
|
||||
ComPtr<IApplicationDataStatics> factory;
|
||||
Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData);
|
||||
HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory));
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
ComPtr<IApplicationData> applicationData;
|
||||
result = factory->get_Current(&applicationData);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
ComPtr<IStorageFolder> storageFolder;
|
||||
result = applicationData->get_LocalFolder(&storageFolder);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
ComPtr<IStorageItem> localFolder;
|
||||
result = storageFolder.As(&localFolder);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
HSTRING localFolderPath;
|
||||
result = localFolder->get_Path(&localFolderPath);
|
||||
if (FAILED(result))
|
||||
break;
|
||||
|
||||
std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
|
||||
path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
|
||||
if (path.empty())
|
||||
{
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
#elif defined(ANGLE_PLATFORM_WINDOWS)
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
char path[MAX_PATH];
|
||||
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
|
||||
if (pathLen == 0)
|
||||
@ -525,3 +484,33 @@ void writeFile(const char* path, const void* content, size_t size)
|
||||
fwrite(content, sizeof(char), size, file);
|
||||
fclose(file);
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
|
||||
void Sleep(unsigned long dwMilliseconds)
|
||||
{
|
||||
static HANDLE singletonEvent = nullptr;
|
||||
HANDLE sleepEvent = singletonEvent;
|
||||
if (!sleepEvent)
|
||||
{
|
||||
sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||
|
||||
if (!sleepEvent)
|
||||
return;
|
||||
|
||||
HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
|
||||
|
||||
if (previousEvent)
|
||||
{
|
||||
// Back out if multiple threads try to demand create at the same time.
|
||||
CloseHandle(sleepEvent);
|
||||
sleepEvent = previousEvent;
|
||||
}
|
||||
}
|
||||
|
||||
// Emulate sleep by waiting with timeout on an event that is never signalled.
|
||||
WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
|
||||
}
|
||||
|
||||
#endif // ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
6
src/3rdparty/angle/src/common/utilities.h
vendored
6
src/3rdparty/angle/src/common/utilities.h
vendored
@ -46,7 +46,13 @@ template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(
|
||||
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::string getTempPath();
|
||||
void writeFile(const char* path, const void* data, size_t size);
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
void Sleep(_In_ unsigned long dwMilliseconds);
|
||||
#endif
|
||||
|
||||
#endif // LIBGLESV2_UTILITIES_H
|
||||
|
66
src/3rdparty/angle/src/common/win32/NativeWindow.cpp
vendored
Normal file
66
src/3rdparty/angle/src/common/win32/NativeWindow.cpp
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// NativeWindow.cpp: Handler for managing HWND native window types.
|
||||
|
||||
#include "common/NativeWindow.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
|
||||
{
|
||||
return (IsWindow(window) == TRUE);
|
||||
}
|
||||
|
||||
NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display)
|
||||
{
|
||||
}
|
||||
|
||||
bool NativeWindow::initialize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeWindow::getClientRect(LPRECT rect)
|
||||
{
|
||||
return GetClientRect(mWindow, rect) == TRUE;
|
||||
}
|
||||
|
||||
bool NativeWindow::isIconic()
|
||||
{
|
||||
return IsIconic(mWindow) == TRUE;
|
||||
}
|
||||
|
||||
HRESULT NativeWindow::createSwapChain(NativeWindow::Device* device, DXGIFactory* factory,
|
||||
DXGI_FORMAT format, unsigned int width, unsigned int height,
|
||||
DXGISwapChain** swapChain)
|
||||
{
|
||||
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
|
||||
swapChainDesc.BufferCount = 1;
|
||||
swapChainDesc.BufferDesc.Format = format;
|
||||
swapChainDesc.BufferDesc.Width = width;
|
||||
swapChainDesc.BufferDesc.Height = height;
|
||||
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
|
||||
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||
swapChainDesc.Flags = 0;
|
||||
swapChainDesc.OutputWindow = mWindow;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.Windowed = TRUE;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
return factory->CreateSwapChain(device, &swapChainDesc, swapChain);
|
||||
}
|
||||
}
|
200
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
vendored
Normal file
200
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
|
||||
|
||||
#include <algorithm>
|
||||
#include "common/winrt/CoreWindowNativeWindow.h"
|
||||
using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
typedef ITypedEventHandler<ABI::Windows::UI::Core::CoreWindow *, ABI::Windows::UI::Core::WindowSizeChangedEventArgs *> SizeChangedHandler;
|
||||
|
||||
CoreWindowNativeWindow::~CoreWindowNativeWindow()
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
|
||||
bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
|
||||
{
|
||||
ComPtr<IPropertySet> props = propertySet;
|
||||
ComPtr<IInspectable> win = window;
|
||||
ComPtr<IInspectable> displayInformation = display;
|
||||
SIZE swapChainSize = {};
|
||||
bool swapChainSizeSpecified = false;
|
||||
HRESULT result = S_OK;
|
||||
|
||||
// IPropertySet is an optional parameter and can be null.
|
||||
// If one is specified, cache as an IMap and read the properties
|
||||
// used for initial host initialization.
|
||||
if (propertySet)
|
||||
{
|
||||
result = props.As(&mPropertyMap);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
|
||||
// was prevalidated to contain the EGLNativeWindowType before being passed to
|
||||
// this host.
|
||||
result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = win.As(&mCoreWindow);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = displayInformation.As(&mDisplayInformation);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation2> displayInformation2;
|
||||
result = mDisplayInformation.As(&displayInformation2);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
#else
|
||||
ABI::Windows::Graphics::Display::ResolutionScale resolutionScale;
|
||||
result = mDisplayInformation->get_ResolutionScale(&resolutionScale);
|
||||
ASSERT(SUCCEEDED(result));
|
||||
|
||||
mScaleFactor = DOUBLE(resolutionScale) / 100.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If a swapchain size is specfied, then the automatic resize
|
||||
// behaviors implemented by the host should be disabled. The swapchain
|
||||
// will be still be scaled when being rendered to fit the bounds
|
||||
// of the host.
|
||||
// Scaling of the swapchain output occurs automatically because if
|
||||
// the scaling mode setting DXGI_SCALING_STRETCH on the swapchain.
|
||||
if (swapChainSizeSpecified)
|
||||
{
|
||||
mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
|
||||
mSupportsSwapChainResize = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ABI::Windows::Foundation::Rect rect;
|
||||
HRESULT result = mCoreWindow->get_Bounds(&rect);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
LONG width = std::floor(rect.Width * mScaleFactor + 0.5);
|
||||
LONG height = std::floor(rect.Height * mScaleFactor + 0.5);
|
||||
mClientRect = { 0, 0, width, height };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
mNewClientRect = mClientRect;
|
||||
mClientRectChanged = false;
|
||||
return registerForSizeChangeEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoreWindowNativeWindow::registerForSizeChangeEvents()
|
||||
{
|
||||
HRESULT result = mCoreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &CoreWindowNativeWindow::onSizeChanged).Get(),
|
||||
&mSizeChangedEventToken);
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
|
||||
{
|
||||
if (mCoreWindow)
|
||||
{
|
||||
(void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
|
||||
}
|
||||
mSizeChangedEventToken.value = 0;
|
||||
}
|
||||
|
||||
HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
|
||||
{
|
||||
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
|
||||
swapChainDesc.Width = width;
|
||||
swapChainDesc.Height = height;
|
||||
swapChainDesc.Format = format;
|
||||
swapChainDesc.Stereo = FALSE;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||
swapChainDesc.BufferCount = 2;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
|
||||
*swapChain = nullptr;
|
||||
|
||||
ComPtr<IDXGISwapChain1> newSwapChain;
|
||||
HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
|
||||
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected
|
||||
// Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
|
||||
// other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
|
||||
// (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
|
||||
if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED)
|
||||
{
|
||||
mSupportsSwapChainResize = false;
|
||||
}
|
||||
#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
|
||||
result = newSwapChain.CopyTo(swapChain);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If automatic swapchain resize behaviors have been disabled, then
|
||||
// unregister for the resize change events.
|
||||
if (mSupportsSwapChainResize == false)
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Basically, this shouldn't be used on Phone
|
||||
HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
|
||||
{
|
||||
ABI::Windows::Foundation::Size size;
|
||||
if (SUCCEEDED(e->get_Size(&size)))
|
||||
{
|
||||
SIZE windowSizeInPixels = {
|
||||
std::floor(size.Width * mScaleFactor + 0.5),
|
||||
std::floor(size.Height * mScaleFactor + 0.5)
|
||||
};
|
||||
setNewClientSize(windowSizeInPixels);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
39
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
vendored
Normal file
39
src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types.
|
||||
|
||||
#ifndef COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
|
||||
#define COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
|
||||
|
||||
#include "common/winrt/InspectableNativeWindow.h"
|
||||
#include <memory>
|
||||
#include <windows.graphics.display.h>
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
|
||||
{
|
||||
public:
|
||||
~CoreWindowNativeWindow();
|
||||
|
||||
bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
|
||||
bool registerForSizeChangeEvents();
|
||||
void unregisterForSizeChangeEvents();
|
||||
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
|
||||
|
||||
private:
|
||||
HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
|
||||
|
||||
ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
|
||||
ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
|
||||
ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
|
274
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
vendored
Normal file
274
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
vendored
Normal file
@ -0,0 +1,274 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// InspectableNativeWindow.cpp: NativeWindow base class for managing IInspectable native window types.
|
||||
|
||||
#include "common/winrt/CoreWindowNativeWindow.h"
|
||||
#include "common/winrt/SwapChainPanelNativeWindow.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display)
|
||||
: mWindow(window), mDisplay(display)
|
||||
{
|
||||
}
|
||||
|
||||
bool NativeWindow::initialize()
|
||||
{
|
||||
// If the native window type is a IPropertySet, extract the
|
||||
// EGLNativeWindowType (IInspectable) and initialize the
|
||||
// proper host with this IPropertySet.
|
||||
ComPtr<ABI::Windows::Foundation::Collections::IPropertySet> propertySet;
|
||||
ComPtr<IInspectable> eglNativeWindow;
|
||||
if (IsEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow))
|
||||
{
|
||||
// A property set was found and the EGLNativeWindowType was
|
||||
// retrieved. The mWindow member of the host to must be updated
|
||||
// to use the EGLNativeWindowType specified in the property set.
|
||||
// mWindow is treated as a raw pointer not an AddRef'd interface, so
|
||||
// the old mWindow does not need a Release() before this assignment.
|
||||
mWindow = eglNativeWindow.Get();
|
||||
}
|
||||
|
||||
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
|
||||
if (IsCoreWindow(mWindow, &coreWindow))
|
||||
{
|
||||
mImpl = std::make_shared<CoreWindowNativeWindow>();
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
|
||||
}
|
||||
}
|
||||
else if (IsSwapChainPanel(mWindow, &swapChainPanel))
|
||||
{
|
||||
mImpl = std::make_shared<SwapChainPanelNativeWindow>();
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow, ISwapChainPanel and IPropertySet");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeWindow::getClientRect(RECT *rect)
|
||||
{
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->getClientRect(rect);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeWindow::isIconic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
|
||||
{
|
||||
if (mImpl)
|
||||
{
|
||||
return mImpl->createSwapChain(device, factory, format, width, height, swapChain);
|
||||
}
|
||||
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<IInspectable> win = window;
|
||||
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
|
||||
if (SUCCEEDED(win.As(&coreWin)))
|
||||
{
|
||||
if (coreWindow != nullptr)
|
||||
{
|
||||
*coreWindow = coreWin.Detach();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<IInspectable> win = window;
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> panel;
|
||||
if (SUCCEEDED(win.As(&panel)))
|
||||
{
|
||||
if (swapChainPanel != nullptr)
|
||||
{
|
||||
*swapChainPanel = panel.Detach();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet, IInspectable **eglNativeWindow)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ComPtr<IInspectable> props = window;
|
||||
ComPtr<IPropertySet> propSet;
|
||||
ComPtr<IInspectable> nativeWindow;
|
||||
ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> propMap;
|
||||
boolean hasEglNativeWindowPropertyKey = false;
|
||||
|
||||
HRESULT result = props.As(&propSet);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propSet.As(&propMap);
|
||||
}
|
||||
|
||||
// Look for the presence of the EGLNativeWindowType in the property set
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEglNativeWindowPropertyKey);
|
||||
}
|
||||
|
||||
// If the IPropertySet does not contain the required EglNativeWindowType key, the property set is
|
||||
// considered invalid.
|
||||
if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
|
||||
{
|
||||
ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
// The EglNativeWindowType property exists, so retreive the IInspectable that represents the EGLNativeWindowType
|
||||
if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey)
|
||||
{
|
||||
result = propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
if (propertySet != nullptr)
|
||||
{
|
||||
result = propSet.CopyTo(propertySet);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
if (eglNativeWindow != nullptr)
|
||||
{
|
||||
result = nativeWindow.CopyTo(eglNativeWindow);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// A Valid EGLNativeWindowType IInspectable can only be:
|
||||
//
|
||||
// ICoreWindow
|
||||
// IPropertySet
|
||||
//
|
||||
// Anything else will be rejected as an invalid IInspectable.
|
||||
bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
|
||||
{
|
||||
return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window);
|
||||
}
|
||||
|
||||
// Attempts to read an optional SIZE property value that is assumed to be in the form of
|
||||
// an ABI::Windows::Foundation::Size. This function validates the Size value before returning
|
||||
// it to the caller.
|
||||
//
|
||||
// Possible return values are:
|
||||
// S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated
|
||||
// S_OK, valueExists == false - optional SIZE value was not found
|
||||
// E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set.
|
||||
// * Incorrect property type ( must be PropertyType_Size)
|
||||
// * Invalid property value (width/height must be > 0)
|
||||
// Additional errors may be returned from IMap or IPropertyValue
|
||||
//
|
||||
HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists)
|
||||
{
|
||||
if (!propertyMap || !propertyName || !value || !valueExists)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume that the value does not exist
|
||||
*valueExists = false;
|
||||
*value = { 0, 0 };
|
||||
|
||||
ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
|
||||
ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
|
||||
Size sizeValue = { 0, 0 };
|
||||
boolean hasKey = false;
|
||||
|
||||
HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey);
|
||||
if (SUCCEEDED(result) && !hasKey)
|
||||
{
|
||||
// Value does not exist, so return S_OK and set the exists parameter to false to indicate
|
||||
// that a the optional property does not exist.
|
||||
*valueExists = false;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = propertyValue->get_Type(&propertyType);
|
||||
}
|
||||
|
||||
// Check if the expected Size property is of PropertyType_Size type.
|
||||
if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
|
||||
{
|
||||
if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
|
||||
{
|
||||
// A valid property value exists
|
||||
*value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
|
||||
*valueExists = true;
|
||||
result = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// An invalid Size property was detected. Width/Height values must > 0
|
||||
result = E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// An invalid property type was detected. Size property must be of PropertyType_Size
|
||||
result = E_INVALIDARG;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
91
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
vendored
Normal file
91
src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// InspectableNativeWindow.h: Host specific implementation interface for
|
||||
// managing IInspectable native window types.
|
||||
|
||||
#ifndef COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
|
||||
#define COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
|
||||
|
||||
#include "common/platform.h"
|
||||
#include "common/NativeWindow.h"
|
||||
#include "angle_windowsstore.h"
|
||||
|
||||
#include <windows.ui.xaml.h>
|
||||
#include <windows.ui.xaml.media.dxinterop.h>
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class InspectableNativeWindow
|
||||
{
|
||||
public:
|
||||
InspectableNativeWindow() :
|
||||
mSupportsSwapChainResize(true),
|
||||
mRequiresSwapChainScaling(false),
|
||||
mClientRectChanged(false),
|
||||
mClientRect({0,0,0,0}),
|
||||
mNewClientRect({0,0,0,0}),
|
||||
mScaleFactor(1.0)
|
||||
{
|
||||
mSizeChangedEventToken.value = 0;
|
||||
}
|
||||
virtual ~InspectableNativeWindow(){}
|
||||
|
||||
virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0;
|
||||
virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
|
||||
virtual bool registerForSizeChangeEvents() = 0;
|
||||
virtual void unregisterForSizeChangeEvents() = 0;
|
||||
virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
|
||||
|
||||
bool getClientRect(RECT *rect)
|
||||
{
|
||||
if (mClientRectChanged && mSupportsSwapChainResize)
|
||||
{
|
||||
mClientRect = mNewClientRect;
|
||||
mClientRectChanged = false;
|
||||
}
|
||||
|
||||
*rect = mClientRect;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setNewClientSize(const SIZE &newSize)
|
||||
{
|
||||
if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
|
||||
{
|
||||
mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
|
||||
mClientRectChanged = true;
|
||||
}
|
||||
|
||||
if (mRequiresSwapChainScaling)
|
||||
{
|
||||
scaleSwapChain(newSize);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mSupportsSwapChainResize;
|
||||
bool mRequiresSwapChainScaling;
|
||||
RECT mClientRect;
|
||||
RECT mNewClientRect;
|
||||
bool mClientRectChanged;
|
||||
DOUBLE mScaleFactor;
|
||||
|
||||
EventRegistrationToken mSizeChangedEventToken;
|
||||
};
|
||||
|
||||
bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
|
||||
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr);
|
||||
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);
|
||||
HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists);
|
||||
}
|
||||
#endif // COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
|
226
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
vendored
Normal file
226
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// SwapChainPanelNativeWindow.cpp: NativeWindow for managing ISwapChainPanel native window types.
|
||||
|
||||
#include "common/winrt/SwapChainPanelNativeWindow.h"
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
using namespace ABI::Windows::Foundation::Collections;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
|
||||
bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
|
||||
{
|
||||
ComPtr<IPropertySet> props = propertySet;
|
||||
ComPtr<IInspectable> win = window;
|
||||
SIZE swapChainSize = {};
|
||||
bool swapChainSizeSpecified = false;
|
||||
HRESULT result = S_OK;
|
||||
|
||||
// IPropertySet is an optional parameter and can be null.
|
||||
// If one is specified, cache as an IMap and read the properties
|
||||
// used for initial host initialization.
|
||||
if (propertySet)
|
||||
{
|
||||
result = props.As(&mPropertyMap);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
|
||||
// was prevalidated to contain the EGLNativeWindowType before being passed to
|
||||
// this host.
|
||||
result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = win.As(&mSwapChainPanel);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If a swapchain size is specfied, then the automatic resize
|
||||
// behaviors implemented by the host should be disabled. The swapchain
|
||||
// will be still be scaled when being rendered to fit the bounds
|
||||
// of the host.
|
||||
// Scaling of the swapchain output needs to be handled by the
|
||||
// host for swapchain panels even though the scaling mode setting
|
||||
// DXGI_SCALING_STRETCH is configured on the swapchain.
|
||||
if (swapChainSizeSpecified)
|
||||
{
|
||||
mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
|
||||
|
||||
// Enable host swapchain scaling
|
||||
mRequiresSwapChainScaling = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
mNewClientRect = mClientRect;
|
||||
mClientRectChanged = false;
|
||||
return registerForSizeChangeEvents();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::ISizeChangedEventHandler> sizeChangedHandler;
|
||||
ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
|
||||
HRESULT result = Microsoft::WRL::MakeAndInitialize<SwapChainPanelSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = mSwapChainPanel.As(&frameworkElement);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents()
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
|
||||
if (SUCCEEDED(mSwapChainPanel.As(&frameworkElement)))
|
||||
{
|
||||
(void)frameworkElement->remove_SizeChanged(mSizeChangedEventToken);
|
||||
}
|
||||
|
||||
mSizeChangedEventToken.value = 0;
|
||||
}
|
||||
|
||||
HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
|
||||
{
|
||||
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
|
||||
swapChainDesc.Width = width;
|
||||
swapChainDesc.Height = height;
|
||||
swapChainDesc.Format = format;
|
||||
swapChainDesc.Stereo = FALSE;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||
swapChainDesc.BufferCount = 2;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||
|
||||
*swapChain = nullptr;
|
||||
|
||||
ComPtr<IDXGISwapChain1> newSwapChain;
|
||||
ComPtr<ISwapChainPanelNative> swapChainPanelNative;
|
||||
RECT currentPanelSize = {};
|
||||
|
||||
HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = mSwapChainPanel.As(&swapChainPanelNative);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = swapChainPanelNative->SetSwapChain(newSwapChain.Get());
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// The swapchain panel host requires an instance of the swapchain set on the SwapChainPanel
|
||||
// to perform the runtime-scale behavior. This swapchain is cached here because there are
|
||||
// no methods for retreiving the currently configured on from ISwapChainPanelNative.
|
||||
mSwapChain = newSwapChain;
|
||||
result = newSwapChain.CopyTo(swapChain);
|
||||
}
|
||||
|
||||
// If the host is responsible for scaling the output of the swapchain, then
|
||||
// scale it now before returning an instance to the caller. This is done by
|
||||
// first reading the current size of the swapchain panel, then scaling
|
||||
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
{
|
||||
result = GetSwapChainPanelSize(mSwapChainPanel, ¤tPanelSize);
|
||||
}
|
||||
|
||||
// Scale the swapchain to fit inside the contents of the panel.
|
||||
if (SUCCEEDED(result) && mRequiresSwapChainScaling)
|
||||
{
|
||||
SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
|
||||
result = scaleSwapChain(currentSize);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
// If automatic swapchain resize behaviors have been disabled, then
|
||||
// unregister for the resize change events.
|
||||
if (mSupportsSwapChainResize == false)
|
||||
{
|
||||
unregisterForSizeChangeEvents();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
|
||||
{
|
||||
ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
|
||||
// Setup a scale matrix for the swap chain
|
||||
DXGI_MATRIX_3X2_F scaleMatrix = {};
|
||||
scaleMatrix._11 = renderScale.Width;
|
||||
scaleMatrix._22 = renderScale.Height;
|
||||
|
||||
ComPtr<IDXGISwapChain2> swapChain2;
|
||||
HRESULT result = mSwapChain.As(&swapChain2);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = swapChain2->SetMatrixTransform(&scaleMatrix);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
|
||||
{
|
||||
ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
|
||||
ABI::Windows::Foundation::Size renderSize = { 0, 0 };
|
||||
HRESULT result = swapChainPanel.As(&uiElement);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = uiElement->get_RenderSize(&renderSize);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
*windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
79
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
vendored
Normal file
79
src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// SwapChainPanelNativeWindow.h: NativeWindow for managing ISwapChainPanel native window types.
|
||||
|
||||
#ifndef COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
||||
#define COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
||||
|
||||
#include "common/winrt/InspectableNativeWindow.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<SwapChainPanelNativeWindow>
|
||||
{
|
||||
public:
|
||||
~SwapChainPanelNativeWindow();
|
||||
|
||||
bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
|
||||
bool registerForSizeChangeEvents();
|
||||
void unregisterForSizeChangeEvents();
|
||||
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
|
||||
HRESULT scaleSwapChain(const SIZE &newSize);
|
||||
|
||||
private:
|
||||
ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
|
||||
ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
|
||||
ComPtr<DXGISwapChain> mSwapChain;
|
||||
};
|
||||
|
||||
[uuid(8ACBD974-8187-4508-AD80-AEC77F93CF36)]
|
||||
class SwapChainPanelSizeChangedHandler :
|
||||
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ABI::Windows::UI::Xaml::ISizeChangedEventHandler>
|
||||
{
|
||||
public:
|
||||
SwapChainPanelSizeChangedHandler() { }
|
||||
HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
|
||||
{
|
||||
if (!host)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
mHost = host;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// ISizeChangedEventHandler
|
||||
IFACEMETHOD(Invoke)(IInspectable *sender, ABI::Windows::UI::Xaml::ISizeChangedEventArgs *sizeChangedEventArgs)
|
||||
{
|
||||
std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
|
||||
if (host)
|
||||
{
|
||||
// The size of the ISwapChainPanel control is returned in DIPs.
|
||||
// We are keeping these in dips because the swapchain created for composition
|
||||
// also uses dip units. This keeps dimensions, viewports, etc in the same unit.
|
||||
// XAML Clients of the ISwapChainPanel are required to use dips to define their
|
||||
// layout sizes as well.
|
||||
ABI::Windows::Foundation::Size newSize;
|
||||
HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
|
||||
host->setNewClientSize(windowSize);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
std::weak_ptr<InspectableNativeWindow> mHost;
|
||||
};
|
||||
|
||||
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
|
||||
}
|
||||
#endif // COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
|
@ -29,7 +29,8 @@ class DirectiveHandler
|
||||
// Handle pragma of form: #pragma name[(value)]
|
||||
virtual void handlePragma(const SourceLocation &loc,
|
||||
const std::string &name,
|
||||
const std::string &value) = 0;
|
||||
const std::string &value,
|
||||
bool stdgl) = 0;
|
||||
|
||||
virtual void handleExtension(const SourceLocation &loc,
|
||||
const std::string &name,
|
||||
|
@ -38,19 +38,19 @@ enum DirectiveType
|
||||
|
||||
DirectiveType getDirective(const pp::Token *token)
|
||||
{
|
||||
static const std::string kDirectiveDefine("define");
|
||||
static const std::string kDirectiveUndef("undef");
|
||||
static const std::string kDirectiveIf("if");
|
||||
static const std::string kDirectiveIfdef("ifdef");
|
||||
static const std::string kDirectiveIfndef("ifndef");
|
||||
static const std::string kDirectiveElse("else");
|
||||
static const std::string kDirectiveElif("elif");
|
||||
static const std::string kDirectiveEndif("endif");
|
||||
static const std::string kDirectiveError("error");
|
||||
static const std::string kDirectivePragma("pragma");
|
||||
static const std::string kDirectiveExtension("extension");
|
||||
static const std::string kDirectiveVersion("version");
|
||||
static const std::string kDirectiveLine("line");
|
||||
const char kDirectiveDefine[] = "define";
|
||||
const char kDirectiveUndef[] = "undef";
|
||||
const char kDirectiveIf[] = "if";
|
||||
const char kDirectiveIfdef[] = "ifdef";
|
||||
const char kDirectiveIfndef[] = "ifndef";
|
||||
const char kDirectiveElse[] = "else";
|
||||
const char kDirectiveElif[] = "elif";
|
||||
const char kDirectiveEndif[] = "endif";
|
||||
const char kDirectiveError[] = "error";
|
||||
const char kDirectivePragma[] = "pragma";
|
||||
const char kDirectiveExtension[] = "extension";
|
||||
const char kDirectiveVersion[] = "version";
|
||||
const char kDirectiveLine[] = "line";
|
||||
|
||||
if (token->type != pp::Token::IDENTIFIER)
|
||||
return DIRECTIVE_NONE;
|
||||
@ -155,7 +155,7 @@ class DefinedParser : public Lexer
|
||||
protected:
|
||||
virtual void lex(Token *token)
|
||||
{
|
||||
static const std::string kDefined("defined");
|
||||
const char kDefined[] = "defined";
|
||||
|
||||
mLexer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
@ -592,6 +592,11 @@ void DirectiveParser::parsePragma(Token *token)
|
||||
int state = PRAGMA_NAME;
|
||||
|
||||
mTokenizer->lex(token);
|
||||
bool stdgl = token->text == "STDGL";
|
||||
if (stdgl)
|
||||
{
|
||||
mTokenizer->lex(token);
|
||||
}
|
||||
while ((token->type != '\n') && (token->type != Token::LAST))
|
||||
{
|
||||
switch(state++)
|
||||
@ -627,7 +632,7 @@ void DirectiveParser::parsePragma(Token *token)
|
||||
}
|
||||
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
|
||||
{
|
||||
mDirectiveHandler->handlePragma(token->location, name, value);
|
||||
mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,8 +194,8 @@ bool MacroExpander::expandMacro(const Macro ¯o,
|
||||
|
||||
if (macro.predefined)
|
||||
{
|
||||
static const std::string kLine = "__LINE__";
|
||||
static const std::string kFile = "__FILE__";
|
||||
const char kLine[] = "__LINE__";
|
||||
const char kFile[] = "__FILE__";
|
||||
|
||||
assert(replacements->size() == 1);
|
||||
Token& repl = replacements->front();
|
||||
|
@ -29,24 +29,27 @@
|
||||
|
||||
bool IsWebGLBasedSpec(ShShaderSpec spec)
|
||||
{
|
||||
return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
|
||||
return (spec == SH_WEBGL_SPEC ||
|
||||
spec == SH_CSS_SHADERS_SPEC ||
|
||||
spec == SH_WEBGL2_SPEC);
|
||||
}
|
||||
|
||||
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
|
||||
{
|
||||
// WebGL defines a max token legnth of 256, while ES2 leaves max token
|
||||
// size undefined. ES3 defines a max size of 1024 characters.
|
||||
if (IsWebGLBasedSpec(spec))
|
||||
switch (spec)
|
||||
{
|
||||
case SH_WEBGL_SPEC:
|
||||
case SH_CSS_SHADERS_SPEC:
|
||||
return 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
default:
|
||||
return 1024;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class TScopedPoolAllocator
|
||||
{
|
||||
public:
|
||||
@ -82,6 +85,24 @@ class TScopedSymbolTableLevel
|
||||
private:
|
||||
TSymbolTable* mTable;
|
||||
};
|
||||
|
||||
int MapSpecToShaderVersion(ShShaderSpec spec)
|
||||
{
|
||||
switch (spec)
|
||||
{
|
||||
case SH_GLES2_SPEC:
|
||||
case SH_WEBGL_SPEC:
|
||||
case SH_CSS_SHADERS_SPEC:
|
||||
return 100;
|
||||
case SH_GLES3_SPEC:
|
||||
case SH_WEBGL2_SPEC:
|
||||
return 300;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TShHandleBase::TShHandleBase()
|
||||
@ -178,9 +199,21 @@ bool TCompiler::compile(const char* const shaderStrings[],
|
||||
(parseContext.treeRoot != NULL);
|
||||
|
||||
shaderVersion = parseContext.getShaderVersion();
|
||||
if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
|
||||
{
|
||||
infoSink.info.prefix(EPrefixError);
|
||||
infoSink.info << "unsupported shader version";
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
mPragma = parseContext.pragma();
|
||||
if (mPragma.stdgl.invariantAll)
|
||||
{
|
||||
symbolTable.setGlobalInvariant();
|
||||
}
|
||||
|
||||
TIntermNode* root = parseContext.treeRoot;
|
||||
success = intermediate.postProcess(root);
|
||||
|
||||
@ -360,7 +393,8 @@ void TCompiler::setResourceString()
|
||||
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
|
||||
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
|
||||
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
|
||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
|
||||
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
|
||||
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
|
||||
|
||||
builtInResourcesString = strstream.str();
|
||||
}
|
||||
@ -377,7 +411,6 @@ void TCompiler::clearResults()
|
||||
uniforms.clear();
|
||||
expandedUniforms.clear();
|
||||
varyings.clear();
|
||||
expandedVaryings.clear();
|
||||
interfaceBlocks.clear();
|
||||
|
||||
builtInFunctionEmulator.Cleanup();
|
||||
@ -507,13 +540,12 @@ void TCompiler::collectVariables(TIntermNode* root)
|
||||
&uniforms,
|
||||
&varyings,
|
||||
&interfaceBlocks,
|
||||
hashFunction);
|
||||
hashFunction,
|
||||
symbolTable);
|
||||
root->traverse(&collect);
|
||||
|
||||
// For backwards compatiblity with ShGetVariableInfo, expand struct
|
||||
// uniforms and varyings into separate variables for each field.
|
||||
sh::ExpandVariables(uniforms, &expandedUniforms);
|
||||
sh::ExpandVariables(varyings, &expandedVaryings);
|
||||
// This is for enforcePackingRestriction().
|
||||
sh::ExpandUniforms(uniforms, &expandedUniforms);
|
||||
}
|
||||
|
||||
bool TCompiler::enforcePackingRestrictions()
|
||||
@ -581,3 +613,10 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
|
||||
{
|
||||
return builtInFunctionEmulator;
|
||||
}
|
||||
|
||||
void TCompiler::writePragma()
|
||||
{
|
||||
TInfoSinkBase &sink = infoSink.obj;
|
||||
if (mPragma.stdgl.invariantAll)
|
||||
sink << "#pragma STDGL invariant(all)\n";
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "compiler/translator/ExtensionBehavior.h"
|
||||
#include "compiler/translator/HashNames.h"
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
#include "compiler/translator/Pragma.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "compiler/translator/VariableInfo.h"
|
||||
#include "third_party/compiler/ArrayBoundsClamper.h"
|
||||
@ -71,9 +72,7 @@ class TCompiler : public TShHandleBase
|
||||
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
|
||||
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
|
||||
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
|
||||
const std::vector<sh::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
|
||||
const std::vector<sh::Varying> &getVaryings() const { return varyings; }
|
||||
const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
|
||||
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
|
||||
|
||||
ShHashFunction64 getHashFunction() const { return hashFunction; }
|
||||
@ -81,7 +80,7 @@ class TCompiler : public TShHandleBase
|
||||
TSymbolTable& getSymbolTable() { return symbolTable; }
|
||||
ShShaderSpec getShaderSpec() const { return shaderSpec; }
|
||||
ShShaderOutput getOutputType() const { return outputType; }
|
||||
std::string getBuiltInResourcesString() const { return builtInResourcesString; }
|
||||
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
|
||||
|
||||
// Get the resources set by InitBuiltInSymbolTable
|
||||
const ShBuiltInResources& getResources() const;
|
||||
@ -131,6 +130,8 @@ class TCompiler : public TShHandleBase
|
||||
bool limitExpressionComplexity(TIntermNode* root);
|
||||
// Get built-in extensions with default behavior.
|
||||
const TExtensionBehavior& getExtensionBehavior() const;
|
||||
const TPragma& getPragma() const { return mPragma; }
|
||||
void writePragma();
|
||||
|
||||
const ArrayBoundsClamper& getArrayBoundsClamper() const;
|
||||
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
|
||||
@ -141,7 +142,6 @@ class TCompiler : public TShHandleBase
|
||||
std::vector<sh::Uniform> uniforms;
|
||||
std::vector<sh::ShaderVariable> expandedUniforms;
|
||||
std::vector<sh::Varying> varyings;
|
||||
std::vector<sh::ShaderVariable> expandedVaryings;
|
||||
std::vector<sh::InterfaceBlock> interfaceBlocks;
|
||||
|
||||
private:
|
||||
@ -174,6 +174,8 @@ class TCompiler : public TShHandleBase
|
||||
// name hashing.
|
||||
ShHashFunction64 hashFunction;
|
||||
NameMap nameMap;
|
||||
|
||||
TPragma mPragma;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// Detect Loop Discontinuity
|
||||
|
||||
bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
|
||||
{
|
||||
mLoopDepth = 0;
|
||||
@ -74,6 +77,55 @@ bool containsLoopDiscontinuity(TIntermNode *node)
|
||||
return detectLoopDiscontinuity.traverse(node);
|
||||
}
|
||||
|
||||
// Detect Any Loop
|
||||
|
||||
bool DetectAnyLoop::traverse(TIntermNode *node)
|
||||
{
|
||||
mHasLoop = false;
|
||||
node->traverse(this);
|
||||
return mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitLoop(Visit visit, TIntermLoop *loop)
|
||||
{
|
||||
mHasLoop = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// The following definitions stop all traversal when we have found a loop
|
||||
bool DetectAnyLoop::visitBinary(Visit, TIntermBinary *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitUnary(Visit, TIntermUnary *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitSelection(Visit, TIntermSelection *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitAggregate(Visit, TIntermAggregate *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool DetectAnyLoop::visitBranch(Visit, TIntermBranch *)
|
||||
{
|
||||
return !mHasLoop;
|
||||
}
|
||||
|
||||
bool containsAnyLoop(TIntermNode *node)
|
||||
{
|
||||
DetectAnyLoop detectAnyLoop;
|
||||
return detectAnyLoop.traverse(node);
|
||||
}
|
||||
|
||||
// Detect Gradient Operation
|
||||
|
||||
bool DetectGradientOperation::traverse(TIntermNode *node)
|
||||
{
|
||||
mGradientOperation = false;
|
||||
|
@ -32,6 +32,25 @@ class DetectLoopDiscontinuity : public TIntermTraverser
|
||||
|
||||
bool containsLoopDiscontinuity(TIntermNode *node);
|
||||
|
||||
// Checks for the existence of any loop
|
||||
class DetectAnyLoop : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
bool traverse(TIntermNode *node);
|
||||
|
||||
protected:
|
||||
bool visitBinary(Visit, TIntermBinary *);
|
||||
bool visitUnary(Visit, TIntermUnary *);
|
||||
bool visitSelection(Visit, TIntermSelection *);
|
||||
bool visitAggregate(Visit, TIntermAggregate *);
|
||||
bool visitLoop(Visit, TIntermLoop *);
|
||||
bool visitBranch(Visit, TIntermBranch *);
|
||||
|
||||
bool mHasLoop;
|
||||
};
|
||||
|
||||
bool containsAnyLoop(TIntermNode *node);
|
||||
|
||||
// Checks for intrinsic functions which compute gradients
|
||||
class DetectGradientOperation : public TIntermTraverser
|
||||
{
|
||||
|
@ -13,10 +13,10 @@
|
||||
|
||||
static TBehavior getBehavior(const std::string& str)
|
||||
{
|
||||
static const std::string kRequire("require");
|
||||
static const std::string kEnable("enable");
|
||||
static const std::string kDisable("disable");
|
||||
static const std::string kWarn("warn");
|
||||
const char kRequire[] = "require";
|
||||
const char kEnable[] = "enable";
|
||||
const char kDisable[] = "disable";
|
||||
const char kWarn[] = "warn";
|
||||
|
||||
if (str == kRequire) return EBhRequire;
|
||||
else if (str == kEnable) return EBhEnable;
|
||||
@ -46,50 +46,61 @@ void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
|
||||
|
||||
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& value)
|
||||
const std::string& value,
|
||||
bool stdgl)
|
||||
{
|
||||
static const std::string kSTDGL("STDGL");
|
||||
static const std::string kOptimize("optimize");
|
||||
static const std::string kDebug("debug");
|
||||
static const std::string kOn("on");
|
||||
static const std::string kOff("off");
|
||||
if (stdgl)
|
||||
{
|
||||
const char kInvariant[] = "invariant";
|
||||
const char kAll[] = "all";
|
||||
|
||||
bool invalidValue = false;
|
||||
if (name == kSTDGL)
|
||||
{
|
||||
if (name == kInvariant && value == kAll)
|
||||
mPragma.stdgl.invariantAll = true;
|
||||
// The STDGL pragma is used to reserve pragmas for use by future
|
||||
// revisions of GLSL. Ignore it.
|
||||
// revisions of GLSL. Do not generate an error on unexpected
|
||||
// name and value.
|
||||
return;
|
||||
}
|
||||
else if (name == kOptimize)
|
||||
{
|
||||
if (value == kOn) mPragma.optimize = true;
|
||||
else if (value == kOff) mPragma.optimize = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else if (name == kDebug)
|
||||
{
|
||||
if (value == kOn) mPragma.debug = true;
|
||||
else if (value == kOff) mPragma.debug = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
|
||||
return;
|
||||
}
|
||||
const char kOptimize[] = "optimize";
|
||||
const char kDebug[] = "debug";
|
||||
const char kOn[] = "on";
|
||||
const char kOff[] = "off";
|
||||
|
||||
if (invalidValue)
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
|
||||
"invalid pragma value", value,
|
||||
"'on' or 'off' expected");
|
||||
bool invalidValue = false;
|
||||
if (name == kOptimize)
|
||||
{
|
||||
if (value == kOn) mPragma.optimize = true;
|
||||
else if (value == kOff) mPragma.optimize = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else if (name == kDebug)
|
||||
{
|
||||
if (value == kOn) mPragma.debug = true;
|
||||
else if (value == kOff) mPragma.debug = false;
|
||||
else invalidValue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (invalidValue)
|
||||
{
|
||||
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
|
||||
"invalid pragma value", value,
|
||||
"'on' or 'off' expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& behavior)
|
||||
{
|
||||
static const std::string kExtAll("all");
|
||||
const char kExtAll[] = "all";
|
||||
|
||||
TBehavior behaviorVal = getBehavior(behavior);
|
||||
if (behaviorVal == EBhUndefined)
|
||||
|
@ -29,7 +29,8 @@ class TDirectiveHandler : public pp::DirectiveHandler
|
||||
|
||||
virtual void handlePragma(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
const std::string& value);
|
||||
const std::string& value,
|
||||
bool stdgl);
|
||||
|
||||
virtual void handleExtension(const pp::SourceLocation& loc,
|
||||
const std::string& name,
|
||||
|
@ -133,6 +133,14 @@ bool CompareStructure(const TType &leftNodeType,
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void TIntermTyped::setTypePreservePrecision(const TType &t)
|
||||
{
|
||||
TPrecision precision = getPrecision();
|
||||
mType = t;
|
||||
ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
|
||||
mType.setPrecision(precision);
|
||||
}
|
||||
|
||||
#define REPLACE_IF_IS(node, type, original, replacement) \
|
||||
if (node == original) { \
|
||||
node = static_cast<type *>(replacement); \
|
||||
@ -237,6 +245,52 @@ void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) con
|
||||
}
|
||||
}
|
||||
|
||||
void TIntermAggregate::setPrecisionFromChildren()
|
||||
{
|
||||
if (getBasicType() == EbtBool)
|
||||
{
|
||||
mType.setPrecision(EbpUndefined);
|
||||
return;
|
||||
}
|
||||
|
||||
TPrecision precision = EbpUndefined;
|
||||
TIntermSequence::iterator childIter = mSequence.begin();
|
||||
while (childIter != mSequence.end())
|
||||
{
|
||||
TIntermTyped *typed = (*childIter)->getAsTyped();
|
||||
if (typed)
|
||||
precision = GetHigherPrecision(typed->getPrecision(), precision);
|
||||
++childIter;
|
||||
}
|
||||
mType.setPrecision(precision);
|
||||
}
|
||||
|
||||
void TIntermAggregate::setBuiltInFunctionPrecision()
|
||||
{
|
||||
// All built-ins returning bool should be handled as ops, not functions.
|
||||
ASSERT(getBasicType() != EbtBool);
|
||||
|
||||
TPrecision precision = EbpUndefined;
|
||||
TIntermSequence::iterator childIter = mSequence.begin();
|
||||
while (childIter != mSequence.end())
|
||||
{
|
||||
TIntermTyped *typed = (*childIter)->getAsTyped();
|
||||
// ESSL spec section 8: texture functions get their precision from the sampler.
|
||||
if (typed && IsSampler(typed->getBasicType()))
|
||||
{
|
||||
precision = typed->getPrecision();
|
||||
break;
|
||||
}
|
||||
++childIter;
|
||||
}
|
||||
// ESSL 3.0 spec section 8: textureSize always gets highp precision.
|
||||
// All other functions that take a sampler are assumed to be texture functions.
|
||||
if (mName.find("textureSize") == 0)
|
||||
mType.setPrecision(EbpHigh);
|
||||
else
|
||||
mType.setPrecision(precision);
|
||||
}
|
||||
|
||||
bool TIntermSelection::replaceChildNode(
|
||||
TIntermNode *original, TIntermNode *replacement)
|
||||
{
|
||||
@ -336,6 +390,7 @@ bool TIntermUnary::promote(TInfoSink &)
|
||||
return false;
|
||||
break;
|
||||
case EOpNegative:
|
||||
case EOpPositive:
|
||||
case EOpPostIncrement:
|
||||
case EOpPostDecrement:
|
||||
case EOpPreIncrement:
|
||||
@ -1068,6 +1123,27 @@ TIntermTyped *TIntermConstantUnion::fold(
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpPositive:
|
||||
switch (getType().getBasicType())
|
||||
{
|
||||
case EbtFloat:
|
||||
tempConstArray[i].setFConst(unionArray[i].getFConst());
|
||||
break;
|
||||
case EbtInt:
|
||||
tempConstArray[i].setIConst(unionArray[i].getIConst());
|
||||
break;
|
||||
case EbtUInt:
|
||||
tempConstArray[i].setUConst(static_cast<unsigned int>(
|
||||
static_cast<int>(unionArray[i].getUConst())));
|
||||
break;
|
||||
default:
|
||||
infoSink.info.message(
|
||||
EPrefixInternalError, getLine(),
|
||||
"Unary operation not folded into constant");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case EOpLogicalNot:
|
||||
// this code is written for possible future use,
|
||||
// will not get executed currently
|
||||
|
@ -45,6 +45,7 @@ enum TOperator
|
||||
//
|
||||
|
||||
EOpNegative,
|
||||
EOpPositive,
|
||||
EOpLogicalNot,
|
||||
EOpVectorLogicalNot,
|
||||
|
||||
@ -265,6 +266,7 @@ class TIntermTyped : public TIntermNode
|
||||
virtual bool hasSideEffects() const = 0;
|
||||
|
||||
void setType(const TType &t) { mType = t; }
|
||||
void setTypePreservePrecision(const TType &t);
|
||||
const TType &getType() const { return mType; }
|
||||
TType *getTypePointer() { return &mType; }
|
||||
|
||||
@ -613,6 +615,9 @@ class TIntermAggregate : public TIntermOperator
|
||||
|
||||
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
|
||||
|
||||
void setPrecisionFromChildren();
|
||||
void setBuiltInFunctionPrecision();
|
||||
|
||||
protected:
|
||||
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
|
||||
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
|
||||
|
@ -198,6 +198,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
|
||||
case EOpPostDecrement:
|
||||
case EOpPreDecrement:
|
||||
case EOpNegative:
|
||||
case EOpPositive:
|
||||
if (child->getType().getBasicType() == EbtStruct ||
|
||||
child->getType().isArray())
|
||||
{
|
||||
|
@ -395,6 +395,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative: preString = "(-"; break;
|
||||
case EOpPositive: preString = "(+"; break;
|
||||
case EOpVectorLogicalNot: preString = "not("; break;
|
||||
case EOpLogicalNot: preString = "(!"; break;
|
||||
|
||||
@ -574,7 +575,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
// Function declaration.
|
||||
ASSERT(visit == PreVisit);
|
||||
writeVariableType(node->getType());
|
||||
out << " " << hashName(node->getName());
|
||||
out << " " << hashFunctionName(node->getName());
|
||||
|
||||
out << "(";
|
||||
writeFunctionParameters(*(node->getSequence()));
|
||||
@ -649,17 +650,18 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
mDeclaringVariables = false;
|
||||
}
|
||||
break;
|
||||
case EOpInvariantDeclaration: {
|
||||
// Invariant declaration.
|
||||
ASSERT(visit == PreVisit);
|
||||
case EOpInvariantDeclaration:
|
||||
// Invariant declaration.
|
||||
ASSERT(visit == PreVisit);
|
||||
{
|
||||
const TIntermSequence *sequence = node->getSequence();
|
||||
ASSERT(sequence && sequence->size() == 1);
|
||||
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
|
||||
ASSERT(symbol);
|
||||
out << "invariant " << symbol->getSymbol() << ";";
|
||||
visitChildren = false;
|
||||
break;
|
||||
out << "invariant " << hashVariableName(symbol->getSymbol());
|
||||
}
|
||||
visitChildren = false;
|
||||
break;
|
||||
case EOpConstructFloat:
|
||||
writeTriplet(visit, "float(", NULL, ")");
|
||||
break;
|
||||
@ -741,7 +743,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
|
||||
break;
|
||||
case EOpComma:
|
||||
writeTriplet(visit, NULL, ", ", NULL);
|
||||
writeTriplet(visit, "(", ", ", ")");
|
||||
break;
|
||||
|
||||
case EOpMod:
|
||||
|
@ -135,6 +135,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
|
||||
mUniqueIndex = 0;
|
||||
|
||||
mContainsLoopDiscontinuity = false;
|
||||
mContainsAnyLoop = false;
|
||||
mOutputLod0Function = false;
|
||||
mInsideDiscontinuousLoop = false;
|
||||
mNestedLoopDepth = 0;
|
||||
@ -172,6 +173,7 @@ OutputHLSL::~OutputHLSL()
|
||||
void OutputHLSL::output()
|
||||
{
|
||||
mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
|
||||
mContainsAnyLoop = containsAnyLoop(mContext.treeRoot);
|
||||
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
|
||||
makeFlaggedStructMaps(flaggedStructs);
|
||||
|
||||
@ -320,14 +322,22 @@ void OutputHLSL::header()
|
||||
|
||||
if (mUsesDiscardRewriting)
|
||||
{
|
||||
out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
|
||||
out << "#define ANGLE_USES_DISCARD_REWRITING\n";
|
||||
}
|
||||
|
||||
if (mUsesNestedBreak)
|
||||
{
|
||||
out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
|
||||
out << "#define ANGLE_USES_NESTED_BREAK\n";
|
||||
}
|
||||
|
||||
out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
|
||||
"#define LOOP [loop]\n"
|
||||
"#define FLATTEN [flatten]\n"
|
||||
"#else\n"
|
||||
"#define LOOP\n"
|
||||
"#define FLATTEN\n"
|
||||
"#endif\n";
|
||||
|
||||
if (mContext.shaderType == GL_FRAGMENT_SHADER)
|
||||
{
|
||||
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
|
||||
@ -1747,6 +1757,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
|
||||
case EOpPositive: outputTriplet(visit, "(+", "", ")"); break;
|
||||
case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
|
||||
case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
|
||||
case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
|
||||
@ -1860,15 +1871,20 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
|
||||
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
|
||||
{
|
||||
if (!mInsideFunction)
|
||||
{
|
||||
out << "static ";
|
||||
}
|
||||
|
||||
out << TypeString(variable->getType()) + " ";
|
||||
|
||||
for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
|
||||
{
|
||||
if (isSingleStatement(*sit))
|
||||
{
|
||||
mUnfoldShortCircuit->traverse(*sit);
|
||||
}
|
||||
|
||||
if (!mInsideFunction)
|
||||
{
|
||||
out << "static ";
|
||||
}
|
||||
|
||||
out << TypeString(variable->getType()) + " ";
|
||||
|
||||
TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
|
||||
|
||||
if (symbol)
|
||||
@ -1884,7 +1900,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
|
||||
if (*sit != sequence->back())
|
||||
{
|
||||
out << ", ";
|
||||
out << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1925,7 +1941,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
case EOpPrototype:
|
||||
if (visit == PreVisit)
|
||||
{
|
||||
out << TypeString(node->getType()) << " " << Decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "(");
|
||||
out << TypeString(node->getType()) << " " << Decorate(TFunction::unmangleName(node->getName())) << (mOutputLod0Function ? "Lod0(" : "(");
|
||||
|
||||
TIntermSequence *arguments = node->getSequence();
|
||||
|
||||
@ -2287,6 +2303,15 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
|
||||
{
|
||||
mUnfoldShortCircuit->traverse(node->getCondition());
|
||||
|
||||
// D3D errors when there is a gradient operation in a loop in an unflattened if
|
||||
// however flattening all the ifs in branch heavy shaders made D3D error too.
|
||||
// As a temporary workaround we flatten the ifs only if there is at least a loop
|
||||
// present somewhere in the shader.
|
||||
if (mContext.shaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop)
|
||||
{
|
||||
out << "FLATTEN ";
|
||||
}
|
||||
|
||||
out << "if (";
|
||||
|
||||
node->getCondition()->traverse(this);
|
||||
@ -2367,14 +2392,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
|
||||
|
||||
if (node->getType() == ELoopDoWhile)
|
||||
{
|
||||
out << "{do\n";
|
||||
out << "{LOOP do\n";
|
||||
|
||||
outputLineDirective(node->getLine().first_line);
|
||||
out << "{\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "{for(";
|
||||
out << "{LOOP for(";
|
||||
|
||||
if (node->getInit())
|
||||
{
|
||||
@ -2503,6 +2528,12 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (aggregate->getOp() == EOpDeclaration)
|
||||
{
|
||||
// Declaring multiple comma-separated variables must be considered multiple statements
|
||||
// because each individual declaration has side effects which are visible in the next.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
|
||||
@ -2675,7 +2706,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
|
||||
|
||||
// for(int index = initial; index < clampedLimit; index += increment)
|
||||
|
||||
out << "for(";
|
||||
out << "LOOP for(";
|
||||
index->traverse(this);
|
||||
out << " = ";
|
||||
out << initial;
|
||||
|
@ -144,6 +144,7 @@ class OutputHLSL : public TIntermTraverser
|
||||
int mUniqueIndex; // For creating unique names
|
||||
|
||||
bool mContainsLoopDiscontinuity;
|
||||
bool mContainsAnyLoop;
|
||||
bool mOutputLod0Function;
|
||||
bool mInsideDiscontinuousLoop;
|
||||
int mNestedLoopDepth;
|
||||
|
@ -1004,12 +1004,12 @@ void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char*
|
||||
directiveHandler.handleExtension(srcLoc, extName, behavior);
|
||||
}
|
||||
|
||||
void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value)
|
||||
void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl)
|
||||
{
|
||||
pp::SourceLocation srcLoc;
|
||||
srcLoc.file = loc.first_file;
|
||||
srcLoc.line = loc.first_line;
|
||||
directiveHandler.handlePragma(srcLoc, name, value);
|
||||
directiveHandler.handlePragma(srcLoc, name, value, stdgl);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1364,11 +1364,18 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv
|
||||
{
|
||||
error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
|
||||
recover();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const TString kGlFrontFacing("gl_FrontFacing");
|
||||
if (*identifier == kGlFrontFacing)
|
||||
{
|
||||
error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
|
||||
recover();
|
||||
return NULL;
|
||||
}
|
||||
symbolTable.addInvariantVarying(*identifier);
|
||||
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
|
||||
ASSERT(variable);
|
||||
const TType &type = variable->getType();
|
||||
|
@ -116,7 +116,7 @@ struct TParseContext {
|
||||
bool supportsExtension(const char* extension);
|
||||
bool isExtensionEnabled(const char* extension) const;
|
||||
void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior);
|
||||
void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value);
|
||||
void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl);
|
||||
|
||||
bool containsSampler(TType& type);
|
||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||
|
@ -7,13 +7,23 @@
|
||||
#ifndef COMPILER_PRAGMA_H_
|
||||
#define COMPILER_PRAGMA_H_
|
||||
|
||||
struct TPragma {
|
||||
struct TPragma
|
||||
{
|
||||
struct STDGL
|
||||
{
|
||||
STDGL() : invariantAll(false) { }
|
||||
|
||||
bool invariantAll;
|
||||
};
|
||||
|
||||
|
||||
// By default optimization is turned on and debug is turned off.
|
||||
TPragma() : optimize(true), debug(false) { }
|
||||
TPragma(bool o, bool d) : optimize(o), debug(d) { }
|
||||
|
||||
bool optimize;
|
||||
bool debug;
|
||||
STDGL stdgl;
|
||||
};
|
||||
|
||||
#endif // COMPILER_PRAGMA_H_
|
||||
|
@ -37,72 +37,6 @@ bool isInitialized = false;
|
||||
// and the shading language compiler.
|
||||
//
|
||||
|
||||
static bool CheckVariableMaxLengths(const ShHandle handle,
|
||||
size_t expectedValue)
|
||||
{
|
||||
size_t activeUniformLimit = 0;
|
||||
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
|
||||
size_t activeAttribLimit = 0;
|
||||
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
|
||||
size_t varyingLimit = 0;
|
||||
ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
|
||||
return (expectedValue == activeUniformLimit &&
|
||||
expectedValue == activeAttribLimit &&
|
||||
expectedValue == varyingLimit);
|
||||
}
|
||||
|
||||
bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
|
||||
{
|
||||
size_t mappedNameMaxLength = 0;
|
||||
ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
|
||||
return (expectedValue == mappedNameMaxLength);
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
|
||||
{
|
||||
if (index < 0 || static_cast<size_t>(index) >= infoList.size())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &infoList[index];
|
||||
}
|
||||
|
||||
const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
|
||||
{
|
||||
switch (varType)
|
||||
{
|
||||
case SH_ACTIVE_ATTRIBUTES:
|
||||
return ReturnVariable(compiler->getAttributes(), index);
|
||||
case SH_ACTIVE_UNIFORMS:
|
||||
return ReturnVariable(compiler->getExpandedUniforms(), index);
|
||||
case SH_VARYINGS:
|
||||
return ReturnVariable(compiler->getExpandedVaryings(), index);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ShPrecisionType ConvertPrecision(sh::GLenum precision)
|
||||
{
|
||||
switch (precision)
|
||||
{
|
||||
case GL_HIGH_FLOAT:
|
||||
case GL_HIGH_INT:
|
||||
return SH_PRECISION_HIGHP;
|
||||
case GL_MEDIUM_FLOAT:
|
||||
case GL_MEDIUM_INT:
|
||||
return SH_PRECISION_MEDIUMP;
|
||||
case GL_LOW_FLOAT:
|
||||
case GL_LOW_INT:
|
||||
return SH_PRECISION_LOWP;
|
||||
default:
|
||||
return SH_PRECISION_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
|
||||
|
||||
@ -150,32 +84,48 @@ const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariabl
|
||||
return GetVariableList<VarT>(compiler, variableType);
|
||||
}
|
||||
|
||||
TCompiler *GetCompilerFromHandle(ShHandle handle)
|
||||
{
|
||||
if (!handle)
|
||||
return NULL;
|
||||
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
|
||||
return base->getAsCompiler();
|
||||
}
|
||||
|
||||
TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
|
||||
{
|
||||
if (!handle)
|
||||
return NULL;
|
||||
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
|
||||
return base->getAsTranslatorHLSL();
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other compiler operations.
|
||||
// Subsequent calls to this function are no-op.
|
||||
//
|
||||
int ShInitialize()
|
||||
bool ShInitialize()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
isInitialized = InitProcess();
|
||||
}
|
||||
return isInitialized ? 1 : 0;
|
||||
return isInitialized;
|
||||
}
|
||||
|
||||
//
|
||||
// Cleanup symbol tables
|
||||
//
|
||||
int ShFinalize()
|
||||
bool ShFinalize()
|
||||
{
|
||||
if (isInitialized)
|
||||
{
|
||||
DetachProcess();
|
||||
isInitialized = false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
@ -183,6 +133,9 @@ int ShFinalize()
|
||||
//
|
||||
void ShInitBuiltInResources(ShBuiltInResources* resources)
|
||||
{
|
||||
// Make comparable.
|
||||
memset(resources, 0, sizeof(*resources));
|
||||
|
||||
// Constants.
|
||||
resources->MaxVertexAttribs = 8;
|
||||
resources->MaxVertexUniformVectors = 128;
|
||||
@ -201,6 +154,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
|
||||
resources->EXT_frag_depth = 0;
|
||||
resources->EXT_shader_texture_lod = 0;
|
||||
|
||||
resources->NV_draw_buffers = 0;
|
||||
|
||||
// Disable highp precision in fragment shader by default.
|
||||
resources->FragmentPrecisionHigh = 0;
|
||||
|
||||
@ -251,23 +206,13 @@ void ShDestruct(ShHandle handle)
|
||||
DeleteCompiler(base->getAsCompiler());
|
||||
}
|
||||
|
||||
void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString)
|
||||
const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !outString)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TShHandleBase *base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler *compiler = base->getAsCompiler();
|
||||
if (!compiler)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen);
|
||||
outString[outStringLen - 1] = '\0';
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return compiler->getBuiltInResourcesString();
|
||||
}
|
||||
|
||||
//
|
||||
// Do an actual compile on the given strings. The result is left
|
||||
// in the given compile object.
|
||||
@ -275,219 +220,62 @@ void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, cha
|
||||
// Return: The return value of ShCompile is really boolean, indicating
|
||||
// success or failure.
|
||||
//
|
||||
int ShCompile(
|
||||
bool ShCompile(
|
||||
const ShHandle handle,
|
||||
const char* const shaderStrings[],
|
||||
const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
int compileOptions)
|
||||
{
|
||||
if (handle == 0)
|
||||
return 0;
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return 0;
|
||||
|
||||
bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
|
||||
return success ? 1 : 0;
|
||||
return compiler->compile(shaderStrings, numStrings, compileOptions);
|
||||
}
|
||||
|
||||
void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
|
||||
int ShGetShaderVersion(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !params)
|
||||
return;
|
||||
TCompiler* compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return compiler->getShaderVersion();
|
||||
}
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
case SH_INFO_LOG_LENGTH:
|
||||
*params = compiler->getInfoSink().info.size() + 1;
|
||||
break;
|
||||
case SH_OBJECT_CODE_LENGTH:
|
||||
*params = compiler->getInfoSink().obj.size() + 1;
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORMS:
|
||||
*params = compiler->getExpandedUniforms().size();
|
||||
break;
|
||||
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTES:
|
||||
*params = compiler->getAttributes().size();
|
||||
break;
|
||||
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_VARYINGS:
|
||||
*params = compiler->getExpandedVaryings().size();
|
||||
break;
|
||||
case SH_VARYING_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_MAPPED_NAME_MAX_LENGTH:
|
||||
// Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
|
||||
// handle array and struct dereferences.
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_NAME_MAX_LENGTH:
|
||||
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
break;
|
||||
case SH_HASHED_NAME_MAX_LENGTH:
|
||||
if (compiler->getHashFunction() == NULL) {
|
||||
*params = 0;
|
||||
} else {
|
||||
// 64 bits hashing output requires 16 bytes for hex
|
||||
// representation.
|
||||
const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
|
||||
(void)HashedNamePrefix;
|
||||
*params = 16 + sizeof(HashedNamePrefix);
|
||||
}
|
||||
break;
|
||||
case SH_HASHED_NAMES_COUNT:
|
||||
*params = compiler->getNameMap().size();
|
||||
break;
|
||||
case SH_SHADER_VERSION:
|
||||
*params = compiler->getShaderVersion();
|
||||
break;
|
||||
case SH_RESOURCES_STRING_LENGTH:
|
||||
*params = compiler->getBuiltInResourcesString().length() + 1;
|
||||
break;
|
||||
case SH_OUTPUT_TYPE:
|
||||
*params = compiler->getOutputType();
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
|
||||
{
|
||||
TCompiler* compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return compiler->getOutputType();
|
||||
}
|
||||
|
||||
//
|
||||
// Return any compiler log of messages for the application.
|
||||
//
|
||||
void ShGetInfoLog(const ShHandle handle, char* infoLog)
|
||||
const std::string &ShGetInfoLog(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !infoLog)
|
||||
return;
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(infoLog, infoSink.info.c_str());
|
||||
TInfoSink &infoSink = compiler->getInfoSink();
|
||||
return infoSink.info.str();
|
||||
}
|
||||
|
||||
//
|
||||
// Return any object code.
|
||||
//
|
||||
void ShGetObjectCode(const ShHandle handle, char* objCode)
|
||||
const std::string &ShGetObjectCode(const ShHandle handle)
|
||||
{
|
||||
if (!handle || !objCode)
|
||||
return;
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
TInfoSink& infoSink = compiler->getInfoSink();
|
||||
strcpy(objCode, infoSink.obj.c_str());
|
||||
TInfoSink &infoSink = compiler->getInfoSink();
|
||||
return infoSink.obj.str();
|
||||
}
|
||||
|
||||
void ShGetVariableInfo(const ShHandle handle,
|
||||
ShShaderInfo varType,
|
||||
int index,
|
||||
size_t* length,
|
||||
int* size,
|
||||
sh::GLenum* type,
|
||||
ShPrecisionType* precision,
|
||||
int* staticUse,
|
||||
char* name,
|
||||
char* mappedName)
|
||||
const std::map<std::string, std::string> *ShGetNameHashingMap(
|
||||
const ShHandle handle)
|
||||
{
|
||||
if (!handle || !size || !type || !precision || !staticUse || !name)
|
||||
return;
|
||||
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
|
||||
(varType == SH_ACTIVE_UNIFORMS) ||
|
||||
(varType == SH_VARYINGS));
|
||||
|
||||
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (compiler == 0)
|
||||
return;
|
||||
|
||||
const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
|
||||
if (!varInfo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (length) *length = varInfo->name.size();
|
||||
*size = varInfo->elementCount();
|
||||
*type = varInfo->type;
|
||||
*precision = ConvertPrecision(varInfo->precision);
|
||||
*staticUse = varInfo->staticUse ? 1 : 0;
|
||||
|
||||
// This size must match that queried by
|
||||
// SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
|
||||
// in ShGetInfo, below.
|
||||
size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
ASSERT(CheckVariableMaxLengths(handle, variableLength));
|
||||
strncpy(name, varInfo->name.c_str(), variableLength);
|
||||
name[variableLength - 1] = 0;
|
||||
if (mappedName)
|
||||
{
|
||||
// This size must match that queried by
|
||||
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
|
||||
size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
|
||||
ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
|
||||
strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
|
||||
mappedName[maxMappedNameLength - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ShGetNameHashingEntry(const ShHandle handle,
|
||||
int index,
|
||||
char* name,
|
||||
char* hashedName)
|
||||
{
|
||||
if (!handle || !name || !hashedName || index < 0)
|
||||
return;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TCompiler* compiler = base->getAsCompiler();
|
||||
if (!compiler) return;
|
||||
|
||||
const NameMap& nameMap = compiler->getNameMap();
|
||||
if (index >= static_cast<int>(nameMap.size()))
|
||||
return;
|
||||
|
||||
NameMap::const_iterator it = nameMap.begin();
|
||||
for (int i = 0; i < index; ++i)
|
||||
++it;
|
||||
|
||||
size_t len = it->first.length() + 1;
|
||||
size_t max_len = 0;
|
||||
ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
|
||||
if (len > max_len) {
|
||||
ASSERT(false);
|
||||
len = max_len;
|
||||
}
|
||||
strncpy(name, it->first.c_str(), len);
|
||||
// To be on the safe side in case the source is longer than expected.
|
||||
name[len - 1] = '\0';
|
||||
|
||||
len = it->second.length() + 1;
|
||||
max_len = 0;
|
||||
ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
|
||||
if (len > max_len) {
|
||||
ASSERT(false);
|
||||
len = max_len;
|
||||
}
|
||||
strncpy(hashedName, it->second.c_str(), len);
|
||||
// To be on the safe side in case the source is longer than expected.
|
||||
hashedName[len - 1] = '\0';
|
||||
TCompiler *compiler = GetCompilerFromHandle(handle);
|
||||
ASSERT(compiler);
|
||||
return &(compiler->getNameMap());
|
||||
}
|
||||
|
||||
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
|
||||
@ -515,11 +303,11 @@ const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handl
|
||||
return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
|
||||
}
|
||||
|
||||
int ShCheckVariablesWithinPackingLimits(
|
||||
int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
|
||||
bool ShCheckVariablesWithinPackingLimits(
|
||||
int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize)
|
||||
{
|
||||
if (varInfoArraySize == 0)
|
||||
return 1;
|
||||
return true;
|
||||
ASSERT(varInfoArray);
|
||||
std::vector<sh::ShaderVariable> variables;
|
||||
for (size_t ii = 0; ii < varInfoArraySize; ++ii)
|
||||
@ -528,24 +316,17 @@ int ShCheckVariablesWithinPackingLimits(
|
||||
variables.push_back(var);
|
||||
}
|
||||
VariablePacker packer;
|
||||
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
|
||||
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
|
||||
}
|
||||
|
||||
bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
const char *interfaceBlockName,
|
||||
const std::string &interfaceBlockName,
|
||||
unsigned int *indexOut)
|
||||
{
|
||||
if (!handle || !interfaceBlockName || !indexOut)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ASSERT(indexOut);
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
|
||||
if (!translator)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
|
||||
ASSERT(translator);
|
||||
|
||||
if (!translator->hasInterfaceBlock(interfaceBlockName))
|
||||
{
|
||||
@ -557,20 +338,12 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle,
|
||||
}
|
||||
|
||||
bool ShGetUniformRegister(const ShHandle handle,
|
||||
const char *uniformName,
|
||||
const std::string &uniformName,
|
||||
unsigned int *indexOut)
|
||||
{
|
||||
if (!handle || !uniformName || !indexOut)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
|
||||
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
|
||||
if (!translator)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ASSERT(indexOut);
|
||||
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
|
||||
ASSERT(translator);
|
||||
|
||||
if (!translator->hasUniform(uniformName))
|
||||
{
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include <GLSLANG/ShaderLang.h>
|
||||
|
||||
#include "compiler/translator/compilerdebug.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
@ -53,6 +55,126 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool ShaderVariable::operator==(const ShaderVariable &other) const
|
||||
{
|
||||
if (type != other.type ||
|
||||
precision != other.precision ||
|
||||
name != other.name ||
|
||||
mappedName != other.mappedName ||
|
||||
arraySize != other.arraySize ||
|
||||
staticUse != other.staticUse ||
|
||||
fields.size() != other.fields.size() ||
|
||||
structName != other.structName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (size_t ii = 0; ii < fields.size(); ++ii)
|
||||
{
|
||||
if (fields[ii] != other.fields[ii])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShaderVariable::findInfoByMappedName(
|
||||
const std::string &mappedFullName,
|
||||
const ShaderVariable **leafVar, std::string *originalFullName) const
|
||||
{
|
||||
ASSERT(leafVar && originalFullName);
|
||||
// There are three cases:
|
||||
// 1) the top variable is of struct type;
|
||||
// 2) the top variable is an array;
|
||||
// 3) otherwise.
|
||||
size_t pos = mappedFullName.find_first_of(".[");
|
||||
std::string topName;
|
||||
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
// Case 3.
|
||||
if (mappedFullName != this->mappedName)
|
||||
return false;
|
||||
*originalFullName = this->name;
|
||||
*leafVar = this;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string topName = mappedFullName.substr(0, pos);
|
||||
if (topName != this->mappedName)
|
||||
return false;
|
||||
std::string originalName = this->name;
|
||||
std::string remaining;
|
||||
if (mappedFullName[pos] == '[')
|
||||
{
|
||||
// Case 2.
|
||||
size_t closePos = mappedFullName.find_first_of(']');
|
||||
if (closePos < pos || closePos == std::string::npos)
|
||||
return false;
|
||||
// Append '[index]'.
|
||||
originalName += mappedFullName.substr(pos, closePos - pos + 1);
|
||||
if (closePos + 1 == mappedFullName.size())
|
||||
{
|
||||
*originalFullName = originalName;
|
||||
*leafVar = this;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In the form of 'a[0].b', so after ']', '.' is expected.
|
||||
if (mappedFullName[closePos + 1] != '.')
|
||||
return false;
|
||||
remaining = mappedFullName.substr(closePos + 2); // Skip "]."
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 1.
|
||||
remaining = mappedFullName.substr(pos + 1); // Skip "."
|
||||
}
|
||||
for (size_t ii = 0; ii < this->fields.size(); ++ii)
|
||||
{
|
||||
const ShaderVariable *fieldVar = NULL;
|
||||
std::string originalFieldName;
|
||||
bool found = fields[ii].findInfoByMappedName(
|
||||
remaining, &fieldVar, &originalFieldName);
|
||||
if (found)
|
||||
{
|
||||
*originalFullName = originalName + "." + originalFieldName;
|
||||
*leafVar = fieldVar;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ShaderVariable::isSameVariableAtLinkTime(
|
||||
const ShaderVariable &other, bool matchPrecision) const
|
||||
{
|
||||
if (type != other.type)
|
||||
return false;
|
||||
if (matchPrecision && precision != other.precision)
|
||||
return false;
|
||||
if (name != other.name)
|
||||
return false;
|
||||
ASSERT(mappedName == other.mappedName);
|
||||
if (arraySize != other.arraySize)
|
||||
return false;
|
||||
if (fields.size() != other.fields.size())
|
||||
return false;
|
||||
for (size_t ii = 0; ii < fields.size(); ++ii)
|
||||
{
|
||||
if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
|
||||
matchPrecision))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (structName != other.structName)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Uniform::Uniform()
|
||||
{}
|
||||
|
||||
@ -69,6 +191,16 @@ Uniform &Uniform::operator=(const Uniform &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Uniform::operator==(const Uniform &other) const
|
||||
{
|
||||
return ShaderVariable::operator==(other);
|
||||
}
|
||||
|
||||
bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
|
||||
{
|
||||
return ShaderVariable::isSameVariableAtLinkTime(other, true);
|
||||
}
|
||||
|
||||
Attribute::Attribute()
|
||||
: location(-1)
|
||||
{}
|
||||
@ -88,6 +220,12 @@ Attribute &Attribute::operator=(const Attribute &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Attribute::operator==(const Attribute &other) const
|
||||
{
|
||||
return (ShaderVariable::operator==(other) &&
|
||||
location == other.location);
|
||||
}
|
||||
|
||||
InterfaceBlockField::InterfaceBlockField()
|
||||
: isRowMajorLayout(false)
|
||||
{}
|
||||
@ -107,6 +245,19 @@ InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &o
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
|
||||
{
|
||||
return (ShaderVariable::operator==(other) &&
|
||||
isRowMajorLayout == other.isRowMajorLayout);
|
||||
}
|
||||
|
||||
bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
|
||||
const InterfaceBlockField &other) const
|
||||
{
|
||||
return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
|
||||
isRowMajorLayout == other.isRowMajorLayout);
|
||||
}
|
||||
|
||||
Varying::Varying()
|
||||
: interpolation(INTERPOLATION_SMOOTH),
|
||||
isInvariant(false)
|
||||
@ -129,6 +280,20 @@ Varying &Varying::operator=(const Varying &other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Varying::operator==(const Varying &other) const
|
||||
{
|
||||
return (ShaderVariable::operator==(other) &&
|
||||
interpolation == other.interpolation &&
|
||||
isInvariant == other.isInvariant);
|
||||
}
|
||||
|
||||
bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
|
||||
{
|
||||
return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
|
||||
interpolation == other.interpolation &&
|
||||
isInvariant == other.isInvariant);
|
||||
}
|
||||
|
||||
InterfaceBlock::InterfaceBlock()
|
||||
: arraySize(0),
|
||||
layout(BLOCKLAYOUT_PACKED),
|
||||
|
@ -31,6 +31,7 @@
|
||||
//
|
||||
|
||||
#include <assert.h>
|
||||
#include <set>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/translator/InfoSink.h"
|
||||
@ -299,19 +300,21 @@ class TSymbolTableLevel
|
||||
tLevel level;
|
||||
};
|
||||
|
||||
enum ESymbolLevel
|
||||
{
|
||||
COMMON_BUILTINS = 0,
|
||||
ESSL1_BUILTINS = 1,
|
||||
ESSL3_BUILTINS = 2,
|
||||
LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
|
||||
GLOBAL_LEVEL = 3
|
||||
};
|
||||
// Define ESymbolLevel as int rather than an enum since level can go
|
||||
// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
|
||||
// compiler optimizes the >= of the last element to ==.
|
||||
typedef int ESymbolLevel;
|
||||
const int COMMON_BUILTINS = 0;
|
||||
const int ESSL1_BUILTINS = 1;
|
||||
const int ESSL3_BUILTINS = 2;
|
||||
const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
|
||||
const int GLOBAL_LEVEL = 3;
|
||||
|
||||
class TSymbolTable
|
||||
{
|
||||
public:
|
||||
TSymbolTable()
|
||||
: mGlobalInvariant(false)
|
||||
{
|
||||
// The symbol table cannot be used until push() is called, but
|
||||
// the lack of an initial call to push() can be used to detect
|
||||
@ -408,6 +411,25 @@ class TSymbolTable
|
||||
// for the specified TBasicType
|
||||
TPrecision getDefaultPrecision(TBasicType type) const;
|
||||
|
||||
// This records invariant varyings declared through
|
||||
// "invariant varying_name;".
|
||||
void addInvariantVarying(const TString &originalName)
|
||||
{
|
||||
mInvariantVaryings.insert(originalName);
|
||||
}
|
||||
// If this returns false, the varying could still be invariant
|
||||
// if it is set as invariant during the varying variable
|
||||
// declaration - this piece of information is stored in the
|
||||
// variable's type, not here.
|
||||
bool isVaryingInvariant(const TString &originalName) const
|
||||
{
|
||||
return (mGlobalInvariant ||
|
||||
mInvariantVaryings.count(originalName) > 0);
|
||||
}
|
||||
|
||||
void setGlobalInvariant() { mGlobalInvariant = true; }
|
||||
bool getGlobalInvariant() const { return mGlobalInvariant; }
|
||||
|
||||
static int nextUniqueId()
|
||||
{
|
||||
return ++uniqueIdCounter;
|
||||
@ -423,6 +445,9 @@ class TSymbolTable
|
||||
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
|
||||
std::vector< PrecisionStackLevel *> precisionStack;
|
||||
|
||||
std::set<TString> mInvariantVaryings;
|
||||
bool mGlobalInvariant;
|
||||
|
||||
static int uniqueIdCounter;
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,8 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
|
||||
void TranslatorESSL::translate(TIntermNode* root) {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
|
||||
writePragma();
|
||||
|
||||
// Write built-in extension behaviors.
|
||||
writeExtensionBehavior();
|
||||
|
||||
@ -37,8 +39,13 @@ void TranslatorESSL::writeExtensionBehavior() {
|
||||
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
|
||||
iter != extensionBehavior.end(); ++iter) {
|
||||
if (iter->second != EBhUndefined) {
|
||||
sink << "#extension " << iter->first << " : "
|
||||
<< getBehaviorString(iter->second) << "\n";
|
||||
if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
|
||||
sink << "#extension GL_NV_draw_buffers : "
|
||||
<< getBehaviorString(iter->second) << "\n";
|
||||
} else {
|
||||
sink << "#extension " << iter->first << " : "
|
||||
<< getBehaviorString(iter->second) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,18 +9,6 @@
|
||||
#include "compiler/translator/OutputGLSL.h"
|
||||
#include "compiler/translator/VersionGLSL.h"
|
||||
|
||||
static void writeVersion(sh::GLenum type, TIntermNode* root,
|
||||
TInfoSinkBase& sink) {
|
||||
TVersionGLSL versionGLSL(type);
|
||||
root->traverse(&versionGLSL);
|
||||
int version = versionGLSL.getVersion();
|
||||
// We need to write version directive only if it is greater than 110.
|
||||
// If there is no version directive in the shader, 110 is implied.
|
||||
if (version > 110) {
|
||||
sink << "#version " << version << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
|
||||
: TCompiler(type, spec, SH_GLSL_OUTPUT) {
|
||||
}
|
||||
@ -29,7 +17,9 @@ void TranslatorGLSL::translate(TIntermNode* root) {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
|
||||
// Write GLSL version.
|
||||
writeVersion(getShaderType(), root, sink);
|
||||
writeVersion(root);
|
||||
|
||||
writePragma();
|
||||
|
||||
// Write extension behaviour as needed
|
||||
writeExtensionBehavior();
|
||||
@ -46,6 +36,20 @@ void TranslatorGLSL::translate(TIntermNode* root) {
|
||||
root->traverse(&outputGLSL);
|
||||
}
|
||||
|
||||
void TranslatorGLSL::writeVersion(TIntermNode *root)
|
||||
{
|
||||
TVersionGLSL versionGLSL(getShaderType(), getPragma());
|
||||
root->traverse(&versionGLSL);
|
||||
int version = versionGLSL.getVersion();
|
||||
// We need to write version directive only if it is greater than 110.
|
||||
// If there is no version directive in the shader, 110 is implied.
|
||||
if (version > 110)
|
||||
{
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
sink << "#version " << version << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void TranslatorGLSL::writeExtensionBehavior() {
|
||||
TInfoSinkBase& sink = getInfoSink().obj;
|
||||
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
|
||||
|
@ -9,14 +9,16 @@
|
||||
|
||||
#include "compiler/translator/Compiler.h"
|
||||
|
||||
class TranslatorGLSL : public TCompiler {
|
||||
public:
|
||||
class TranslatorGLSL : public TCompiler
|
||||
{
|
||||
public:
|
||||
TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
|
||||
|
||||
protected:
|
||||
virtual void translate(TIntermNode* root);
|
||||
protected:
|
||||
virtual void translate(TIntermNode *root);
|
||||
|
||||
private:
|
||||
private:
|
||||
void writeVersion(TIntermNode *root);
|
||||
void writeExtensionBehavior();
|
||||
};
|
||||
|
||||
|
@ -94,6 +94,7 @@ const char *GetOperatorString(TOperator op)
|
||||
case EOpLogicalXor: return "^^";
|
||||
case EOpLogicalAnd: return "&&";
|
||||
case EOpNegative: return "-";
|
||||
case EOpPositive: return "+";
|
||||
case EOpVectorLogicalNot: return "not";
|
||||
case EOpLogicalNot: return "!";
|
||||
case EOpPostIncrement: return "++";
|
||||
|
@ -5,6 +5,7 @@
|
||||
//
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "compiler/translator/VariableInfo.h"
|
||||
#include "compiler/translator/util.h"
|
||||
#include "common/utilities.h"
|
||||
@ -131,7 +132,8 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
|
||||
std::vector<sh::Uniform> *uniforms,
|
||||
std::vector<sh::Varying> *varyings,
|
||||
std::vector<sh::InterfaceBlock> *interfaceBlocks,
|
||||
ShHashFunction64 hashFunction)
|
||||
ShHashFunction64 hashFunction,
|
||||
const TSymbolTable &symbolTable)
|
||||
: mAttribs(attribs),
|
||||
mOutputVariables(outputVariables),
|
||||
mUniforms(uniforms),
|
||||
@ -140,7 +142,10 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
|
||||
mPointCoordAdded(false),
|
||||
mFrontFacingAdded(false),
|
||||
mFragCoordAdded(false),
|
||||
mHashFunction(hashFunction)
|
||||
mPositionAdded(false),
|
||||
mPointSizeAdded(false),
|
||||
mHashFunction(hashFunction),
|
||||
mSymbolTable(symbolTable)
|
||||
{
|
||||
}
|
||||
|
||||
@ -200,12 +205,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
if (!mFragCoordAdded)
|
||||
{
|
||||
Varying info;
|
||||
info.name = "gl_FragCoord";
|
||||
info.mappedName = "gl_FragCoord";
|
||||
const char kName[] = "gl_FragCoord";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT_VEC4;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
|
||||
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mFragCoordAdded = true;
|
||||
}
|
||||
@ -214,12 +221,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
if (!mFrontFacingAdded)
|
||||
{
|
||||
Varying info;
|
||||
info.name = "gl_FrontFacing";
|
||||
info.mappedName = "gl_FrontFacing";
|
||||
const char kName[] = "gl_FrontFacing";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_BOOL;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_NONE;
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mFrontFacingAdded = true;
|
||||
}
|
||||
@ -228,16 +237,50 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
if (!mPointCoordAdded)
|
||||
{
|
||||
Varying info;
|
||||
info.name = "gl_PointCoord";
|
||||
info.mappedName = "gl_PointCoord";
|
||||
const char kName[] = "gl_PointCoord";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT_VEC2;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
|
||||
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mPointCoordAdded = true;
|
||||
}
|
||||
return;
|
||||
case EvqPosition:
|
||||
if (!mPositionAdded)
|
||||
{
|
||||
Varying info;
|
||||
const char kName[] = "gl_Position";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT_VEC4;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_HIGH_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mPositionAdded = true;
|
||||
}
|
||||
return;
|
||||
case EvqPointSize:
|
||||
if (!mPointSizeAdded)
|
||||
{
|
||||
Varying info;
|
||||
const char kName[] = "gl_PointSize";
|
||||
info.name = kName;
|
||||
info.mappedName = kName;
|
||||
info.type = GL_FLOAT;
|
||||
info.arraySize = 0;
|
||||
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
|
||||
info.staticUse = true;
|
||||
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
|
||||
mVaryings->push_back(info);
|
||||
mPointSizeAdded = true;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -251,8 +294,10 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
|
||||
class NameHashingTraverser : public GetVariableTraverser
|
||||
{
|
||||
public:
|
||||
NameHashingTraverser(ShHashFunction64 hashFunction)
|
||||
: mHashFunction(hashFunction)
|
||||
NameHashingTraverser(ShHashFunction64 hashFunction,
|
||||
const TSymbolTable &symbolTable)
|
||||
: GetVariableTraverser(symbolTable),
|
||||
mHashFunction(hashFunction)
|
||||
{}
|
||||
|
||||
private:
|
||||
@ -312,7 +357,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
|
||||
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
|
||||
const TType &fieldType = *field.type();
|
||||
|
||||
GetVariableTraverser traverser;
|
||||
GetVariableTraverser traverser(mSymbolTable);
|
||||
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
|
||||
|
||||
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
|
||||
@ -325,7 +370,7 @@ template <typename VarT>
|
||||
void CollectVariables::visitVariable(const TIntermSymbol *variable,
|
||||
std::vector<VarT> *infoList) const
|
||||
{
|
||||
NameHashingTraverser traverser(mHashFunction);
|
||||
NameHashingTraverser traverser(mHashFunction, mSymbolTable);
|
||||
traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
|
||||
}
|
||||
|
||||
@ -421,9 +466,8 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
void ExpandVariables(const std::vector<VarT> &compact,
|
||||
std::vector<ShaderVariable> *expanded)
|
||||
void ExpandUniforms(const std::vector<Uniform> &compact,
|
||||
std::vector<ShaderVariable> *expanded)
|
||||
{
|
||||
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
|
||||
{
|
||||
@ -432,7 +476,4 @@ void ExpandVariables(const std::vector<VarT> &compact,
|
||||
}
|
||||
}
|
||||
|
||||
template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
|
||||
template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
class TSymbolTable;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
@ -23,7 +25,8 @@ class CollectVariables : public TIntermTraverser
|
||||
std::vector<Uniform> *uniforms,
|
||||
std::vector<Varying> *varyings,
|
||||
std::vector<InterfaceBlock> *interfaceBlocks,
|
||||
ShHashFunction64 hashFunction);
|
||||
ShHashFunction64 hashFunction,
|
||||
const TSymbolTable &symbolTable);
|
||||
|
||||
virtual void visitSymbol(TIntermSymbol *symbol);
|
||||
virtual bool visitAggregate(Visit, TIntermAggregate *node);
|
||||
@ -48,13 +51,17 @@ class CollectVariables : public TIntermTraverser
|
||||
bool mFrontFacingAdded;
|
||||
bool mFragCoordAdded;
|
||||
|
||||
bool mPositionAdded;
|
||||
bool mPointSizeAdded;
|
||||
|
||||
ShHashFunction64 mHashFunction;
|
||||
|
||||
const TSymbolTable &mSymbolTable;
|
||||
};
|
||||
|
||||
// Expand struct variables to flattened lists of split variables
|
||||
template <typename VarT>
|
||||
void ExpandVariables(const std::vector<VarT> &compact,
|
||||
std::vector<ShaderVariable> *expanded);
|
||||
// Expand struct uniforms to flattened lists of split variables
|
||||
void ExpandUniforms(const std::vector<Uniform> &compact,
|
||||
std::vector<ShaderVariable> *expanded);
|
||||
|
||||
}
|
||||
|
||||
|
@ -26,18 +26,12 @@ static const int GLSL_VERSION_120 = 120;
|
||||
// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
|
||||
// are built-in types, entire structures or arrays... are all l-values."
|
||||
//
|
||||
// TODO(alokp): The following two cases of invariant decalaration get lost
|
||||
// during parsing - they do not get carried over to the intermediate tree.
|
||||
// Handle these cases:
|
||||
// 1. When a pragma is used to force all output variables to be invariant:
|
||||
// - #pragma STDGL invariant(all)
|
||||
// 2. When a previously decalared or built-in variable is marked invariant:
|
||||
// - invariant gl_Position;
|
||||
// - varying vec3 color; invariant color;
|
||||
//
|
||||
TVersionGLSL::TVersionGLSL(sh::GLenum type)
|
||||
: mVersion(GLSL_VERSION_110)
|
||||
TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma)
|
||||
{
|
||||
if (pragma.stdgl.invariantAll)
|
||||
mVersion = GLSL_VERSION_120;
|
||||
else
|
||||
mVersion = GLSL_VERSION_110;
|
||||
}
|
||||
|
||||
void TVersionGLSL::visitSymbol(TIntermSymbol *node)
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "compiler/translator/IntermNode.h"
|
||||
|
||||
#include "compiler/translator/Pragma.h"
|
||||
|
||||
// Traverses the intermediate tree to return the minimum GLSL version
|
||||
// required to legally access all built-in features used in the shader.
|
||||
// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
|
||||
@ -27,7 +29,7 @@
|
||||
class TVersionGLSL : public TIntermTraverser
|
||||
{
|
||||
public:
|
||||
TVersionGLSL(sh::GLenum type);
|
||||
TVersionGLSL(sh::GLenum type, const TPragma &pragma);
|
||||
|
||||
// Returns 120 if the following is used the shader:
|
||||
// - "invariant",
|
||||
|
@ -354,6 +354,15 @@ function_call
|
||||
// Treat it like a built-in unary operator.
|
||||
//
|
||||
$$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1);
|
||||
const TType& returnType = fnCandidate->getReturnType();
|
||||
if (returnType.getBasicType() == EbtBool) {
|
||||
// Bool types should not have precision, so we'll override any precision
|
||||
// that might have been set by addUnaryMath.
|
||||
$$->setType(returnType);
|
||||
} else {
|
||||
// addUnaryMath has set the precision of the node based on the operand.
|
||||
$$->setTypePreservePrecision(returnType);
|
||||
}
|
||||
if ($$ == 0) {
|
||||
std::stringstream extraInfoStream;
|
||||
extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
|
||||
@ -362,20 +371,29 @@ function_call
|
||||
YYERROR;
|
||||
}
|
||||
} else {
|
||||
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
|
||||
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
|
||||
aggregate->setType(fnCandidate->getReturnType());
|
||||
aggregate->setPrecisionFromChildren();
|
||||
$$ = aggregate;
|
||||
}
|
||||
} else {
|
||||
// This is a real function call
|
||||
|
||||
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
|
||||
$$->setType(fnCandidate->getReturnType());
|
||||
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
|
||||
aggregate->setType(fnCandidate->getReturnType());
|
||||
|
||||
// this is how we know whether the given function is a builtIn function or a user defined function
|
||||
// if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
|
||||
// if builtIn == true, it's definitely a builtIn function with EOpNull
|
||||
if (!builtIn)
|
||||
$$->getAsAggregate()->setUserDefined();
|
||||
$$->getAsAggregate()->setName(fnCandidate->getMangledName());
|
||||
aggregate->setUserDefined();
|
||||
aggregate->setName(fnCandidate->getMangledName());
|
||||
|
||||
// This needs to happen after the name is set
|
||||
if (builtIn)
|
||||
aggregate->setBuiltInFunctionPrecision();
|
||||
|
||||
$$ = aggregate;
|
||||
|
||||
TQualifier qual;
|
||||
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
|
||||
@ -388,7 +406,6 @@ function_call
|
||||
}
|
||||
}
|
||||
}
|
||||
$$->setType(fnCandidate->getReturnType());
|
||||
} else {
|
||||
// error message was put out by PaFindFunction()
|
||||
// Put on a dummy node for error recovery
|
||||
@ -500,6 +517,7 @@ unary_expression
|
||||
const char* errorOp = "";
|
||||
switch($1.op) {
|
||||
case EOpNegative: errorOp = "-"; break;
|
||||
case EOpPositive: errorOp = "+"; break;
|
||||
case EOpLogicalNot: errorOp = "!"; break;
|
||||
default: break;
|
||||
}
|
||||
@ -514,7 +532,7 @@ unary_expression
|
||||
// Grammar Note: No traditional style type casts.
|
||||
|
||||
unary_operator
|
||||
: PLUS { $$.op = EOpNull; }
|
||||
: PLUS { $$.op = EOpPositive; }
|
||||
| DASH { $$.op = EOpNegative; }
|
||||
| BANG { $$.op = EOpLogicalNot; }
|
||||
;
|
||||
@ -762,7 +780,7 @@ declaration
|
||||
|
||||
TIntermAggregate *prototype = new TIntermAggregate;
|
||||
prototype->setType(function.getReturnType());
|
||||
prototype->setName(function.getName());
|
||||
prototype->setName(function.getMangledName());
|
||||
|
||||
for (size_t i = 0; i < function.getParamCount(); i++)
|
||||
{
|
||||
|
@ -62,7 +62,9 @@ TString TType::getCompleteString() const
|
||||
TStringStream stream;
|
||||
|
||||
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
|
||||
stream << getQualifierString() << " " << getPrecisionString() << " ";
|
||||
stream << getQualifierString() << " ";
|
||||
if (precision != EbpUndefined)
|
||||
stream << getPrecisionString() << " ";
|
||||
if (array)
|
||||
stream << "array[" << getArraySize() << "] of ";
|
||||
if (isMatrix())
|
||||
@ -221,6 +223,7 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
|
||||
switch (node->getOp())
|
||||
{
|
||||
case EOpNegative: out << "Negate value"; break;
|
||||
case EOpPositive: out << "Positive sign"; break;
|
||||
case EOpVectorLogicalNot:
|
||||
case EOpLogicalNot: out << "Negate conditional"; break;
|
||||
|
||||
@ -292,6 +295,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
|
||||
case EOpFunction: out << "Function Definition: " << node->getName(); break;
|
||||
case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
|
||||
case EOpParameters: out << "Function Parameters: "; break;
|
||||
case EOpPrototype: out << "Function Prototype: " << node->getName(); break;
|
||||
|
||||
case EOpConstructFloat: out << "Construct float"; break;
|
||||
case EOpConstructVec2: out << "Construct vec2"; break;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include "compiler/preprocessor/numeric_lex.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
#include "common/utilities.h"
|
||||
|
||||
bool atof_clamp(const char *str, float *value)
|
||||
@ -281,8 +282,47 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
|
||||
}
|
||||
}
|
||||
|
||||
GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
|
||||
: mSymbolTable(symbolTable)
|
||||
{
|
||||
}
|
||||
|
||||
template void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, InterfaceBlockField *variable);
|
||||
template void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, ShaderVariable *variable);
|
||||
template void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, Uniform *variable);
|
||||
|
||||
template<>
|
||||
void GetVariableTraverser::setTypeSpecificInfo(
|
||||
const TType &type, const TString& name, Varying *variable)
|
||||
{
|
||||
ASSERT(variable);
|
||||
switch (type.getQualifier())
|
||||
{
|
||||
case EvqInvariantVaryingIn:
|
||||
case EvqInvariantVaryingOut:
|
||||
variable->isInvariant = true;
|
||||
break;
|
||||
case EvqVaryingIn:
|
||||
case EvqVaryingOut:
|
||||
if (mSymbolTable.isVaryingInvariant(name))
|
||||
{
|
||||
variable->isInvariant = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
variable->interpolation = GetInterpolationType(type.getQualifier());
|
||||
}
|
||||
|
||||
template <typename VarT>
|
||||
void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
|
||||
void GetVariableTraverser::traverse(const TType &type,
|
||||
const TString &name,
|
||||
std::vector<VarT> *output)
|
||||
{
|
||||
const TStructure *structure = type.getStruct();
|
||||
|
||||
@ -309,15 +349,16 @@ void GetVariableTraverser::traverse(const TType &type, const TString &name, std:
|
||||
traverse(*field->type(), field->name(), &variable.fields);
|
||||
}
|
||||
}
|
||||
|
||||
setTypeSpecificInfo(type, name, &variable);
|
||||
visitVariable(&variable);
|
||||
|
||||
ASSERT(output);
|
||||
output->push_back(variable);
|
||||
}
|
||||
|
||||
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
|
||||
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
|
||||
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
|
||||
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
|
||||
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ extern bool atof_clamp(const char *str, float *value);
|
||||
// Return false if overflow happens.
|
||||
extern bool atoi_clamp(const char *str, int *value);
|
||||
|
||||
class TSymbolTable;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
@ -38,7 +40,7 @@ TString ArrayString(const TType &type);
|
||||
class GetVariableTraverser
|
||||
{
|
||||
public:
|
||||
GetVariableTraverser() {}
|
||||
GetVariableTraverser(const TSymbolTable &symbolTable);
|
||||
|
||||
template <typename VarT>
|
||||
void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
|
||||
@ -48,6 +50,14 @@ class GetVariableTraverser
|
||||
virtual void visitVariable(ShaderVariable *newVar) {}
|
||||
|
||||
private:
|
||||
// Helper function called by traverse() to fill specific fields
|
||||
// for attributes/varyings/uniforms.
|
||||
template <typename VarT>
|
||||
void setTypeSpecificInfo(
|
||||
const TType &type, const TString &name, VarT *variable) {}
|
||||
|
||||
const TSymbolTable &mSymbolTable;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
|
||||
};
|
||||
|
||||
|
40
src/3rdparty/angle/src/libEGL/AttributeMap.cpp
vendored
Normal file
40
src/3rdparty/angle/src/libEGL/AttributeMap.cpp
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#include "libEGL/AttributeMap.h"
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
AttributeMap::AttributeMap()
|
||||
{
|
||||
}
|
||||
|
||||
AttributeMap::AttributeMap(const EGLint *attributes)
|
||||
{
|
||||
for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
|
||||
{
|
||||
insert(curAttrib[0], curAttrib[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void AttributeMap::insert(EGLint key, EGLint value)
|
||||
{
|
||||
mAttributes[key] = value;
|
||||
}
|
||||
|
||||
bool AttributeMap::contains(EGLint key) const
|
||||
{
|
||||
return (mAttributes.find(key) != mAttributes.end());
|
||||
}
|
||||
|
||||
EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const
|
||||
{
|
||||
std::map<EGLint, EGLint>::const_iterator iter = mAttributes.find(key);
|
||||
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
|
||||
}
|
||||
|
||||
}
|
33
src/3rdparty/angle/src/libEGL/AttributeMap.h
vendored
Normal file
33
src/3rdparty/angle/src/libEGL/AttributeMap.h
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
#ifndef LIBEGL_ATTRIBUTEMAP_H_
|
||||
#define LIBEGL_ATTRIBUTEMAP_H_
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
class AttributeMap
|
||||
{
|
||||
public:
|
||||
AttributeMap();
|
||||
explicit AttributeMap(const EGLint *attributes);
|
||||
|
||||
virtual void insert(EGLint key, EGLint value);
|
||||
virtual bool contains(EGLint key) const;
|
||||
virtual EGLint get(EGLint key, EGLint defaultValue) const;
|
||||
|
||||
private:
|
||||
std::map<EGLint, EGLint> mAttributes;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBEGL_ATTRIBUTEMAP_H_
|
169
src/3rdparty/angle/src/libEGL/Display.cpp
vendored
169
src/3rdparty/angle/src/libEGL/Display.cpp
vendored
@ -35,32 +35,36 @@ static DisplayMap *GetDisplayMap()
|
||||
return &displays;
|
||||
}
|
||||
|
||||
egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, EGLint displayType)
|
||||
egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap)
|
||||
{
|
||||
Display *display = NULL;
|
||||
|
||||
DisplayMap *displays = GetDisplayMap();
|
||||
DisplayMap::const_iterator iter = displays->find(displayId);
|
||||
if (iter != displays->end())
|
||||
{
|
||||
return iter->second;
|
||||
display = iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
display = new egl::Display(displayId);
|
||||
displays->insert(std::make_pair(displayId, display));
|
||||
}
|
||||
|
||||
// FIXME: Check if displayId is a valid display device context
|
||||
|
||||
egl::Display *display = new egl::Display(displayId, displayType);
|
||||
displays->insert(std::make_pair(displayId, display));
|
||||
// Apply new attributes if the display is not initialized yet.
|
||||
if (!display->isInitialized())
|
||||
{
|
||||
display->setAttributes(attribMap);
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
Display::Display(EGLNativeDisplayType displayId, EGLint displayType)
|
||||
Display::Display(EGLNativeDisplayType displayId)
|
||||
: mDisplayId(displayId),
|
||||
mRequestedDisplayType(displayType),
|
||||
mAttributeMap(),
|
||||
mRenderer(NULL)
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mDisplayId)
|
||||
mDisplayId->AddRef();
|
||||
#endif
|
||||
}
|
||||
|
||||
Display::~Display()
|
||||
@ -73,28 +77,29 @@ Display::~Display()
|
||||
{
|
||||
displays->erase(iter);
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mDisplayId)
|
||||
mDisplayId->Release();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Display::initialize()
|
||||
void Display::setAttributes(const AttributeMap &attribMap)
|
||||
{
|
||||
mAttributeMap = attribMap;
|
||||
}
|
||||
|
||||
Error Display::initialize()
|
||||
{
|
||||
if (isInitialized())
|
||||
{
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
mRenderer = glCreateRenderer(this, mDisplayId, mRequestedDisplayType);
|
||||
mRenderer = glCreateRenderer(this, mDisplayId, mAttributeMap);
|
||||
|
||||
if (!mRenderer)
|
||||
{
|
||||
terminate();
|
||||
return error(EGL_NOT_INITIALIZED, false);
|
||||
return Error(EGL_NOT_INITIALIZED);
|
||||
}
|
||||
|
||||
//TODO(jmadill): should be part of caps?
|
||||
EGLint minSwapInterval = mRenderer->getMinSwapInterval();
|
||||
EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
|
||||
EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
|
||||
@ -125,13 +130,13 @@ bool Display::initialize()
|
||||
if (!isInitialized())
|
||||
{
|
||||
terminate();
|
||||
return false;
|
||||
return Error(EGL_NOT_INITIALIZED);
|
||||
}
|
||||
|
||||
initDisplayExtensionString();
|
||||
initVendorString();
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
void Display::terminate()
|
||||
@ -148,6 +153,8 @@ void Display::terminate()
|
||||
|
||||
glDestroyRenderer(mRenderer);
|
||||
mRenderer = NULL;
|
||||
|
||||
mConfigSet.mSet.clear();
|
||||
}
|
||||
|
||||
bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
|
||||
@ -202,7 +209,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
|
||||
|
||||
|
||||
|
||||
EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
|
||||
Error Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface)
|
||||
{
|
||||
const Config *configuration = mConfigSet.get(config);
|
||||
EGLint postSubBufferSupported = EGL_FALSE;
|
||||
@ -223,9 +230,9 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
case EGL_BACK_BUFFER:
|
||||
break;
|
||||
case EGL_SINGLE_BUFFER:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported
|
||||
return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
break;
|
||||
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
|
||||
@ -241,11 +248,11 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
fixedSize = attribList[1];
|
||||
break;
|
||||
case EGL_VG_COLORSPACE:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
case EGL_VG_ALPHA_FORMAT:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
attribList += 2;
|
||||
@ -254,7 +261,7 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
{
|
||||
return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
if (!fixedSize)
|
||||
@ -265,29 +272,33 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
|
||||
|
||||
if (hasExistingWindowSurface(window))
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ALLOC);
|
||||
}
|
||||
|
||||
if (mRenderer->testDeviceLost(false))
|
||||
{
|
||||
if (!restoreLostDevice())
|
||||
return EGL_NO_SURFACE;
|
||||
Error error = restoreLostDevice();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
Surface *surface = new Surface(this, configuration, window, fixedSize, width, height, postSubBufferSupported);
|
||||
|
||||
if (!surface->initialize())
|
||||
Error error = surface->initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
delete surface;
|
||||
return EGL_NO_SURFACE;
|
||||
SafeDelete(surface);
|
||||
return error;
|
||||
}
|
||||
|
||||
mSurfaceSet.insert(surface);
|
||||
|
||||
return success(surface);
|
||||
*outSurface = surface;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
|
||||
Error Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface)
|
||||
{
|
||||
EGLint width = 0, height = 0;
|
||||
EGLenum textureFormat = EGL_NO_TEXTURE;
|
||||
@ -319,7 +330,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
|
||||
textureFormat = attribList[1];
|
||||
break;
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
break;
|
||||
case EGL_TEXTURE_TARGET:
|
||||
@ -330,19 +341,19 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
|
||||
textureTarget = attribList[1];
|
||||
break;
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
break;
|
||||
case EGL_MIPMAP_TEXTURE:
|
||||
if (attribList[1] != EGL_FALSE)
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
break;
|
||||
case EGL_VG_COLORSPACE:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
case EGL_VG_ALPHA_FORMAT:
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
default:
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
attribList += 2;
|
||||
@ -351,86 +362,98 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
|
||||
|
||||
if (width < 0 || height < 0)
|
||||
{
|
||||
return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
|
||||
{
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
}
|
||||
|
||||
if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
|
||||
(textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
|
||||
{
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
}
|
||||
|
||||
if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
|
||||
{
|
||||
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_MATCH);
|
||||
}
|
||||
|
||||
if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
|
||||
(textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
|
||||
{
|
||||
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
|
||||
return Error(EGL_BAD_ATTRIBUTE);
|
||||
}
|
||||
|
||||
if (mRenderer->testDeviceLost(false))
|
||||
{
|
||||
if (!restoreLostDevice())
|
||||
return EGL_NO_SURFACE;
|
||||
Error error = restoreLostDevice();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
|
||||
|
||||
if (!surface->initialize())
|
||||
Error error = surface->initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
delete surface;
|
||||
return EGL_NO_SURFACE;
|
||||
SafeDelete(surface);
|
||||
return error;
|
||||
}
|
||||
|
||||
mSurfaceSet.insert(surface);
|
||||
|
||||
return success(surface);
|
||||
*outSurface = surface;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
|
||||
Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
|
||||
bool robustAccess, EGLContext *outContext)
|
||||
{
|
||||
if (!mRenderer)
|
||||
{
|
||||
return EGL_NO_CONTEXT;
|
||||
*outContext = EGL_NO_CONTEXT;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
else if (mRenderer->testDeviceLost(false)) // Lost device
|
||||
{
|
||||
if (!restoreLostDevice())
|
||||
Error error = restoreLostDevice();
|
||||
if (error.isError())
|
||||
{
|
||||
return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO(jmadill): shader model is not cross-platform
|
||||
if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4)
|
||||
{
|
||||
return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
|
||||
return Error(EGL_BAD_CONFIG);
|
||||
}
|
||||
|
||||
gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
|
||||
mContextSet.insert(context);
|
||||
|
||||
return success(context);
|
||||
*outContext = context;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Display::restoreLostDevice()
|
||||
Error Display::restoreLostDevice()
|
||||
{
|
||||
for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
|
||||
{
|
||||
if ((*ctx)->isResetNotificationEnabled())
|
||||
return false; // If reset notifications have been requested, application must delete all contexts first
|
||||
{
|
||||
// If reset notifications have been requested, application must delete all contexts first
|
||||
return Error(EGL_CONTEXT_LOST);
|
||||
}
|
||||
}
|
||||
|
||||
// Release surface resources to make the Reset() succeed
|
||||
@ -441,16 +464,20 @@ bool Display::restoreLostDevice()
|
||||
|
||||
if (!mRenderer->resetDevice())
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
return Error(EGL_BAD_ALLOC);
|
||||
}
|
||||
|
||||
// Restore any surfaces that may have been lost
|
||||
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
|
||||
{
|
||||
(*surface)->resetSwapChain();
|
||||
Error error = (*surface)->resetSwapChain();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@ -472,7 +499,6 @@ void Display::notifyDeviceLost()
|
||||
{
|
||||
(*context)->markContextLost();
|
||||
}
|
||||
egl::error(EGL_CONTEXT_LOST);
|
||||
}
|
||||
|
||||
void Display::recreateSwapChains()
|
||||
@ -604,10 +630,11 @@ void Display::initVendorString()
|
||||
|
||||
LUID adapterLuid = {0};
|
||||
|
||||
//TODO(jmadill): LUID is not cross-platform
|
||||
if (mRenderer && mRenderer->getLUID(&adapterLuid))
|
||||
{
|
||||
char adapterLuidString[64];
|
||||
snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
|
||||
sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
|
||||
|
||||
mVendorString += adapterLuidString;
|
||||
}
|
||||
|
22
src/3rdparty/angle/src/libEGL/Display.h
vendored
22
src/3rdparty/angle/src/libEGL/Display.h
vendored
@ -14,7 +14,9 @@
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
#include "libEGL/Config.h"
|
||||
#include "libEGL/AttributeMap.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -30,10 +32,10 @@ class Display
|
||||
public:
|
||||
~Display();
|
||||
|
||||
bool initialize();
|
||||
Error initialize();
|
||||
void terminate();
|
||||
|
||||
static egl::Display *getDisplay(EGLNativeDisplayType displayId, EGLint displayType);
|
||||
static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap);
|
||||
|
||||
static const char *getExtensionString(egl::Display *display);
|
||||
|
||||
@ -43,9 +45,10 @@ class Display
|
||||
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
|
||||
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
|
||||
|
||||
EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
|
||||
EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
|
||||
EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
|
||||
Error createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface);
|
||||
Error createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface);
|
||||
Error createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
|
||||
bool robustAccess, EGLContext *outContext);
|
||||
|
||||
void destroySurface(egl::Surface *surface);
|
||||
void destroyContext(gl::Context *context);
|
||||
@ -64,18 +67,19 @@ class Display
|
||||
|
||||
const char *getExtensionString() const;
|
||||
const char *getVendorString() const;
|
||||
|
||||
EGLNativeDisplayType getDisplayId() const { return mDisplayId; }
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Display);
|
||||
|
||||
Display(EGLNativeDisplayType displayId, EGLint displayType);
|
||||
Display(EGLNativeDisplayType displayId);
|
||||
|
||||
bool restoreLostDevice();
|
||||
void setAttributes(const AttributeMap &attribMap);
|
||||
|
||||
Error restoreLostDevice();
|
||||
|
||||
EGLNativeDisplayType mDisplayId;
|
||||
EGLint mRequestedDisplayType;
|
||||
AttributeMap mAttributeMap;
|
||||
|
||||
typedef std::set<Surface*> SurfaceSet;
|
||||
SurfaceSet mSurfaceSet;
|
||||
|
48
src/3rdparty/angle/src/libEGL/Error.cpp
vendored
Normal file
48
src/3rdparty/angle/src/libEGL/Error.cpp
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
// Error.cpp: Implements the egl::Error class which encapsulates an EGL error
|
||||
// and optional error message.
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
Error::Error(EGLint errorCode)
|
||||
: mCode(errorCode),
|
||||
mMessage()
|
||||
{
|
||||
}
|
||||
|
||||
Error::Error(EGLint errorCode, const char *msg, ...)
|
||||
: mCode(errorCode),
|
||||
mMessage()
|
||||
{
|
||||
va_list vararg;
|
||||
va_start(vararg, msg);
|
||||
mMessage = FormatString(msg, vararg);
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
Error::Error(const Error &other)
|
||||
: mCode(other.mCode),
|
||||
mMessage(other.mMessage)
|
||||
{
|
||||
}
|
||||
|
||||
Error &Error::operator=(const Error &other)
|
||||
{
|
||||
mCode = other.mCode;
|
||||
mMessage = other.mMessage;
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
39
src/3rdparty/angle/src/libEGL/Error.h
vendored
Normal file
39
src/3rdparty/angle/src/libEGL/Error.h
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Error.h: Defines the egl::Error class which encapsulates an EGL error
|
||||
// and optional error message.
|
||||
|
||||
#ifndef LIBEGL_ERROR_H_
|
||||
#define LIBEGL_ERROR_H_
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
class Error
|
||||
{
|
||||
public:
|
||||
explicit Error(EGLint errorCode);
|
||||
Error(EGLint errorCode, const char *msg, ...);
|
||||
Error(const Error &other);
|
||||
Error &operator=(const Error &other);
|
||||
|
||||
EGLint getCode() const { return mCode; }
|
||||
bool isError() const { return (mCode != EGL_SUCCESS); }
|
||||
|
||||
const std::string &getMessage() const { return mMessage; }
|
||||
|
||||
private:
|
||||
EGLint mCode;
|
||||
std::string mMessage;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBEGL_ERROR_H_
|
339
src/3rdparty/angle/src/libEGL/Surface.cpp
vendored
339
src/3rdparty/angle/src/libEGL/Surface.cpp
vendored
@ -22,23 +22,19 @@
|
||||
#include "libEGL/main.h"
|
||||
#include "libEGL/Display.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
# include "wrl.h"
|
||||
# include "windows.graphics.display.h"
|
||||
# include "windows.ui.core.h"
|
||||
using namespace ABI::Windows::Graphics::Display;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::UI::Core;
|
||||
using namespace Microsoft::WRL;
|
||||
#endif
|
||||
#include "common/NativeWindow.h"
|
||||
|
||||
//TODO(jmadill): phase this out
|
||||
#include "libGLESv2/renderer/d3d/RendererD3D.h"
|
||||
|
||||
namespace egl
|
||||
{
|
||||
|
||||
Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
|
||||
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
|
||||
: mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported)
|
||||
{
|
||||
mRenderer = mDisplay->getRenderer();
|
||||
//TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
|
||||
mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
|
||||
mSwapChain = NULL;
|
||||
mShareHandle = NULL;
|
||||
mTexture = NULL;
|
||||
@ -51,27 +47,19 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
|
||||
mSwapInterval = -1;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFixedWidth = mWidth;
|
||||
mFixedHeight = mHeight;
|
||||
setSwapInterval(1);
|
||||
mFixedSize = fixedSize;
|
||||
mSwapFlags = rx::SWAP_NORMAL;
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mWindow)
|
||||
mWindow->AddRef();
|
||||
mScaleFactor = 1.0;
|
||||
mSizeToken.value = 0;
|
||||
mDpiToken.value = 0;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
mOrientationToken.value = 0;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
subclassWindow();
|
||||
}
|
||||
|
||||
Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
|
||||
: mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
|
||||
: mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
|
||||
{
|
||||
mRenderer = mDisplay->getRenderer();
|
||||
//TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
|
||||
mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
|
||||
mSwapChain = NULL;
|
||||
mWindowSubclassed = false;
|
||||
mTexture = NULL;
|
||||
@ -85,90 +73,33 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL
|
||||
setSwapInterval(1);
|
||||
// This constructor is for offscreen surfaces, which are always fixed-size.
|
||||
mFixedSize = EGL_TRUE;
|
||||
mSwapFlags = rx::SWAP_NORMAL;
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
mScaleFactor = 1.0;
|
||||
mSizeToken.value = 0;
|
||||
mDpiToken.value = 0;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
mOrientationToken.value = 0;
|
||||
# endif
|
||||
#endif
|
||||
mFixedWidth = mWidth;
|
||||
mFixedHeight = mHeight;
|
||||
}
|
||||
|
||||
Surface::~Surface()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mSizeToken.value) {
|
||||
ComPtr<ICoreWindow> coreWindow;
|
||||
HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = coreWindow->remove_SizeChanged(mSizeToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
if (mDpiToken.value) {
|
||||
ComPtr<IDisplayInformation> displayInformation;
|
||||
HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = displayInformation->remove_DpiChanged(mDpiToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
if (mOrientationToken.value) {
|
||||
ComPtr<IDisplayInformation> displayInformation;
|
||||
HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = displayInformation->remove_OrientationChanged(mOrientationToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
unsubclassWindow();
|
||||
release();
|
||||
}
|
||||
|
||||
bool Surface::initialize()
|
||||
Error Surface::initialize()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mFixedSize) {
|
||||
HRESULT hr;
|
||||
ComPtr<IDisplayInformation> displayInformation;
|
||||
hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
onDpiChanged(displayInformation.Get(), 0);
|
||||
hr = displayInformation->add_DpiChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onDpiChanged).Get(),
|
||||
&mDpiToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
onOrientationChanged(displayInformation.Get(), 0);
|
||||
hr = displayInformation->add_OrientationChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onOrientationChanged).Get(),
|
||||
&mOrientationToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
# endif
|
||||
|
||||
ComPtr<ICoreWindow> coreWindow;
|
||||
hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
Rect rect;
|
||||
hr = coreWindow->get_Bounds(&rect);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
mWidth = rect.Width * mScaleFactor;
|
||||
mHeight = rect.Height * mScaleFactor;
|
||||
hr = coreWindow->add_SizeChanged(Callback<ITypedEventHandler<CoreWindow *, WindowSizeChangedEventArgs *>>(this, &Surface::onSizeChanged).Get(),
|
||||
&mSizeToken);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
if (mNativeWindow.getNativeWindow())
|
||||
{
|
||||
if (!mNativeWindow.initialize())
|
||||
{
|
||||
return Error(EGL_BAD_SURFACE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!resetSwapChain())
|
||||
return false;
|
||||
Error error = resetSwapChain();
|
||||
if (error.isError())
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
void Surface::release()
|
||||
@ -181,85 +112,80 @@ void Surface::release()
|
||||
mTexture->releaseTexImage();
|
||||
mTexture = NULL;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (mWindow)
|
||||
mWindow->Release();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Surface::resetSwapChain()
|
||||
Error Surface::resetSwapChain()
|
||||
{
|
||||
ASSERT(!mSwapChain);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mFixedSize)
|
||||
{
|
||||
RECT windowRect;
|
||||
if (!GetClientRect(getWindowHandle(), &windowRect))
|
||||
if (!mNativeWindow.getClientRect(&windowRect))
|
||||
{
|
||||
ASSERT(false);
|
||||
|
||||
ERR("Could not retrieve the window dimensions");
|
||||
return error(EGL_BAD_SURFACE, false);
|
||||
return Error(EGL_BAD_SURFACE, "Could not retrieve the window dimensions");
|
||||
}
|
||||
|
||||
width = windowRect.right - windowRect.left;
|
||||
height = windowRect.bottom - windowRect.top;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// non-window surface - size is determined at creation
|
||||
width = mWidth;
|
||||
height = mHeight;
|
||||
}
|
||||
|
||||
mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
|
||||
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle,
|
||||
mConfig->mRenderTargetFormat,
|
||||
mConfig->mDepthStencilFormat);
|
||||
if (!mSwapChain)
|
||||
{
|
||||
return error(EGL_BAD_ALLOC, false);
|
||||
return Error(EGL_BAD_ALLOC);
|
||||
}
|
||||
|
||||
if (!resetSwapChain(width, height))
|
||||
Error error = resetSwapChain(width, height);
|
||||
if (error.isError())
|
||||
{
|
||||
delete mSwapChain;
|
||||
mSwapChain = NULL;
|
||||
return false;
|
||||
SafeDelete(mSwapChain);
|
||||
return error;
|
||||
}
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
{
|
||||
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
|
||||
ASSERT(mSwapChain);
|
||||
|
||||
EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight));
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
backbufferWidth = std::max(1, backbufferWidth);
|
||||
backbufferHeight = std::max(1, backbufferHeight);
|
||||
#endif
|
||||
EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
|
||||
|
||||
if (status == EGL_CONTEXT_LOST)
|
||||
{
|
||||
mDisplay->notifyDeviceLost();
|
||||
return false;
|
||||
return Error(status);
|
||||
}
|
||||
else if (status != EGL_SUCCESS)
|
||||
{
|
||||
return error(status, false);
|
||||
return Error(status);
|
||||
}
|
||||
|
||||
mWidth = backbufferWidth;
|
||||
mHeight = backbufferHeight;
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
Error Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
{
|
||||
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
|
||||
ASSERT(mSwapChain);
|
||||
@ -269,69 +195,71 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
|
||||
if (status == EGL_CONTEXT_LOST)
|
||||
{
|
||||
mRenderer->notifyDeviceLost();
|
||||
return false;
|
||||
return Error(status);
|
||||
}
|
||||
else if (status != EGL_SUCCESS)
|
||||
{
|
||||
return error(status, false);
|
||||
return Error(status);
|
||||
}
|
||||
|
||||
mWidth = backbufferWidth;
|
||||
mHeight = backbufferHeight;
|
||||
mSwapIntervalDirty = false;
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
{
|
||||
if (!mSwapChain)
|
||||
{
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
if (x + width > mWidth)
|
||||
if (x + width > abs(mWidth))
|
||||
{
|
||||
width = mWidth - x;
|
||||
width = abs(mWidth) - x;
|
||||
}
|
||||
|
||||
if (y + height > mHeight)
|
||||
if (y + height > abs(mHeight))
|
||||
{
|
||||
height = mHeight - y;
|
||||
height = abs(mHeight) - y;
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags);
|
||||
ASSERT(width > 0);
|
||||
ASSERT(height > 0);
|
||||
|
||||
EGLint status = mSwapChain->swapRect(x, y, width, height);
|
||||
|
||||
if (status == EGL_CONTEXT_LOST)
|
||||
{
|
||||
mRenderer->notifyDeviceLost();
|
||||
return false;
|
||||
return Error(status);
|
||||
}
|
||||
else if (status != EGL_SUCCESS)
|
||||
{
|
||||
return error(status, false);
|
||||
return Error(status);
|
||||
}
|
||||
|
||||
checkForOutOfDateSwapChain();
|
||||
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
EGLNativeWindowType Surface::getWindowHandle()
|
||||
{
|
||||
return mWindow;
|
||||
return mNativeWindow.getNativeWindow();
|
||||
}
|
||||
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
|
||||
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
|
||||
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (message == WM_SIZE)
|
||||
@ -349,45 +277,50 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
|
||||
|
||||
void Surface::subclassWindow()
|
||||
{
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mWindow)
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
HWND window = mNativeWindow.getNativeWindow();
|
||||
if (!window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD processId;
|
||||
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
|
||||
DWORD threadId = GetWindowThreadProcessId(window, &processId);
|
||||
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetLastError(0);
|
||||
LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
|
||||
LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
|
||||
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
|
||||
{
|
||||
mWindowSubclassed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
|
||||
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
|
||||
SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
|
||||
SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
|
||||
mWindowSubclassed = true;
|
||||
#else
|
||||
mWindowSubclassed = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Surface::unsubclassWindow()
|
||||
{
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if(!mWindowSubclassed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
HWND window = mNativeWindow.getNativeWindow();
|
||||
if (!window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// un-subclass
|
||||
LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc));
|
||||
LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, kParentWndProc));
|
||||
|
||||
// Check the windowproc is still SurfaceWindowProc.
|
||||
// If this assert fails, then it is likely the application has subclassed the
|
||||
@ -396,29 +329,28 @@ void Surface::unsubclassWindow()
|
||||
// EGL context, or to unsubclass before destroying the EGL context.
|
||||
if(parentWndFunc)
|
||||
{
|
||||
LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
|
||||
LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
|
||||
UNUSED_ASSERTION_VARIABLE(prevWndFunc);
|
||||
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
|
||||
}
|
||||
|
||||
RemoveProp(mWindow, kSurfaceProperty);
|
||||
RemoveProp(mWindow, kParentWndProc);
|
||||
mWindowSubclassed = false;
|
||||
RemoveProp(window, kSurfaceProperty);
|
||||
RemoveProp(window, kParentWndProc);
|
||||
#endif
|
||||
mWindowSubclassed = false;
|
||||
}
|
||||
|
||||
bool Surface::checkForOutOfDateSwapChain()
|
||||
{
|
||||
RECT client;
|
||||
int clientWidth = getWidth();
|
||||
int clientHeight = getHeight();
|
||||
bool sizeDirty = false;
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
if (!mFixedSize && !IsIconic(getWindowHandle()))
|
||||
if (!mFixedSize && !mNativeWindow.isIconic())
|
||||
{
|
||||
RECT client;
|
||||
// The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized
|
||||
// because that's not a useful size to render to.
|
||||
if (!GetClientRect(getWindowHandle(), &client))
|
||||
if (!mNativeWindow.getClientRect(&client))
|
||||
{
|
||||
ASSERT(false);
|
||||
return false;
|
||||
@ -429,7 +361,13 @@ bool Surface::checkForOutOfDateSwapChain()
|
||||
clientHeight = client.bottom - client.top;
|
||||
sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight))
|
||||
{
|
||||
clientWidth = mFixedWidth;
|
||||
clientHeight = mFixedHeight;
|
||||
sizeDirty = true;
|
||||
}
|
||||
|
||||
bool wasDirty = (mSwapIntervalDirty || sizeDirty);
|
||||
|
||||
@ -455,17 +393,17 @@ bool Surface::checkForOutOfDateSwapChain()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Surface::swap()
|
||||
Error Surface::swap()
|
||||
{
|
||||
return swapRect(0, 0, mWidth, mHeight);
|
||||
return swapRect(0, 0, abs(mWidth), abs(mHeight));
|
||||
}
|
||||
|
||||
bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
{
|
||||
if (!mPostSubBufferSupported)
|
||||
{
|
||||
// Spec is not clear about how this should be handled.
|
||||
return true;
|
||||
return Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
return swapRect(x, y, width, height);
|
||||
@ -550,77 +488,18 @@ EGLint Surface::isFixedSize() const
|
||||
return mFixedSize;
|
||||
}
|
||||
|
||||
void Surface::setFixedWidth(EGLint width)
|
||||
{
|
||||
mFixedWidth = width;
|
||||
}
|
||||
|
||||
void Surface::setFixedHeight(EGLint height)
|
||||
{
|
||||
mFixedHeight = height;
|
||||
}
|
||||
|
||||
EGLenum Surface::getFormat() const
|
||||
{
|
||||
return mConfig->mRenderTargetFormat;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
|
||||
HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
|
||||
{
|
||||
HRESULT hr;
|
||||
Size size;
|
||||
hr = args->get_Size(&size);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5),
|
||||
std::floor(size.Height * mScaleFactor + 0.5));
|
||||
|
||||
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
|
||||
{
|
||||
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *)
|
||||
{
|
||||
HRESULT hr;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
ComPtr<IDisplayInformation2> displayInformation2;
|
||||
hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf());
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
# else
|
||||
ResolutionScale resolutionScale;
|
||||
hr = displayInformation->get_ResolutionScale(&resolutionScale);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
|
||||
mScaleFactor = double(resolutionScale) / 100.0;
|
||||
# endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *)
|
||||
{
|
||||
HRESULT hr;
|
||||
DisplayOrientations orientation;
|
||||
hr = displayInformation->get_CurrentOrientation(&orientation);
|
||||
ASSERT(SUCCEEDED(hr));
|
||||
switch (orientation) {
|
||||
default:
|
||||
case DisplayOrientations_Portrait:
|
||||
mSwapFlags = rx::SWAP_NORMAL;
|
||||
break;
|
||||
case DisplayOrientations_Landscape:
|
||||
mSwapFlags = rx::SWAP_ROTATE_90;
|
||||
break;
|
||||
case DisplayOrientations_LandscapeFlipped:
|
||||
mSwapFlags = rx::SWAP_ROTATE_270;
|
||||
break;
|
||||
case DisplayOrientations_PortraitFlipped:
|
||||
mSwapFlags = rx::SWAP_ROTATE_180;
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
60
src/3rdparty/angle/src/libEGL/Surface.h
vendored
60
src/3rdparty/angle/src/libEGL/Surface.h
vendored
@ -11,23 +11,12 @@
|
||||
#ifndef LIBEGL_SURFACE_H_
|
||||
#define LIBEGL_SURFACE_H_
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
#include <EventToken.h>
|
||||
namespace ABI { namespace Windows {
|
||||
namespace UI { namespace Core {
|
||||
struct ICoreWindow;
|
||||
struct IWindowSizeChangedEventArgs;
|
||||
} }
|
||||
namespace Graphics { namespace Display {
|
||||
struct IDisplayInformation;
|
||||
} }
|
||||
} }
|
||||
struct IInspectable;
|
||||
#endif
|
||||
#include "common/NativeWindow.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -35,8 +24,8 @@ class Texture2D;
|
||||
}
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class SwapChain;
|
||||
class RendererD3D; //TODO(jmadill): remove this
|
||||
}
|
||||
|
||||
namespace egl
|
||||
@ -52,13 +41,13 @@ class Surface
|
||||
|
||||
virtual ~Surface();
|
||||
|
||||
bool initialize();
|
||||
Error initialize();
|
||||
void release();
|
||||
bool resetSwapChain();
|
||||
Error resetSwapChain();
|
||||
|
||||
EGLNativeWindowType getWindowHandle();
|
||||
bool swap();
|
||||
bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
Error swap();
|
||||
Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
|
||||
virtual EGLint isPostSubBufferSupported() const;
|
||||
|
||||
@ -81,35 +70,31 @@ class Surface
|
||||
virtual gl::Texture2D *getBoundTexture() const;
|
||||
|
||||
EGLint isFixedSize() const;
|
||||
void setFixedWidth(EGLint width);
|
||||
void setFixedHeight(EGLint height);
|
||||
|
||||
private:
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Surface);
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
|
||||
HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
Display *const mDisplay;
|
||||
rx::Renderer *mRenderer;
|
||||
rx::RendererD3D *mRenderer;
|
||||
|
||||
HANDLE mShareHandle;
|
||||
rx::SwapChain *mSwapChain;
|
||||
|
||||
void subclassWindow();
|
||||
void unsubclassWindow();
|
||||
bool resizeSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
bool resetSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
Error resetSwapChain(int backbufferWidth, int backbufferHeight);
|
||||
Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
|
||||
|
||||
const EGLNativeWindowType mWindow; // Window that the surface is created for.
|
||||
rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
|
||||
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
|
||||
const egl::Config *mConfig; // EGL config surface was created with
|
||||
EGLint mHeight; // Height of surface
|
||||
EGLint mWidth; // Width of surface
|
||||
EGLint mFixedHeight; // Pending height of the surface
|
||||
EGLint mFixedWidth; // Pending width of the surface
|
||||
// EGLint horizontalResolution; // Horizontal dot pitch
|
||||
// EGLint verticalResolution; // Vertical dot pitch
|
||||
// EGLBoolean largestPBuffer; // If true, create largest pbuffer possible
|
||||
@ -126,18 +111,9 @@ private:
|
||||
EGLint mSwapInterval;
|
||||
EGLint mPostSubBufferSupported;
|
||||
EGLint mFixedSize;
|
||||
EGLint mSwapFlags;
|
||||
|
||||
bool mSwapIntervalDirty;
|
||||
gl::Texture2D *mTexture;
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
double mScaleFactor;
|
||||
EventRegistrationToken mSizeToken;
|
||||
EventRegistrationToken mDpiToken;
|
||||
# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
|
||||
EventRegistrationToken mOrientationToken;
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
|
469
src/3rdparty/angle/src/libEGL/libEGL.cpp
vendored
469
src/3rdparty/angle/src/libEGL/libEGL.cpp
vendored
@ -13,7 +13,6 @@
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/version.h"
|
||||
#include "common/platform.h"
|
||||
#include "libGLESv2/Context.h"
|
||||
#include "libGLESv2/Texture.h"
|
||||
#include "libGLESv2/main.h"
|
||||
@ -26,16 +25,20 @@
|
||||
#include "libEGL/Display.h"
|
||||
#include "libEGL/Surface.h"
|
||||
|
||||
#include "common/NativeWindow.h"
|
||||
|
||||
bool validateDisplay(egl::Display *display)
|
||||
{
|
||||
if (display == EGL_NO_DISPLAY)
|
||||
{
|
||||
return egl::error(EGL_BAD_DISPLAY, false);
|
||||
recordError(egl::Error(EGL_BAD_DISPLAY));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!display->isInitialized())
|
||||
{
|
||||
return egl::error(EGL_NOT_INITIALIZED, false);
|
||||
recordError(egl::Error(EGL_NOT_INITIALIZED));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -50,7 +53,8 @@ bool validateConfig(egl::Display *display, EGLConfig config)
|
||||
|
||||
if (!display->isValidConfig(config))
|
||||
{
|
||||
return egl::error(EGL_BAD_CONFIG, false);
|
||||
recordError(egl::Error(EGL_BAD_CONFIG));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -65,7 +69,8 @@ bool validateContext(egl::Display *display, gl::Context *context)
|
||||
|
||||
if (!display->isValidContext(context))
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, false);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -80,7 +85,8 @@ bool validateSurface(egl::Display *display, egl::Surface *surface)
|
||||
|
||||
if (!display->isValidSurface(surface))
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, false);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -93,12 +99,7 @@ EGLint __stdcall eglGetError(void)
|
||||
EVENT("()");
|
||||
|
||||
EGLint error = egl::getCurrentError();
|
||||
|
||||
if (error != EGL_SUCCESS)
|
||||
{
|
||||
egl::setCurrentError(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
|
||||
{
|
||||
EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
|
||||
|
||||
return egl::Display::getDisplay(display_id, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
|
||||
return egl::Display::getDisplay(display_id, egl::AttributeMap());
|
||||
}
|
||||
|
||||
EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
|
||||
@ -120,19 +121,26 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
|
||||
break;
|
||||
|
||||
default:
|
||||
return egl::error(EGL_BAD_CONFIG, EGL_NO_DISPLAY);
|
||||
recordError(egl::Error(EGL_BAD_CONFIG));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
// Validate the display device context
|
||||
if (WindowFromDC(displayId) == NULL)
|
||||
{
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
|
||||
EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
|
||||
bool majorVersionSpecified = false;
|
||||
bool minorVersionSpecified = false;
|
||||
bool requestedWARP = false;
|
||||
|
||||
if (attrib_list)
|
||||
{
|
||||
for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
|
||||
@ -140,7 +148,69 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
|
||||
switch (curAttrib[0])
|
||||
{
|
||||
case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
|
||||
requestedDisplayType = curAttrib[1];
|
||||
switch (curAttrib[1])
|
||||
{
|
||||
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
|
||||
if (!egl::Display::supportsPlatformD3D())
|
||||
{
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
|
||||
if (!egl::Display::supportsPlatformOpenGL())
|
||||
{
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
platformType = curAttrib[1];
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
|
||||
if (curAttrib[1] != EGL_DONT_CARE)
|
||||
{
|
||||
majorVersionSpecified = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
|
||||
if (curAttrib[1] != EGL_DONT_CARE)
|
||||
{
|
||||
minorVersionSpecified = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_USE_WARP_ANGLE:
|
||||
if (!egl::Display::supportsPlatformD3D())
|
||||
{
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
switch (curAttrib[1])
|
||||
{
|
||||
case EGL_FALSE:
|
||||
case EGL_TRUE:
|
||||
break;
|
||||
|
||||
default:
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
requestedWARP = (curAttrib[1] == EGL_TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -149,33 +219,20 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
|
||||
}
|
||||
}
|
||||
|
||||
switch (requestedDisplayType)
|
||||
if (!majorVersionSpecified && minorVersionSpecified)
|
||||
{
|
||||
case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE:
|
||||
if (!egl::Display::supportsPlatformD3D())
|
||||
{
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
}
|
||||
break;
|
||||
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
|
||||
case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
|
||||
if (!egl::Display::supportsPlatformOpenGL())
|
||||
{
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return egl::success(EGL_NO_DISPLAY);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
return egl::Display::getDisplay(displayId, requestedDisplayType);
|
||||
if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE && requestedWARP)
|
||||
{
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return egl::Display::getDisplay(displayId, egl::AttributeMap(attrib_list));
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
||||
@ -185,20 +242,24 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
||||
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_DISPLAY));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
|
||||
if (!display->initialize())
|
||||
egl::Error error = display->initialize();
|
||||
if (error.isError())
|
||||
{
|
||||
return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
|
||||
recordError(error);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (major) *major = 1;
|
||||
if (minor) *minor = 4;
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
|
||||
@ -207,14 +268,16 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
|
||||
|
||||
if (dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_DISPLAY));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
|
||||
display->terminate();
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
|
||||
@ -227,19 +290,28 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *result;
|
||||
switch (name)
|
||||
{
|
||||
case EGL_CLIENT_APIS:
|
||||
return egl::success("OpenGL_ES");
|
||||
result = "OpenGL_ES";
|
||||
break;
|
||||
case EGL_EXTENSIONS:
|
||||
return egl::success(egl::Display::getExtensionString(display));
|
||||
result = egl::Display::getExtensionString(display);
|
||||
break;
|
||||
case EGL_VENDOR:
|
||||
return egl::success(display->getVendorString());
|
||||
result = display->getVendorString();
|
||||
break;
|
||||
case EGL_VERSION:
|
||||
return egl::success("1.4 (ANGLE " ANGLE_VERSION_STRING ")");
|
||||
result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return result;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
|
||||
@ -257,17 +329,20 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co
|
||||
|
||||
if (!num_config)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
const EGLint attribList[] = {EGL_NONE};
|
||||
|
||||
if (!display->getConfigs(configs, attribList, config_size, num_config))
|
||||
{
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
|
||||
@ -285,7 +360,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
|
||||
|
||||
if (!num_config)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
const EGLint attribList[] = {EGL_NONE};
|
||||
@ -297,7 +373,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
|
||||
|
||||
display->getConfigs(configs, attrib_list, config_size, num_config);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
|
||||
@ -314,10 +391,12 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
|
||||
|
||||
if (!display->getConfigAttrib(config, attribute, value))
|
||||
{
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
|
||||
@ -332,16 +411,21 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
HWND window = (HWND)win;
|
||||
|
||||
if (!IsWindow(window))
|
||||
if (!rx::IsValidEGLNativeWindowType(win))
|
||||
{
|
||||
return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_BAD_NATIVE_WINDOW));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return display->createWindowSurface(win, config, attrib_list);
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
egl::Error error = display->createWindowSurface(win, config, attrib_list, &surface);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
|
||||
@ -356,7 +440,15 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return display->createOffscreenSurface(config, NULL, attrib_list);
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
egl::Error error = display->createOffscreenSurface(config, NULL, attrib_list, &surface);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
|
||||
@ -373,7 +465,8 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
|
||||
@ -390,12 +483,14 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
display->destroySurface((egl::Surface*)surface);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
|
||||
@ -413,7 +508,8 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
switch (attribute)
|
||||
@ -473,10 +569,12 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
*value = eglSurface->isFixedSize();
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
|
||||
@ -498,7 +596,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
rx::SwapChain *swapchain = eglSurface->getSwapChain();
|
||||
@ -522,7 +621,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
|
||||
|
||||
if (renderer->getMajorShaderModel() < 4)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
*value = static_cast<rx::Renderer11*>(renderer)->getDevice();
|
||||
@ -530,10 +630,12 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglBindAPI(EGLenum api)
|
||||
@ -544,16 +646,19 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api)
|
||||
{
|
||||
case EGL_OPENGL_API:
|
||||
case EGL_OPENVG_API:
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE; // Not supported by this implementation
|
||||
case EGL_OPENGL_ES_API:
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::setCurrentAPI(api);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLenum __stdcall eglQueryAPI(void)
|
||||
@ -562,7 +667,8 @@ EGLenum __stdcall eglQueryAPI(void)
|
||||
|
||||
EGLenum API = egl::getCurrentAPI();
|
||||
|
||||
return egl::success(API);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return API;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglWaitClient(void)
|
||||
@ -571,7 +677,8 @@ EGLBoolean __stdcall eglWaitClient(void)
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglReleaseThread(void)
|
||||
@ -580,7 +687,8 @@ EGLBoolean __stdcall eglReleaseThread(void)
|
||||
|
||||
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
|
||||
@ -598,10 +706,19 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
|
||||
|
||||
if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
egl::Error error = display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list, &surface);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
|
||||
@ -617,9 +734,30 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
switch (attribute)
|
||||
{
|
||||
case EGL_WIDTH:
|
||||
if (!eglSurface->isFixedSize() || !value) {
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
eglSurface->setFixedWidth(value);
|
||||
return EGL_TRUE;
|
||||
case EGL_HEIGHT:
|
||||
if (!eglSurface->isFixedSize() || !value) {
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
eglSurface->setFixedHeight(value);
|
||||
return EGL_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
||||
@ -636,30 +774,36 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
|
||||
|
||||
if (buffer != EGL_BACK_BUFFER)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->getBoundTexture())
|
||||
{
|
||||
return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_ACCESS));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (!glBindTexImage(eglSurface))
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
||||
@ -676,17 +820,20 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
|
||||
if (buffer != EGL_BACK_BUFFER)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
gl::Texture2D *texture = eglSurface->getBoundTexture();
|
||||
@ -696,7 +843,8 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
texture->releaseTexImage();
|
||||
}
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
|
||||
@ -714,12 +862,14 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
|
||||
|
||||
if (draw_surface == NULL)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
draw_surface->setSwapInterval(interval);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
|
||||
@ -744,27 +894,38 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
|
||||
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
|
||||
if (attribute[1] == EGL_TRUE)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
|
||||
recordError(egl::Error(EGL_BAD_CONFIG)); // Unimplemented
|
||||
return EGL_NO_CONTEXT;
|
||||
// robust_access = true;
|
||||
}
|
||||
else if (attribute[1] != EGL_FALSE)
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
|
||||
{
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
break;
|
||||
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
|
||||
if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
|
||||
{
|
||||
reset_notification = true;
|
||||
}
|
||||
else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
|
||||
{
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_ATTRIBUTE));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (client_version != 2 && client_version != 3)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_CONFIG));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
@ -775,18 +936,21 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
|
||||
|
||||
if (sharedGLContext->isResetNotificationEnabled() != reset_notification)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (sharedGLContext->getClientVersion() != client_version)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
// Can not share contexts between displays
|
||||
if (sharedGLContext->getRenderer() != display->getRenderer())
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,7 +959,16 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
return display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
egl::Error error = display->createContext(config, client_version, static_cast<gl::Context*>(share_context),
|
||||
reset_notification, robust_access, &context);
|
||||
if (error.isError())
|
||||
{
|
||||
recordError(error);
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
|
||||
@ -812,12 +985,14 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
|
||||
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
{
|
||||
return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_CONTEXT));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
display->destroyContext(context);
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
|
||||
@ -832,7 +1007,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
|
||||
bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
|
||||
if (noContext != noSurface)
|
||||
{
|
||||
return egl::error(EGL_BAD_MATCH, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_MATCH));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
|
||||
@ -850,7 +1026,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
|
||||
|
||||
if (renderer->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -871,7 +1048,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
|
||||
|
||||
glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
|
||||
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLContext __stdcall eglGetCurrentContext(void)
|
||||
@ -880,7 +1058,8 @@ EGLContext __stdcall eglGetCurrentContext(void)
|
||||
|
||||
EGLContext context = glGetCurrentContext();
|
||||
|
||||
return egl::success(context);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return context;
|
||||
}
|
||||
|
||||
EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
|
||||
@ -889,17 +1068,18 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
|
||||
|
||||
if (readdraw == EGL_READ)
|
||||
{
|
||||
EGLSurface read = egl::getCurrentReadSurface();
|
||||
return egl::success(read);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return egl::getCurrentReadSurface();
|
||||
}
|
||||
else if (readdraw == EGL_DRAW)
|
||||
{
|
||||
EGLSurface draw = egl::getCurrentDrawSurface();
|
||||
return egl::success(draw);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return egl::getCurrentDrawSurface();
|
||||
}
|
||||
else
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -909,7 +1089,8 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void)
|
||||
|
||||
EGLDisplay dpy = egl::getCurrentDisplay();
|
||||
|
||||
return egl::success(dpy);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return dpy;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
|
||||
@ -927,7 +1108,8 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglWaitGL(void)
|
||||
@ -936,7 +1118,8 @@ EGLBoolean __stdcall eglWaitGL(void)
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglWaitNative(EGLint engine)
|
||||
@ -945,7 +1128,8 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine)
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
|
||||
@ -962,20 +1146,25 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
|
||||
|
||||
if (display->getRenderer()->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->swap())
|
||||
egl::Error error = eglSurface->swap();
|
||||
if (error.isError())
|
||||
{
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(error);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return EGL_FALSE;
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
|
||||
@ -992,12 +1181,14 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
|
||||
|
||||
if (display->getRenderer()->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
UNIMPLEMENTED(); // FIXME
|
||||
|
||||
return egl::success(0);
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
|
||||
@ -1006,7 +1197,8 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
|
||||
if (x < 0 || y < 0 || width < 0 || height < 0)
|
||||
{
|
||||
return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_PARAMETER));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
egl::Display *display = static_cast<egl::Display*>(dpy);
|
||||
@ -1019,20 +1211,25 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
|
||||
|
||||
if (display->getRenderer()->isDeviceLost())
|
||||
{
|
||||
return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_CONTEXT_LOST));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (surface == EGL_NO_SURFACE)
|
||||
{
|
||||
return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
|
||||
recordError(egl::Error(EGL_BAD_SURFACE));
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
if (eglSurface->postSubBuffer(x, y, width, height))
|
||||
egl::Error error = eglSurface->postSubBuffer(x, y, width, height);
|
||||
if (error.isError())
|
||||
{
|
||||
return egl::success(EGL_TRUE);
|
||||
recordError(error);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
return EGL_FALSE;
|
||||
recordError(egl::Error(EGL_SUCCESS));
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
|
||||
|
40
src/3rdparty/angle/src/libEGL/main.cpp
vendored
40
src/3rdparty/angle/src/libEGL/main.cpp
vendored
@ -11,9 +11,6 @@
|
||||
#include "common/debug.h"
|
||||
#include "common/tls.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
__declspec(thread)
|
||||
#endif
|
||||
static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
|
||||
|
||||
namespace egl
|
||||
@ -21,12 +18,6 @@ namespace egl
|
||||
|
||||
Current *AllocateCurrent()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
currentTLS = CreateTLSIndex();
|
||||
}
|
||||
#endif
|
||||
ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
@ -51,12 +42,6 @@ Current *AllocateCurrent()
|
||||
|
||||
void DeallocateCurrent()
|
||||
{
|
||||
#if defined(ANGLE_PLATFORM_WINRT)
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
|
||||
SafeDelete(current);
|
||||
SetTLSValue(currentTLS, NULL);
|
||||
@ -72,7 +57,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_TRACE)
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
|
||||
|
||||
if (debug)
|
||||
@ -87,15 +72,15 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain
|
||||
return DisableThreadLibraryCalls(instance);
|
||||
#endif
|
||||
|
||||
currentTLS = CreateTLSIndex();
|
||||
if (currentTLS == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
gl::InitializeDebugAnnotations();
|
||||
#endif
|
||||
}
|
||||
// Fall through to initialize index
|
||||
case DLL_THREAD_ATTACH:
|
||||
@ -105,15 +90,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
{
|
||||
#if !defined(ANGLE_PLATFORM_WINRT)
|
||||
egl::DeallocateCurrent();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
egl::DeallocateCurrent();
|
||||
DestroyTLSIndex(currentTLS);
|
||||
|
||||
#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
|
||||
gl::UninitializeDebugAnnotations();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -143,11 +130,11 @@ Current *GetCurrentData()
|
||||
#endif
|
||||
}
|
||||
|
||||
void setCurrentError(EGLint error)
|
||||
void recordError(const Error &error)
|
||||
{
|
||||
Current *current = GetCurrentData();
|
||||
|
||||
current->error = error;
|
||||
current->error = error.getCode();
|
||||
}
|
||||
|
||||
EGLint getCurrentError()
|
||||
@ -213,9 +200,4 @@ EGLSurface getCurrentReadSurface()
|
||||
return current->readSurface;
|
||||
}
|
||||
|
||||
void error(EGLint errorCode)
|
||||
{
|
||||
egl::setCurrentError(errorCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
22
src/3rdparty/angle/src/libEGL/main.h
vendored
22
src/3rdparty/angle/src/libEGL/main.h
vendored
@ -9,6 +9,8 @@
|
||||
#ifndef LIBEGL_MAIN_H_
|
||||
#define LIBEGL_MAIN_H_
|
||||
|
||||
#include "libEGL/Error.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
@ -23,7 +25,7 @@ struct Current
|
||||
EGLSurface readSurface;
|
||||
};
|
||||
|
||||
void setCurrentError(EGLint error);
|
||||
void recordError(const Error &error);
|
||||
EGLint getCurrentError();
|
||||
|
||||
void setCurrentAPI(EGLenum API);
|
||||
@ -38,24 +40,6 @@ EGLSurface getCurrentDrawSurface();
|
||||
void setCurrentReadSurface(EGLSurface surface);
|
||||
EGLSurface getCurrentReadSurface();
|
||||
|
||||
void error(EGLint errorCode);
|
||||
|
||||
template<class T>
|
||||
const T &error(EGLint errorCode, const T &returnValue)
|
||||
{
|
||||
error(errorCode);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T &success(const T &returnValue)
|
||||
{
|
||||
egl::setCurrentError(EGL_SUCCESS);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // LIBEGL_MAIN_H_
|
||||
|
12
src/3rdparty/angle/src/libGLESv2/BinaryStream.h
vendored
12
src/3rdparty/angle/src/libGLESv2/BinaryStream.h
vendored
@ -15,6 +15,7 @@
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
@ -26,7 +27,7 @@ class BinaryInputStream
|
||||
{
|
||||
mError = false;
|
||||
mOffset = 0;
|
||||
mData = static_cast<const char*>(data);
|
||||
mData = static_cast<const uint8_t*>(data);
|
||||
mLength = length;
|
||||
}
|
||||
|
||||
@ -85,7 +86,7 @@ class BinaryInputStream
|
||||
return;
|
||||
}
|
||||
|
||||
v->assign(mData + mOffset, length);
|
||||
v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
|
||||
mOffset += length;
|
||||
}
|
||||
|
||||
@ -115,11 +116,16 @@ class BinaryInputStream
|
||||
return mOffset == mLength;
|
||||
}
|
||||
|
||||
const uint8_t *data()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
|
||||
bool mError;
|
||||
size_t mOffset;
|
||||
const char *mData;
|
||||
const uint8_t *mData;
|
||||
size_t mLength;
|
||||
|
||||
template <typename T>
|
||||
|
1
src/3rdparty/angle/src/libGLESv2/Buffer.h
vendored
1
src/3rdparty/angle/src/libGLESv2/Buffer.h
vendored
@ -19,7 +19,6 @@
|
||||
|
||||
namespace rx
|
||||
{
|
||||
class Renderer;
|
||||
class BufferImpl;
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user