зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1440849 - Nuke old ANGLE.
MozReview-Commit-ID: G0uEx2efEKe
This commit is contained in:
Родитель
d7f00b4cb7
Коммит
b7a6fddcc3
|
@ -1,51 +0,0 @@
|
|||
# This is the official list of The ANGLE Project Authors
|
||||
# for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS files.
|
||||
# See the latter for an explanation.
|
||||
|
||||
# Names should be added to this file as
|
||||
# Name or Organization
|
||||
# Email addresses for individuals are tracked elsewhere to avoid spam.
|
||||
|
||||
Google Inc.
|
||||
TransGaming Inc.
|
||||
3DLabs Inc. Ltd.
|
||||
|
||||
Adobe Systems Inc.
|
||||
Autodesk, Inc.
|
||||
BlackBerry Limited
|
||||
Cable Television Laboratories, Inc.
|
||||
Cloud Party, Inc.
|
||||
Imagination Technologies Ltd.
|
||||
Intel Corporation
|
||||
Mozilla Corporation
|
||||
Turbulenz
|
||||
Klarälvdalens Datakonsult AB
|
||||
Microsoft Corporation
|
||||
Microsoft Open Technologies, Inc.
|
||||
NVIDIA Corporation
|
||||
Opera Software ASA
|
||||
The Qt Company Ltd.
|
||||
Advanced Micro Devices, Inc.
|
||||
|
||||
Jacek Caban
|
||||
Mark Callow
|
||||
Ginn Chen
|
||||
Tibor den Ouden
|
||||
Régis Fénéon
|
||||
James Hauxwell
|
||||
Sam Hocevar
|
||||
Pierre Leveille
|
||||
Jonathan Liu
|
||||
Boying Lu
|
||||
Aitor Moreno
|
||||
Yuri O'Donnell
|
||||
Josh Soref
|
||||
Maks Naumov
|
||||
Jinyoung Hur
|
||||
Sebastian Bergstein
|
||||
James Ross-Gowan
|
||||
Nickolay Artamonov
|
||||
Ihsan Akmal
|
||||
Andrei Volykhin
|
||||
Jérôme Duval
|
|
@ -1,765 +0,0 @@
|
|||
# Copyright 2014-2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# import the use_x11 variable
|
||||
import("//build/config/dcheck_always_on.gni")
|
||||
import("//build/config/linux/pkg_config.gni")
|
||||
import("//build/config/ui.gni")
|
||||
import("//testing/libfuzzer/fuzzer_test.gni")
|
||||
import("//third_party/angle/gni/angle.gni")
|
||||
import("//ui/ozone/ozone.gni")
|
||||
|
||||
declare_args() {
|
||||
# Use the PCI lib to collect GPU information on Linux.
|
||||
use_libpci = is_linux && (!is_chromecast || is_cast_desktop_build) &&
|
||||
(use_x11 || use_ozone)
|
||||
}
|
||||
|
||||
if (ozone_platform_gbm) {
|
||||
pkg_config("libdrm") {
|
||||
packages = [ "libdrm" ]
|
||||
}
|
||||
}
|
||||
|
||||
angle_git_is_present = exec_script("src/commit_id.py",
|
||||
[
|
||||
"check",
|
||||
rebase_path(".", root_build_dir),
|
||||
],
|
||||
"value")
|
||||
|
||||
angle_use_commit_id = angle_git_is_present == 1
|
||||
|
||||
gles_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/libGLESv2.gypi") ],
|
||||
"scope",
|
||||
[ "src/libGLESv2.gypi" ])
|
||||
|
||||
compiler_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("src/compiler.gypi") ],
|
||||
"scope",
|
||||
[ "src/compiler.gypi" ])
|
||||
|
||||
# This config is exported to dependent targets (and also applied to internal
|
||||
# ones).
|
||||
config("external_config") {
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
# This config is applied to internal Angle targets (not pushed to dependents).
|
||||
config("internal_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
"src",
|
||||
]
|
||||
|
||||
# Prevent the GL headers from redeclaring ANGLE entry points.
|
||||
defines = [
|
||||
"GL_GLEXT_PROTOTYPES",
|
||||
"EGL_EGLEXT_PROTOTYPES",
|
||||
]
|
||||
|
||||
if (target_cpu == "x86") {
|
||||
defines += [ "ANGLE_X86_CPU" ]
|
||||
}
|
||||
if (target_cpu == "x64") {
|
||||
defines += [ "ANGLE_X64_CPU" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("extra_warnings") {
|
||||
# Enable more default warnings on Windows.
|
||||
if (is_win) {
|
||||
cflags = [
|
||||
"/we4244", # Conversion: possible loss of data.
|
||||
"/we4456", # Variable shadowing.
|
||||
"/we4458", # declaration hides class member.
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
copy("copy_compiler_dll") {
|
||||
sources = [
|
||||
"$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll",
|
||||
]
|
||||
outputs = [
|
||||
"$root_out_dir/d3dcompiler_47.dll",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
angle_undefine_configs = [ "//build/config/compiler:default_include_dirs" ]
|
||||
|
||||
# Holds the shared includes so we only need to list them once.
|
||||
source_set("includes") {
|
||||
sources = [
|
||||
"include/EGL/egl.h",
|
||||
"include/EGL/eglext.h",
|
||||
"include/EGL/eglplatform.h",
|
||||
"include/GLES2/gl2.h",
|
||||
"include/GLES2/gl2ext.h",
|
||||
"include/GLES2/gl2platform.h",
|
||||
"include/GLES3/gl3.h",
|
||||
"include/GLES3/gl31.h",
|
||||
"include/GLES3/gl32.h",
|
||||
"include/GLES3/gl3platform.h",
|
||||
"include/GLSLANG/ShaderLang.h",
|
||||
"include/KHR/khrplatform.h",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("preprocessor") {
|
||||
sources = rebase_path(compiler_gypi.angle_preprocessor_sources, ".", "src")
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [ ":internal_config" ]
|
||||
|
||||
public_deps = [
|
||||
":angle_common",
|
||||
]
|
||||
}
|
||||
|
||||
config("translator_disable_pool_alloc") {
|
||||
defines = [ "ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC" ]
|
||||
}
|
||||
|
||||
config("debug_annotations_config") {
|
||||
if (is_debug) {
|
||||
defines = [ "ANGLE_ENABLE_DEBUG_ANNOTATIONS" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("angle_release_asserts_config") {
|
||||
if (dcheck_always_on) {
|
||||
defines = [ "ANGLE_ENABLE_RELEASE_ASSERTS" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("angle_common_config") {
|
||||
include_dirs = [ "src/common/third_party/base" ]
|
||||
}
|
||||
|
||||
static_library("angle_common") {
|
||||
sources = rebase_path(gles_gypi.libangle_common_sources, ".", "src")
|
||||
|
||||
if (is_linux || is_android) {
|
||||
sources += rebase_path(gles_gypi.libangle_common_linux_sources, ".", "src")
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
sources += rebase_path(gles_gypi.libangle_common_mac_sources, ".", "src")
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
sources += rebase_path(gles_gypi.libangle_common_win_sources, ".", "src")
|
||||
}
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [
|
||||
":angle_common_config",
|
||||
":debug_annotations_config",
|
||||
":extra_warnings",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
":commit_id",
|
||||
]
|
||||
public_configs = [ ":angle_common_config" ]
|
||||
all_dependent_configs = [ ":angle_release_asserts_config" ]
|
||||
}
|
||||
|
||||
config("angle_image_util_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
"src",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("angle_image_util") {
|
||||
sources = rebase_path(gles_gypi.libangle_image_util_sources, ".", "src")
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [
|
||||
":internal_config",
|
||||
":extra_warnings",
|
||||
]
|
||||
|
||||
public_configs = [ ":angle_image_util_config" ]
|
||||
|
||||
public_deps = [
|
||||
":angle_common",
|
||||
]
|
||||
}
|
||||
|
||||
config("angle_gpu_info_util_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
"src",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("angle_gpu_info_util") {
|
||||
configs -= angle_undefine_configs
|
||||
configs += [
|
||||
":internal_config",
|
||||
":extra_warnings",
|
||||
]
|
||||
|
||||
public_configs = [ ":angle_gpu_info_util_config" ]
|
||||
|
||||
public_deps = [
|
||||
":angle_common",
|
||||
]
|
||||
|
||||
sources = rebase_path(gles_gypi.libangle_gpu_info_util_sources, ".", "src")
|
||||
deps = []
|
||||
libs = []
|
||||
defines = []
|
||||
|
||||
if (is_win) {
|
||||
sources +=
|
||||
rebase_path(gles_gypi.libangle_gpu_info_util_win_sources, ".", "src")
|
||||
libs += [ "setupapi.lib" ]
|
||||
defines += [ "GPU_INFO_USE_SETUPAPI" ]
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
sources +=
|
||||
rebase_path(gles_gypi.libangle_gpu_info_util_linux_sources, ".", "src")
|
||||
|
||||
if (use_x11) {
|
||||
sources +=
|
||||
rebase_path(gles_gypi.libangle_gpu_info_util_x11_sources, ".", "src")
|
||||
deps += [ "src/third_party/libXNVCtrl:libXNVCtrl" ]
|
||||
defines += [ "GPU_INFO_USE_X11" ]
|
||||
libs += [
|
||||
"X11",
|
||||
"Xi",
|
||||
"Xext",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (use_libpci) {
|
||||
sources +=
|
||||
rebase_path(gles_gypi.libangle_gpu_info_util_libpci_sources, ".", "src")
|
||||
defines += [ "GPU_INFO_USE_LIBPCI" ]
|
||||
libs += [ "pci" ]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
sources +=
|
||||
rebase_path(gles_gypi.libangle_gpu_info_util_mac_sources, ".", "src")
|
||||
libs += [
|
||||
"IOKit.framework",
|
||||
"CoreFoundation.framework",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
static_library("translator") {
|
||||
sources = rebase_path(compiler_gypi.angle_translator_sources, ".", "src")
|
||||
defines = []
|
||||
|
||||
if (angle_enable_essl || use_libfuzzer) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_essl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_ESSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_glsl || use_libfuzzer) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_glsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_GLSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_hlsl || use_libfuzzer) {
|
||||
sources +=
|
||||
rebase_path(compiler_gypi.angle_translator_hlsl_sources, ".", "src")
|
||||
defines += [ "ANGLE_ENABLE_HLSL" ]
|
||||
}
|
||||
|
||||
if (angle_enable_vulkan || use_libfuzzer) {
|
||||
sources += rebase_path(compiler_gypi.angle_translator_lib_vulkan_sources,
|
||||
".",
|
||||
"src")
|
||||
defines += [ "ANGLE_ENABLE_VULKAN" ]
|
||||
}
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [ ":internal_config" ]
|
||||
public_configs = [ ":external_config" ]
|
||||
if (use_libfuzzer) {
|
||||
all_dependent_configs = [ ":translator_disable_pool_alloc" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
":preprocessor",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
":angle_common",
|
||||
]
|
||||
|
||||
if (is_win) {
|
||||
# Necessary to suppress some system header xtree warnigns in Release.
|
||||
# For some reason this warning doesn't get triggered in Chromium
|
||||
cflags = [ "/wd4718" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("translator_fuzzer") {
|
||||
sources = [
|
||||
"src/compiler/fuzz/translator_fuzzer.cpp",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"include",
|
||||
"src",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":translator",
|
||||
]
|
||||
}
|
||||
|
||||
config("commit_id_config") {
|
||||
include_dirs = [ "$root_gen_dir/angle" ]
|
||||
}
|
||||
|
||||
commit_id_output_file = "$root_gen_dir/angle/id/commit.h"
|
||||
if (angle_use_commit_id) {
|
||||
action("commit_id") {
|
||||
script = "src/commit_id.py"
|
||||
outputs = [
|
||||
commit_id_output_file,
|
||||
]
|
||||
|
||||
args = [
|
||||
"gen",
|
||||
rebase_path(".", root_build_dir),
|
||||
rebase_path(commit_id_output_file, root_build_dir),
|
||||
]
|
||||
|
||||
public_configs = [ ":commit_id_config" ]
|
||||
}
|
||||
} else {
|
||||
copy("commit_id") {
|
||||
sources = [
|
||||
"src/commit.h",
|
||||
]
|
||||
outputs = [
|
||||
commit_id_output_file,
|
||||
]
|
||||
public_configs = [ ":commit_id_config" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("libANGLE_config") {
|
||||
cflags = []
|
||||
defines = []
|
||||
if (angle_enable_d3d9) {
|
||||
defines += [ "ANGLE_ENABLE_D3D9" ]
|
||||
}
|
||||
if (angle_enable_d3d11) {
|
||||
defines += [ "ANGLE_ENABLE_D3D11" ]
|
||||
}
|
||||
if (angle_enable_gl) {
|
||||
defines += [ "ANGLE_ENABLE_OPENGL" ]
|
||||
if (use_x11) {
|
||||
defines += [ "ANGLE_USE_X11" ]
|
||||
}
|
||||
}
|
||||
if (angle_enable_vulkan) {
|
||||
defines += [ "ANGLE_ENABLE_VULKAN" ]
|
||||
}
|
||||
if (angle_enable_null) {
|
||||
defines += [ "ANGLE_ENABLE_NULL" ]
|
||||
}
|
||||
defines += [ "LIBANGLE_IMPLEMENTATION" ]
|
||||
|
||||
if (is_win) {
|
||||
cflags += [ "/wd4530" ] # C++ exception handler used, but unwind semantics are not enabled.
|
||||
}
|
||||
}
|
||||
|
||||
static_library("libANGLE") {
|
||||
sources = rebase_path(gles_gypi.libangle_sources, ".", "src")
|
||||
|
||||
include_dirs = []
|
||||
libs = []
|
||||
defines = []
|
||||
public_deps = [
|
||||
":angle_common",
|
||||
]
|
||||
deps = [
|
||||
":angle_gpu_info_util",
|
||||
":angle_image_util",
|
||||
":commit_id",
|
||||
":includes",
|
||||
":translator",
|
||||
]
|
||||
|
||||
# Shared D3D sources.
|
||||
if (angle_enable_d3d9 || angle_enable_d3d11) {
|
||||
sources += rebase_path(gles_gypi.libangle_d3d_shared_sources, ".", "src")
|
||||
|
||||
defines += [ "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " + "\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }" ]
|
||||
}
|
||||
|
||||
if (angle_enable_d3d9) {
|
||||
sources += rebase_path(gles_gypi.libangle_d3d9_sources, ".", "src")
|
||||
libs += [ "d3d9.lib" ]
|
||||
}
|
||||
|
||||
if (angle_enable_d3d11) {
|
||||
sources += rebase_path(gles_gypi.libangle_d3d11_sources, ".", "src")
|
||||
sources += rebase_path(gles_gypi.libangle_d3d11_win32_sources, ".", "src")
|
||||
libs += [ "dxguid.lib" ]
|
||||
}
|
||||
|
||||
if (angle_enable_gl) {
|
||||
sources += rebase_path(gles_gypi.libangle_gl_sources, ".", "src")
|
||||
include_dirs += [ "src/third_party/khronos" ]
|
||||
|
||||
if (is_win) {
|
||||
sources += rebase_path(gles_gypi.libangle_gl_wgl_sources, ".", "src")
|
||||
}
|
||||
if (use_x11) {
|
||||
sources += rebase_path(gles_gypi.libangle_gl_glx_sources, ".", "src")
|
||||
deps += [ "src/third_party/libXNVCtrl:libXNVCtrl" ]
|
||||
libs += [
|
||||
"X11",
|
||||
"Xi",
|
||||
"Xext",
|
||||
]
|
||||
}
|
||||
if (is_mac) {
|
||||
sources += rebase_path(gles_gypi.libangle_gl_cgl_sources, ".", "src")
|
||||
libs += [
|
||||
"Cocoa.framework",
|
||||
"IOSurface.framework",
|
||||
"OpenGL.framework",
|
||||
"QuartzCore.framework",
|
||||
]
|
||||
}
|
||||
if (is_android) {
|
||||
sources += rebase_path(gles_gypi.libangle_gl_egl_sources, ".", "src")
|
||||
sources += rebase_path(gles_gypi.libangle_gl_egl_dl_sources, ".", "src")
|
||||
sources +=
|
||||
rebase_path(gles_gypi.libangle_gl_egl_android_sources, ".", "src")
|
||||
libs += [
|
||||
"android",
|
||||
"log",
|
||||
]
|
||||
}
|
||||
if (ozone_platform_gbm) {
|
||||
configs += [ ":libdrm" ]
|
||||
defines += [ "ANGLE_USE_OZONE" ]
|
||||
deps += [ "//third_party/minigbm" ]
|
||||
sources += rebase_path(gles_gypi.libangle_gl_egl_sources, ".", "src")
|
||||
sources += rebase_path(gles_gypi.libangle_gl_egl_dl_sources, ".", "src")
|
||||
sources += rebase_path(gles_gypi.libangle_gl_ozone_sources, ".", "src")
|
||||
}
|
||||
}
|
||||
|
||||
if (angle_enable_vulkan) {
|
||||
sources += rebase_path(gles_gypi.libangle_vulkan_sources, ".", "src")
|
||||
if (is_win) {
|
||||
sources +=
|
||||
rebase_path(gles_gypi.libangle_vulkan_win32_sources, ".", "src")
|
||||
}
|
||||
if (is_linux) {
|
||||
sources += rebase_path(gles_gypi.libangle_vulkan_xcb_sources, ".", "src")
|
||||
}
|
||||
deps += [ "//third_party/angle/src/vulkan_support:angle_vulkan" ]
|
||||
}
|
||||
|
||||
if (angle_enable_null) {
|
||||
sources += rebase_path(gles_gypi.libangle_null_sources, ".", "src")
|
||||
}
|
||||
|
||||
if (is_debug) {
|
||||
defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
|
||||
}
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
|
||||
configs += [
|
||||
":commit_id_config",
|
||||
":debug_annotations_config",
|
||||
":extra_warnings",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
public_configs = [ ":libANGLE_config" ]
|
||||
|
||||
if (is_win) {
|
||||
data_deps = [
|
||||
":copy_compiler_dll",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
config("shared_library_public_config") {
|
||||
if (is_mac && !is_component_build) {
|
||||
# Executable targets that depend on the shared libraries below need to have
|
||||
# the rpath setup in non-component build configurations.
|
||||
ldflags = [
|
||||
"-rpath",
|
||||
"@executable_path/",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# This config controls export definitions on ANGLE API calls.
|
||||
config("angle_static") {
|
||||
defines = [
|
||||
"ANGLE_EXPORT=",
|
||||
"EGLAPI=",
|
||||
"GL_APICALL=",
|
||||
]
|
||||
}
|
||||
|
||||
shared_library("libGLESv2") {
|
||||
sources = rebase_path(gles_gypi.libglesv2_sources, ".", "src")
|
||||
|
||||
if (is_android) {
|
||||
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
ldflags =
|
||||
[ "/DEF:" + rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ]
|
||||
}
|
||||
|
||||
if (is_mac && !is_component_build) {
|
||||
ldflags = [
|
||||
"-install_name",
|
||||
"@rpath/${target_name}.dylib",
|
||||
]
|
||||
public_configs = [ ":shared_library_public_config" ]
|
||||
}
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [
|
||||
":commit_id_config",
|
||||
":debug_annotations_config",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
defines = [ "LIBGLESV2_IMPLEMENTATION" ]
|
||||
if (is_win) {
|
||||
defines += [ "GL_APICALL=" ]
|
||||
} else {
|
||||
defines += [ "GL_APICALL=__attribute__((visibility(\"default\")))" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
":libANGLE",
|
||||
"//build/config:exe_and_shlib_deps",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("libGLESv2_static") {
|
||||
sources = rebase_path(gles_gypi.libglesv2_sources, ".", "src")
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [
|
||||
":commit_id_config",
|
||||
":debug_annotations_config",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
public_configs = [ ":angle_static" ]
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
":libANGLE",
|
||||
]
|
||||
}
|
||||
|
||||
shared_library("libEGL") {
|
||||
sources = rebase_path(gles_gypi.libegl_sources, ".", "src")
|
||||
|
||||
if (is_android) {
|
||||
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
|
||||
}
|
||||
configs -= angle_undefine_configs
|
||||
configs += [
|
||||
":commit_id_config",
|
||||
":debug_annotations_config",
|
||||
":extra_warnings",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
defines = [ "LIBEGL_IMPLEMENTATION" ]
|
||||
if (is_win) {
|
||||
defines += [ "EGLAPI=" ]
|
||||
} else {
|
||||
defines += [ "EGLAPI=__attribute__((visibility(\"default\")))" ]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
ldflags = [ "/DEF:" + rebase_path("src/libEGL/libEGL.def", root_build_dir) ]
|
||||
}
|
||||
|
||||
if (is_mac && !is_component_build) {
|
||||
ldflags = [
|
||||
"-install_name",
|
||||
"@rpath/${target_name}.dylib",
|
||||
]
|
||||
public_configs = [ ":shared_library_public_config" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
":libGLESv2",
|
||||
"//build/config:exe_and_shlib_deps",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("libEGL_static") {
|
||||
sources = rebase_path(gles_gypi.libegl_sources, ".", "src")
|
||||
|
||||
configs -= angle_undefine_configs
|
||||
configs += [
|
||||
":commit_id_config",
|
||||
":debug_annotations_config",
|
||||
":extra_warnings",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
public_configs = [ ":angle_static" ]
|
||||
|
||||
deps = [
|
||||
":includes",
|
||||
":libGLESv2_static",
|
||||
]
|
||||
}
|
||||
|
||||
util_gypi = exec_script("//build/gypi_to_gn.py",
|
||||
[ rebase_path("util/util.gyp") ],
|
||||
"scope",
|
||||
[ "util/util.gyp" ])
|
||||
|
||||
config("angle_util_config") {
|
||||
include_dirs = [ "util" ]
|
||||
if (is_linux && use_x11) {
|
||||
libs = [ "X11" ]
|
||||
}
|
||||
}
|
||||
|
||||
foreach(is_shared_library,
|
||||
[
|
||||
true,
|
||||
false,
|
||||
]) {
|
||||
if (is_shared_library) {
|
||||
library_type = "shared_library"
|
||||
library_name = "angle_util"
|
||||
dep_suffix = ""
|
||||
} else {
|
||||
library_type = "static_library"
|
||||
library_name = "angle_util_static"
|
||||
dep_suffix = "_static"
|
||||
}
|
||||
|
||||
target(library_type, library_name) {
|
||||
sources = rebase_path(util_gypi.util_sources, ".", "util")
|
||||
|
||||
if (is_win) {
|
||||
sources += rebase_path(util_gypi.util_win32_sources, ".", "util")
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
sources += rebase_path(util_gypi.util_linux_sources, ".", "util")
|
||||
libs = [
|
||||
"rt",
|
||||
"dl",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
sources += rebase_path(util_gypi.util_osx_sources, ".", "util")
|
||||
libs = [
|
||||
"AppKit.framework",
|
||||
"QuartzCore.framework",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_x11) {
|
||||
sources += rebase_path(util_gypi.util_x11_sources, ".", "util")
|
||||
}
|
||||
|
||||
if (is_android) {
|
||||
if (is_shared_library) {
|
||||
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
|
||||
}
|
||||
|
||||
# To prevent linux sources filtering on android
|
||||
set_sources_assignment_filter([])
|
||||
sources += rebase_path(util_gypi.util_linux_sources, ".", "util")
|
||||
sources += rebase_path(util_gypi.util_android_sources, ".", "util")
|
||||
libs = [
|
||||
"android",
|
||||
"log",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_ozone) {
|
||||
sources += rebase_path(util_gypi.util_ozone_sources, ".", "util")
|
||||
}
|
||||
|
||||
configs += [
|
||||
":debug_annotations_config",
|
||||
":extra_warnings",
|
||||
]
|
||||
|
||||
public_configs = [
|
||||
":angle_util_config",
|
||||
":internal_config",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":angle_common",
|
||||
":libEGL${dep_suffix}",
|
||||
":libGLESv2${dep_suffix}",
|
||||
]
|
||||
|
||||
if (is_shared_library) {
|
||||
defines = [ "LIBANGLE_UTIL_IMPLEMENTATION" ]
|
||||
|
||||
deps += [ "//build/config:exe_and_shlib_deps" ]
|
||||
|
||||
if (is_mac && !is_component_build) {
|
||||
ldflags = [
|
||||
"-install_name",
|
||||
"@rpath/lib${target_name}.dylib",
|
||||
]
|
||||
public_configs += [ ":shared_library_public_config" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Convenience targets for some of the samples so they can be built
|
||||
# with Chromium's toolchain.
|
||||
|
||||
executable("angle_shader_translator") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"samples/shader_translator/shader_translator.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":translator",
|
||||
"//build/config:exe_and_shlib_deps",
|
||||
]
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
# This is the official list of people who can contribute
|
||||
# (and who have contributed) code to the ANGLE project
|
||||
# repository.
|
||||
# The AUTHORS file lists the copyright holders; this file
|
||||
# lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
#
|
||||
|
||||
TransGaming Inc.
|
||||
Nicolas Capens
|
||||
Daniel Koch
|
||||
Geoff Lang
|
||||
Andrew Lewycky
|
||||
Jamie Madill
|
||||
Gavriel State
|
||||
Shannon Woods
|
||||
|
||||
Google Inc.
|
||||
Brent Austin
|
||||
Michael Bai
|
||||
John Bauman
|
||||
Peter Beverloo
|
||||
Steve Block
|
||||
Rachel Blum
|
||||
Eric Boren
|
||||
Henry Bridge
|
||||
Nat Duca
|
||||
Peter Kasting
|
||||
Vangelis Kokkevis
|
||||
Zhenyao Mo
|
||||
Daniel Nicoara
|
||||
Alastair Patrick
|
||||
Alok Priyadarshi
|
||||
Kenneth Russell
|
||||
Brian Salomon
|
||||
Gregg Tavares
|
||||
Jeff Timanus
|
||||
Ben Vanik
|
||||
Adrienne Walker
|
||||
thestig@chromium.org
|
||||
Justin Schuh
|
||||
Scott Graham
|
||||
Corentin Wallez
|
||||
|
||||
Adobe Systems Inc.
|
||||
Alexandru Chiculita
|
||||
Steve Minns
|
||||
Max Vujovic
|
||||
|
||||
Autodesk, Inc.
|
||||
Ranger Harke
|
||||
|
||||
Cloud Party, Inc.
|
||||
Conor Dickinson
|
||||
|
||||
The Qt Company Ltd.
|
||||
Andrew Knight
|
||||
|
||||
Imagination Technologies Ltd.
|
||||
Gregoire Payen de La Garanderie
|
||||
|
||||
Intel Corporation
|
||||
Jin Yang
|
||||
Andy Chen
|
||||
Josh Triplett
|
||||
Sudarsana Nagineni
|
||||
Jiajia Qin
|
||||
Jiawei Shao
|
||||
Jie Chen
|
||||
Qiankun Miao
|
||||
Bryan Bernhart
|
||||
Yunchao He
|
||||
Xinghua Cao
|
||||
Brandon Jones
|
||||
|
||||
Klarälvdalens Datakonsult AB
|
||||
Milian Wolff
|
||||
|
||||
Mozilla Corp.
|
||||
Ehsan Akhgari
|
||||
Edwin Flores
|
||||
Jeff Gilbert
|
||||
Mike Hommey
|
||||
Benoit Jacob
|
||||
Makoto Kato
|
||||
Vladimir Vukicevic
|
||||
|
||||
Turbulenz
|
||||
Michael Braithwaite
|
||||
|
||||
Ulrik Persson (ddefrostt)
|
||||
Mark Banner (standard8mbp)
|
||||
David Kilzer
|
||||
Jacek Caban
|
||||
Tibor den Ouden
|
||||
Régis Fénéon
|
||||
Sebastian Bergstein
|
||||
James Ross-Gowan
|
||||
Andrei Volykhin
|
||||
Jérôme Duval
|
||||
|
||||
Microsoft Corporation
|
||||
Cooper Partin
|
||||
Austin Kinross
|
||||
Minmin Gong
|
||||
Shawn Hargreaves
|
||||
|
||||
Microsoft Open Technologies, Inc.
|
||||
Cooper Partin
|
||||
Austin Kinross
|
||||
|
||||
NVIDIA Corporation
|
||||
Olli Etuaho
|
||||
Arun Patole
|
||||
Qingqing Deng
|
||||
Kimmo Kinnunen
|
||||
Sami Väisänen
|
||||
Martin Radev
|
||||
|
||||
Opera Software ASA
|
||||
Daniel Bratell
|
||||
Tomasz Moniuszko
|
||||
David Landell
|
||||
|
||||
Advanced Micro Devices, Inc.
|
||||
Russ Lind
|
125
gfx/angle/DEPS
125
gfx/angle/DEPS
|
@ -1,125 +0,0 @@
|
|||
vars = {
|
||||
'android_git': 'https://android.googlesource.com',
|
||||
'chromium_git': 'https://chromium.googlesource.com',
|
||||
}
|
||||
|
||||
deps = {
|
||||
|
||||
'buildtools':
|
||||
Var('chromium_git') + '/chromium/buildtools.git' + '@' + '98f00fa10dbad2cdbb2e297a66c3d6d5bc3994f3',
|
||||
|
||||
'testing/gmock':
|
||||
Var('chromium_git') + '/external/googlemock.git' + '@' + '0421b6f358139f02e102c9c332ce19a33faf75be', # from svn revision 566
|
||||
|
||||
'testing/gtest':
|
||||
Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '6f8a66431cb592dad629028a50b3dd418a408c87',
|
||||
|
||||
# Cherry is a dEQP management GUI written in Go. We use it for viewing test results.
|
||||
'third_party/cherry':
|
||||
Var('android_git') + '/platform/external/cherry' + '@' + 'd2e26b4d864ec2a6757e7f1174e464949ca5bf73',
|
||||
|
||||
'third_party/deqp/src':
|
||||
Var('android_git') + '/platform/external/deqp' + '@' + '455d82c60b096e7bd83b6a2f5ed70c61e4bfa759',
|
||||
|
||||
'third_party/glslang-angle/src':
|
||||
Var('android_git') + '/platform/external/shaderc/glslang' + '@' + '1e275c8486325aaab34734ad9a650c0121c5efdb',
|
||||
|
||||
'third_party/gyp':
|
||||
Var('chromium_git') + '/external/gyp' + '@' + 'c6f471687407bf28ddfc63f1a8f47aeb7bf54edc',
|
||||
|
||||
'third_party/libpng':
|
||||
Var('android_git') + '/platform/external/libpng' + '@' + '094e181e79a3d6c23fd005679025058b7df1ad6c',
|
||||
|
||||
'third_party/spirv-headers/src':
|
||||
Var('android_git') + '/platform/external/shaderc/spirv-headers' + '@' + 'c470b68225a04965bf87d35e143ae92f831e8110',
|
||||
|
||||
'third_party/spirv-tools-angle/src':
|
||||
Var('android_git') + '/platform/external/shaderc/spirv-tools' + '@' + '68c5f0436f1d4f1f137e608780190865d0b193ca',
|
||||
|
||||
'third_party/vulkan-validation-layers/src':
|
||||
Var('android_git') + '/platform/external/vulkan-validation-layers' + '@' + 'f47c534fee2f26f6b783209d56e0ade48e30eb8d',
|
||||
|
||||
'third_party/zlib':
|
||||
Var('chromium_git') + '/chromium/src/third_party/zlib' + '@' + '24ab14872e8e068ba08cc31cc3d43bcc6d5cb832',
|
||||
}
|
||||
|
||||
hooks = [
|
||||
# Pull clang-format binaries using checked-in hashes.
|
||||
{
|
||||
'name': 'clang_format_win',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=win32',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-clang-format',
|
||||
'-s', 'buildtools/win/clang-format.exe.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'clang_format_mac',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=darwin',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-clang-format',
|
||||
'-s', 'buildtools/mac/clang-format.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'clang_format_linux',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=linux*',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-clang-format',
|
||||
'-s', 'buildtools/linux64/clang-format.sha1',
|
||||
],
|
||||
},
|
||||
# Pull GN binaries using checked-in hashes.
|
||||
{
|
||||
'name': 'gn_win',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=win32',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/win/gn.exe.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'gn_mac',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=darwin',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/mac/gn.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': 'gn_linux64',
|
||||
'pattern': '.',
|
||||
'action': [ 'download_from_google_storage',
|
||||
'--no_resume',
|
||||
'--platform=linux*',
|
||||
'--no_auth',
|
||||
'--bucket', 'chromium-gn',
|
||||
'-s', 'buildtools/linux64/gn.sha1',
|
||||
],
|
||||
},
|
||||
{
|
||||
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
|
||||
'pattern': '.',
|
||||
'action': ['python', 'gyp/gyp_angle'],
|
||||
},
|
||||
]
|
||||
|
||||
recursedeps = [
|
||||
# buildtools provides clang_format.
|
||||
'buildtools',
|
||||
]
|
|
@ -1,46 +0,0 @@
|
|||
# This file is used to manage the ANGLE's dependencies in the Chromium src repo. It is
|
||||
# used by gclient to determine what version of each dependency to check out, and
|
||||
# where.
|
||||
#
|
||||
# These deps are duplicated in ANGLE's DEPS file which we use for the standalone
|
||||
# build. The dual file setup is necessary because Chromium can only recurse into
|
||||
# a single file and we do not want to import all of ANGLE's standalone DEPS.
|
||||
#
|
||||
# If you make a change to one of these dependencies please also update the
|
||||
# standalone DEPS file.
|
||||
|
||||
vars = {
|
||||
'android_git': 'https://android.googlesource.com',
|
||||
|
||||
# Current revision of dEQP.
|
||||
'deqp_revision': '455d82c60b096e7bd83b6a2f5ed70c61e4bfa759',
|
||||
|
||||
# Current revision of glslang, the Khronos SPIRV compiler.
|
||||
'glslang_revision': '1e275c8486325aaab34734ad9a650c0121c5efdb',
|
||||
|
||||
# Current revision fo the SPIRV-Headers Vulkan support library.
|
||||
'spirv_headers_revision': 'c470b68225a04965bf87d35e143ae92f831e8110',
|
||||
|
||||
# Current revision of SPIRV-Tools for Vulkan.
|
||||
'spirv_tools_revision': '68c5f0436f1d4f1f137e608780190865d0b193ca',
|
||||
|
||||
# Current revision of the Vulkan Validation Layers SDK.
|
||||
'vulkan_revision': 'f47c534fee2f26f6b783209d56e0ade48e30eb8d',
|
||||
}
|
||||
|
||||
deps = {
|
||||
'src/third_party/deqp/src':
|
||||
Var('android_git') + '/platform/external/deqp@' + Var('deqp_revision'),
|
||||
|
||||
'src/third_party/glslang-angle/src':
|
||||
Var('android_git') + '/platform/external/shaderc/glslang@' + Var('glslang_revision'),
|
||||
|
||||
'src/third_party/spirv-headers/src':
|
||||
Var('android_git') + '/platform/external/shaderc/spirv-headers@' + Var('spirv_headers_revision'),
|
||||
|
||||
'src/third_party/spirv-tools-angle/src':
|
||||
Var('android_git') + '/platform/external/shaderc/spirv-tools@' + Var('spirv_tools_revision'),
|
||||
|
||||
'src/third_party/vulkan-validation-layers/src':
|
||||
Var('android_git') + '/platform/external/vulkan-validation-layers@' + Var('vulkan_revision'),
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright (C) 2002-2013 The ANGLE Project Authors.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc.
|
||||
// Ltd., nor the names of their contributors may be used to endorse
|
||||
// or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,10 +0,0 @@
|
|||
Name: ANGLE
|
||||
URL: https://code.google.com/p/angleproject/
|
||||
Version: 2422
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
Description:
|
||||
ANGLE is a conformant implementation of the OpenGL ES 2.0
|
||||
specification that is hardware‐accelerated via Direct3D.
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
# ANGLE - Almost Native Graphics Layer Engine
|
||||
|
||||
The goal of ANGLE is to allow users of multiple operating systems to seamlessly run WebGL and other
|
||||
OpenGL ES content by translating OpenGL ES API calls to one of the hardware-supported APIs available
|
||||
for that platform. ANGLE currently provides translation from OpenGL ES 2.0 and 3.0 to desktop
|
||||
OpenGL, OpenGL ES, Direct3D 9, and Direct3D 11. Support for translation from OpenGL ES to Vulkan is
|
||||
underway, and future plans include compute shader support (ES 3.1) and MacOS support.
|
||||
|
||||
### Level of OpenGL ES support via backing renderers
|
||||
|
||||
| | Direct3D 9 | Direct3D 11 | Desktop GL | GL ES | Vulkan |
|
||||
|----------------|:-------------:|:----------------:|:--------------:|:-------------:|:-------------:|
|
||||
| OpenGL ES 2.0 | complete | complete | complete | complete | in progress |
|
||||
| OpenGL ES 3.0 | | complete | complete | in progress | not started |
|
||||
| OpenGL ES 3.1 | | not started | in progress | in progress | not started |
|
||||
|
||||
### Platform support via backing renderers
|
||||
|
||||
| | Direct3D 9 | Direct3D 11 | Desktop GL | GL ES | Vulkan |
|
||||
|------------:|:--------------:|:--------------:|:-------------:|:-----------:|:-----------:|
|
||||
| Windows | complete | complete | complete | complete | in progress |
|
||||
| Linux | | | complete | | planned |
|
||||
| Mac OS X | | | in progress | | |
|
||||
| Chrome OS | | | | complete | planned |
|
||||
| Android | | | | complete | planned |
|
||||
|
||||
ANGLE v1.0.772 was certified compliant by passing the ES 2.0.3 conformance tests in October 2011.
|
||||
ANGLE also provides an implementation of the EGL 1.4 specification.
|
||||
|
||||
ANGLE is used as the default WebGL backend for both Google Chrome and Mozilla Firefox on Windows
|
||||
platforms. Chrome uses ANGLE for all graphics rendering on Windows, including the accelerated
|
||||
Canvas2D implementation and the Native Client sandbox environment.
|
||||
|
||||
Portions of the ANGLE shader compiler are used as a shader validator and translator by WebGL
|
||||
implementations across multiple platforms. It is used on Mac OS X, Linux, and in mobile variants of
|
||||
the browsers. Having one shader validator helps to ensure that a consistent set of GLSL ES shaders
|
||||
are accepted across browsers and platforms. The shader translator can be used to translate shaders
|
||||
to other shading languages, and to optionally apply shader modifications to work around bugs or
|
||||
quirks in the native graphics drivers. The translator targets Desktop GLSL, Direct3D HLSL, and even
|
||||
ESSL for native GLES2 platforms.
|
||||
|
||||
## Sources
|
||||
|
||||
ANGLE repository is hosted by Chromium project and can be
|
||||
[browsed online](https://chromium.googlesource.com/angle/angle) or cloned with
|
||||
|
||||
git clone https://chromium.googlesource.com/angle/angle
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
View the [Dev setup instructions](doc/DevSetup.md). For generating a Windows Store version of ANGLE view the [Windows Store instructions](doc/BuildingAngleForWindowsStore.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
* Join our [Google group](https://groups.google.com/group/angleproject) to keep up to date.
|
||||
* Join us on IRC in the #ANGLEproject channel on FreeNode.
|
||||
* File bugs in the [issue tracker](http://code.google.com/p/angleproject/issues/list) (preferably with an isolated test-case).
|
||||
* [Choose an ANGLE branch](doc/ChoosingANGLEBranch.md) to track in your own project.
|
||||
|
||||
|
||||
* Read ANGLE development [documentation](doc).
|
||||
* Look at [pending](https://chromium-review.googlesource.com/#/q/project:angle/angle+status:open)
|
||||
and [merged](https://chromium-review.googlesource.com/#/q/project:angle/angle+status:merged) changes.
|
||||
* Become a [code contributor](doc/ContributingCode.md).
|
||||
* Use ANGLE's [coding standard](doc/CodingStandard.md).
|
||||
* Learn how to [build ANGLE for Chromium development](doc/BuildingAngleForChromiumDevelopment.md).
|
||||
* Get help on [debugging ANGLE](doc/DebuggingTips.md).
|
||||
|
||||
|
||||
* Read about WebGL on the [Khronos WebGL Wiki](http://khronos.org/webgl/wiki/Main_Page).
|
||||
* Learn about implementation details in the [OpenGL Insights chapter on ANGLE](http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf) and this [ANGLE presentation](https://drive.google.com/file/d/0Bw29oYeC09QbbHoxNE5EUFh0RGs/view?usp=sharing).
|
||||
* Learn about the past, present, and future of the ANGLE implementation in [this recent presentation](https://docs.google.com/presentation/d/1CucIsdGVDmdTWRUbg68IxLE5jXwCb2y1E9YVhQo0thg/pub?start=false&loop=false).
|
||||
* If you use ANGLE in your own project, we'd love to hear about it!
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
#ifndef __egl_h_
|
||||
#define __egl_h_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013-2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
/*
|
||||
** This header is generated from the Khronos OpenGL / OpenGL ES XML
|
||||
** API Registry. The current version of the Registry, generator scripts
|
||||
** used to make the header, and the header can be found at
|
||||
** http://www.opengl.org/registry/egl
|
||||
**
|
||||
** Khronos $Revision$ on $Date$
|
||||
*/
|
||||
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
/* Generated on date 20161230 */
|
||||
|
||||
/* Generated C header for:
|
||||
* API: egl
|
||||
* Versions considered: .*
|
||||
* Versions emitted: .*
|
||||
* Default extensions included: None
|
||||
* Additional extensions included: _nomatch_^
|
||||
* Extensions removed: _nomatch_^
|
||||
*/
|
||||
|
||||
#ifndef EGL_VERSION_1_0
|
||||
#define EGL_VERSION_1_0 1
|
||||
typedef unsigned int EGLBoolean;
|
||||
typedef void *EGLDisplay;
|
||||
#include <KHR/khrplatform.h>
|
||||
#include <EGL/eglplatform.h>
|
||||
typedef void *EGLConfig;
|
||||
typedef void *EGLSurface;
|
||||
typedef void *EGLContext;
|
||||
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
|
||||
#define EGL_ALPHA_SIZE 0x3021
|
||||
#define EGL_BAD_ACCESS 0x3002
|
||||
#define EGL_BAD_ALLOC 0x3003
|
||||
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||
#define EGL_BAD_CONFIG 0x3005
|
||||
#define EGL_BAD_CONTEXT 0x3006
|
||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
#define EGL_BAD_DISPLAY 0x3008
|
||||
#define EGL_BAD_MATCH 0x3009
|
||||
#define EGL_BAD_NATIVE_PIXMAP 0x300A
|
||||
#define EGL_BAD_NATIVE_WINDOW 0x300B
|
||||
#define EGL_BAD_PARAMETER 0x300C
|
||||
#define EGL_BAD_SURFACE 0x300D
|
||||
#define EGL_BLUE_SIZE 0x3022
|
||||
#define EGL_BUFFER_SIZE 0x3020
|
||||
#define EGL_CONFIG_CAVEAT 0x3027
|
||||
#define EGL_CONFIG_ID 0x3028
|
||||
#define EGL_CORE_NATIVE_ENGINE 0x305B
|
||||
#define EGL_DEPTH_SIZE 0x3025
|
||||
#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
|
||||
#define EGL_DRAW 0x3059
|
||||
#define EGL_EXTENSIONS 0x3055
|
||||
#define EGL_FALSE 0
|
||||
#define EGL_GREEN_SIZE 0x3023
|
||||
#define EGL_HEIGHT 0x3056
|
||||
#define EGL_LARGEST_PBUFFER 0x3058
|
||||
#define EGL_LEVEL 0x3029
|
||||
#define EGL_MAX_PBUFFER_HEIGHT 0x302A
|
||||
#define EGL_MAX_PBUFFER_PIXELS 0x302B
|
||||
#define EGL_MAX_PBUFFER_WIDTH 0x302C
|
||||
#define EGL_NATIVE_RENDERABLE 0x302D
|
||||
#define EGL_NATIVE_VISUAL_ID 0x302E
|
||||
#define EGL_NATIVE_VISUAL_TYPE 0x302F
|
||||
#define EGL_NONE 0x3038
|
||||
#define EGL_NON_CONFORMANT_CONFIG 0x3051
|
||||
#define EGL_NOT_INITIALIZED 0x3001
|
||||
#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
|
||||
#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
|
||||
#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
|
||||
#define EGL_PBUFFER_BIT 0x0001
|
||||
#define EGL_PIXMAP_BIT 0x0002
|
||||
#define EGL_READ 0x305A
|
||||
#define EGL_RED_SIZE 0x3024
|
||||
#define EGL_SAMPLES 0x3031
|
||||
#define EGL_SAMPLE_BUFFERS 0x3032
|
||||
#define EGL_SLOW_CONFIG 0x3050
|
||||
#define EGL_STENCIL_SIZE 0x3026
|
||||
#define EGL_SUCCESS 0x3000
|
||||
#define EGL_SURFACE_TYPE 0x3033
|
||||
#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
|
||||
#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
|
||||
#define EGL_TRANSPARENT_RED_VALUE 0x3037
|
||||
#define EGL_TRANSPARENT_RGB 0x3052
|
||||
#define EGL_TRANSPARENT_TYPE 0x3034
|
||||
#define EGL_TRUE 1
|
||||
#define EGL_VENDOR 0x3053
|
||||
#define EGL_VERSION 0x3054
|
||||
#define EGL_WIDTH 0x3057
|
||||
#define EGL_WINDOW_BIT 0x0004
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
|
||||
EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
|
||||
EGLAPI EGLint EGLAPIENTRY eglGetError (void);
|
||||
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
|
||||
EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
|
||||
#endif /* EGL_VERSION_1_0 */
|
||||
|
||||
#ifndef EGL_VERSION_1_1
|
||||
#define EGL_VERSION_1_1 1
|
||||
#define EGL_BACK_BUFFER 0x3084
|
||||
#define EGL_BIND_TO_TEXTURE_RGB 0x3039
|
||||
#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
|
||||
#define EGL_CONTEXT_LOST 0x300E
|
||||
#define EGL_MIN_SWAP_INTERVAL 0x303B
|
||||
#define EGL_MAX_SWAP_INTERVAL 0x303C
|
||||
#define EGL_MIPMAP_TEXTURE 0x3082
|
||||
#define EGL_MIPMAP_LEVEL 0x3083
|
||||
#define EGL_NO_TEXTURE 0x305C
|
||||
#define EGL_TEXTURE_2D 0x305F
|
||||
#define EGL_TEXTURE_FORMAT 0x3080
|
||||
#define EGL_TEXTURE_RGB 0x305D
|
||||
#define EGL_TEXTURE_RGBA 0x305E
|
||||
#define EGL_TEXTURE_TARGET 0x3081
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
|
||||
#endif /* EGL_VERSION_1_1 */
|
||||
|
||||
#ifndef EGL_VERSION_1_2
|
||||
#define EGL_VERSION_1_2 1
|
||||
typedef unsigned int EGLenum;
|
||||
typedef void *EGLClientBuffer;
|
||||
#define EGL_ALPHA_FORMAT 0x3088
|
||||
#define EGL_ALPHA_FORMAT_NONPRE 0x308B
|
||||
#define EGL_ALPHA_FORMAT_PRE 0x308C
|
||||
#define EGL_ALPHA_MASK_SIZE 0x303E
|
||||
#define EGL_BUFFER_PRESERVED 0x3094
|
||||
#define EGL_BUFFER_DESTROYED 0x3095
|
||||
#define EGL_CLIENT_APIS 0x308D
|
||||
#define EGL_COLORSPACE 0x3087
|
||||
#define EGL_COLORSPACE_sRGB 0x3089
|
||||
#define EGL_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_COLOR_BUFFER_TYPE 0x303F
|
||||
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
|
||||
#define EGL_DISPLAY_SCALING 10000
|
||||
#define EGL_HORIZONTAL_RESOLUTION 0x3090
|
||||
#define EGL_LUMINANCE_BUFFER 0x308F
|
||||
#define EGL_LUMINANCE_SIZE 0x303D
|
||||
#define EGL_OPENGL_ES_BIT 0x0001
|
||||
#define EGL_OPENVG_BIT 0x0002
|
||||
#define EGL_OPENGL_ES_API 0x30A0
|
||||
#define EGL_OPENVG_API 0x30A1
|
||||
#define EGL_OPENVG_IMAGE 0x3096
|
||||
#define EGL_PIXEL_ASPECT_RATIO 0x3092
|
||||
#define EGL_RENDERABLE_TYPE 0x3040
|
||||
#define EGL_RENDER_BUFFER 0x3086
|
||||
#define EGL_RGB_BUFFER 0x308E
|
||||
#define EGL_SINGLE_BUFFER 0x3085
|
||||
#define EGL_SWAP_BEHAVIOR 0x3093
|
||||
#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
|
||||
#define EGL_VERTICAL_RESOLUTION 0x3091
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
|
||||
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
|
||||
#ifndef EGL_VERSION_1_3
|
||||
#define EGL_VERSION_1_3 1
|
||||
#define EGL_CONFORMANT 0x3042
|
||||
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||
#define EGL_MATCH_NATIVE_PIXMAP 0x3041
|
||||
#define EGL_OPENGL_ES2_BIT 0x0004
|
||||
#define EGL_VG_ALPHA_FORMAT 0x3088
|
||||
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
|
||||
#define EGL_VG_COLORSPACE 0x3087
|
||||
#define EGL_VG_COLORSPACE_sRGB 0x3089
|
||||
#define EGL_VG_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
|
||||
#endif /* EGL_VERSION_1_3 */
|
||||
|
||||
#ifndef EGL_VERSION_1_4
|
||||
#define EGL_VERSION_1_4 1
|
||||
#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
|
||||
#define EGL_MULTISAMPLE_RESOLVE 0x3099
|
||||
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
|
||||
#define EGL_OPENGL_API 0x30A2
|
||||
#define EGL_OPENGL_BIT 0x0008
|
||||
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
|
||||
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
|
||||
#endif /* EGL_VERSION_1_4 */
|
||||
|
||||
#ifndef EGL_VERSION_1_5
|
||||
#define EGL_VERSION_1_5 1
|
||||
typedef void *EGLSync;
|
||||
typedef intptr_t EGLAttrib;
|
||||
typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
typedef void *EGLImage;
|
||||
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
|
||||
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
|
||||
#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
|
||||
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
|
||||
#define EGL_NO_RESET_NOTIFICATION 0x31BE
|
||||
#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
|
||||
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
|
||||
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
|
||||
#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
|
||||
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
|
||||
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
|
||||
#define EGL_OPENGL_ES3_BIT 0x00000040
|
||||
#define EGL_CL_EVENT_HANDLE 0x309C
|
||||
#define EGL_SYNC_CL_EVENT 0x30FE
|
||||
#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
|
||||
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
|
||||
#define EGL_SYNC_TYPE 0x30F7
|
||||
#define EGL_SYNC_STATUS 0x30F1
|
||||
#define EGL_SYNC_CONDITION 0x30F8
|
||||
#define EGL_SIGNALED 0x30F2
|
||||
#define EGL_UNSIGNALED 0x30F3
|
||||
#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
|
||||
#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
|
||||
#define EGL_TIMEOUT_EXPIRED 0x30F5
|
||||
#define EGL_CONDITION_SATISFIED 0x30F6
|
||||
#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
|
||||
#define EGL_SYNC_FENCE 0x30F9
|
||||
#define EGL_GL_COLORSPACE 0x309D
|
||||
#define EGL_GL_COLORSPACE_SRGB 0x3089
|
||||
#define EGL_GL_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_GL_RENDERBUFFER 0x30B9
|
||||
#define EGL_GL_TEXTURE_2D 0x30B1
|
||||
#define EGL_GL_TEXTURE_LEVEL 0x30BC
|
||||
#define EGL_GL_TEXTURE_3D 0x30B2
|
||||
#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
|
||||
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
|
||||
#define EGL_IMAGE_PRESERVED 0x30D2
|
||||
#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
|
||||
EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
|
||||
EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
|
||||
EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
|
||||
EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
|
||||
#endif /* EGL_VERSION_1_5 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,170 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2017 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.
|
||||
//
|
||||
// eglext_angle.h: ANGLE modifications to the eglext.h header file.
|
||||
// Currently we don't include this file directly, we patch eglext.h
|
||||
// to include it implicitly so it is visible throughout our code.
|
||||
|
||||
#ifndef INCLUDE_EGL_EGLEXT_ANGLE_
|
||||
#define INCLUDE_EGL_EGLEXT_ANGLE_
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef EGL_ANGLE_display_robust_resource_initialization
|
||||
#define EGL_ANGLE_display_robust_resource_initialization 1
|
||||
#define EGL_DISPLAY_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x3453
|
||||
#endif /* EGL_ANGLE_display_robust_resource_initialization */
|
||||
|
||||
#ifndef EGL_ANGLE_keyed_mutex
|
||||
#define EGL_ANGLE_keyed_mutex 1
|
||||
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
|
||||
#endif /* EGL_ANGLE_keyed_mutex */
|
||||
|
||||
#ifndef EGL_ANGLE_d3d_texture_client_buffer
|
||||
#define EGL_ANGLE_d3d_texture_client_buffer 1
|
||||
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
|
||||
#endif /* EGL_ANGLE_d3d_texture_client_buffer */
|
||||
|
||||
#ifndef EGL_ANGLE_software_display
|
||||
#define EGL_ANGLE_software_display 1
|
||||
#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
|
||||
#endif /* EGL_ANGLE_software_display */
|
||||
|
||||
#ifndef EGL_ANGLE_direct3d_display
|
||||
#define EGL_ANGLE_direct3d_display 1
|
||||
#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
|
||||
#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
|
||||
#endif /* EGL_ANGLE_direct3d_display */
|
||||
|
||||
#ifndef EGL_ANGLE_direct_composition
|
||||
#define EGL_ANGLE_direct_composition 1
|
||||
#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5
|
||||
#endif /* EGL_ANGLE_direct_composition */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle
|
||||
#define EGL_ANGLE_platform_angle 1
|
||||
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
|
||||
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
|
||||
#define EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE 0x3451
|
||||
#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 0x3207
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C
|
||||
#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
|
||||
#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 0x320D
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
|
||||
#endif /* EGL_ANGLE_platform_angle_opengl */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_null
|
||||
#define EGL_ANGLE_platform_angle_null 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE
|
||||
#endif /* EGL_ANGLE_platform_angle_null */
|
||||
|
||||
#ifndef EGL_ANGLE_platform_angle_vulkan
|
||||
#define EGL_ANGLE_platform_angle_vulkan 1
|
||||
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
|
||||
#endif /* EGL_ANGLE_platform_angle_vulkan */
|
||||
|
||||
#ifndef EGL_ANGLE_x11_visual
|
||||
#define EGL_ANGLE_x11_visual
|
||||
#define EGL_X11_VISUAL_ID_ANGLE 0x33A3
|
||||
#endif /* EGL_ANGLE_x11_visual */
|
||||
|
||||
#ifndef EGL_ANGLE_flexible_surface_compatibility
|
||||
#define EGL_ANGLE_flexible_surface_compatibility 1
|
||||
#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6
|
||||
#endif /* EGL_ANGLE_flexible_surface_compatibility */
|
||||
|
||||
#ifndef EGL_ANGLE_surface_orientation
|
||||
#define EGL_ANGLE_surface_orientation
|
||||
#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7
|
||||
#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8
|
||||
#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001
|
||||
#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
|
||||
#endif /* EGL_ANGLE_surface_orientation */
|
||||
|
||||
#ifndef EGL_ANGLE_experimental_present_path
|
||||
#define EGL_ANGLE_experimental_present_path
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
|
||||
#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
|
||||
#endif /* EGL_ANGLE_experimental_present_path */
|
||||
|
||||
#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12
|
||||
#define EGL_ANGLE_stream_producer_d3d_texture_nv12
|
||||
#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x33AB
|
||||
typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
|
||||
typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
|
||||
#endif
|
||||
#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */
|
||||
|
||||
#ifndef EGL_ANGLE_create_context_webgl_compatibility
|
||||
#define EGL_ANGLE_create_context_webgl_compatibility 1
|
||||
#define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x3AAC
|
||||
#endif /* EGL_ANGLE_create_context_webgl_compatibility */
|
||||
|
||||
#ifndef EGL_ANGLE_display_texture_share_group
|
||||
#define EGL_ANGLE_display_texture_share_group 1
|
||||
#define EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE 0x3AAF
|
||||
#endif /* EGL_ANGLE_display_texture_share_group */
|
||||
|
||||
#ifndef EGL_CHROMIUM_create_context_bind_generates_resource
|
||||
#define EGL_CHROMIUM_create_context_bind_generates_resource 1
|
||||
#define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x3AAD
|
||||
#endif /* EGL_CHROMIUM_create_context_bind_generates_resource */
|
||||
|
||||
#ifndef EGL_ANGLE_create_context_client_arrays
|
||||
#define EGL_ANGLE_create_context_client_arrays 1
|
||||
#define EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE 0x3452
|
||||
#endif /* EGL_ANGLE_create_context_client_arrays */
|
||||
|
||||
#ifndef EGL_ANGLE_device_creation
|
||||
#define EGL_ANGLE_device_creation 1
|
||||
typedef EGLDeviceEXT(EGLAPIENTRYP PFNEGLCREATEDEVICEANGLEPROC) (EGLint device_type, void *native_device, const EGLAttrib *attrib_list);
|
||||
typedef EGLBoolean(EGLAPIENTRYP PFNEGLRELEASEDEVICEANGLEPROC) (EGLDeviceEXT device);
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE(EGLint device_type, void *native_device, const EGLAttrib *attrib_list);
|
||||
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE(EGLDeviceEXT device);
|
||||
#endif
|
||||
#endif /* EGL_ANGLE_device_creation */
|
||||
|
||||
#ifndef EGL_ANGLE_program_cache_control
|
||||
#define EGL_ANGLE_program_cache_control 1
|
||||
#define EGL_PROGRAM_CACHE_SIZE_ANGLE 0x3455
|
||||
#define EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE 0x3456
|
||||
#define EGL_PROGRAM_CACHE_RESIZE_ANGLE 0x3457
|
||||
#define EGL_PROGRAM_CACHE_TRIM_ANGLE 0x3458
|
||||
#define EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE 0x3459
|
||||
typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHEGETATTRIBANGLEPROC) (EGLDisplay dpy, EGLenum attrib);
|
||||
typedef void (EGLAPIENTRYP PFNEGLPROGRAMCACHEQUERYANGLEPROC) (EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize);
|
||||
typedef void (EGLAPIENTRYP PFNEGPROGRAMCACHELPOPULATEANGLEPROC) (EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize);
|
||||
typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHERESIZEANGLEPROC) (EGLDisplay dpy, EGLint limit, EGLenum mode);
|
||||
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||
EGLAPI EGLint EGLAPIENTRY eglProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib);
|
||||
EGLAPI void EGLAPIENTRY eglProgramCacheQueryANGLE(EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize);
|
||||
EGLAPI void EGLAPIENTRY eglProgramCachePopulateANGLE(EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize);
|
||||
EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode);
|
||||
#endif
|
||||
#endif /* EGL_ANGLE_program_cache_control */
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // INCLUDE_EGL_EGLEXT_ANGLE_
|
|
@ -1,152 +0,0 @@
|
|||
#ifndef __eglplatform_h_
|
||||
#define __eglplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for egl.h
|
||||
* $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "EGL" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
/* Macros used in EGL function prototype declarations.
|
||||
*
|
||||
* EGL functions should be prototyped as:
|
||||
*
|
||||
* EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
|
||||
* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
|
||||
*
|
||||
* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
|
||||
*/
|
||||
|
||||
#ifndef EGLAPI
|
||||
#define EGLAPI KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef EGLAPIENTRY
|
||||
#define EGLAPIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
#define EGLAPIENTRYP EGLAPIENTRY*
|
||||
|
||||
/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
|
||||
* are aliases of window-system-dependent types, such as X Display * or
|
||||
* Windows Device Context. They must be defined in platform-specific
|
||||
* code below. The EGL-prefixed versions of Native*Type are the same
|
||||
* types, renamed in EGL 1.3 so all types in the API start with "EGL".
|
||||
*
|
||||
* Khronos STRONGLY RECOMMENDS that you use the default definitions
|
||||
* provided below, since these changes affect both binary and source
|
||||
* portability of applications using EGL running on different EGL
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#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_DESKTOP_APP) /* Windows Desktop */
|
||||
typedef HWND EGLNativeWindowType;
|
||||
#else /* Windows Store */
|
||||
#include <inspectable.h>
|
||||
typedef IInspectable* EGLNativeWindowType;
|
||||
#endif
|
||||
|
||||
#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__) || \
|
||||
defined(__Fuchsia__) || defined(__HAIKU__)
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
|
||||
#elif defined(__ANDROID__) || defined(ANDROID)
|
||||
|
||||
#include <android/native_window.h>
|
||||
|
||||
struct egl_native_pixmap_t;
|
||||
|
||||
typedef struct ANativeWindow* EGLNativeWindowType;
|
||||
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
|
||||
typedef void* EGLNativeDisplayType;
|
||||
|
||||
#elif defined(USE_OZONE)
|
||||
|
||||
typedef intptr_t EGLNativeDisplayType;
|
||||
typedef intptr_t EGLNativeWindowType;
|
||||
typedef intptr_t EGLNativePixmapType;
|
||||
|
||||
#elif defined(WL_EGL_PLATFORM)
|
||||
|
||||
typedef struct wl_display *EGLNativeDisplayType;
|
||||
typedef struct wl_egl_pixmap *EGLNativePixmapType;
|
||||
typedef struct wl_egl_window *EGLNativeWindowType;
|
||||
|
||||
#elif defined(__unix__)
|
||||
|
||||
/* X11 (tentative) */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
||||
#else
|
||||
#error "Platform not recognized"
|
||||
#endif
|
||||
|
||||
/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
|
||||
typedef EGLNativeDisplayType NativeDisplayType;
|
||||
typedef EGLNativePixmapType NativePixmapType;
|
||||
typedef EGLNativeWindowType NativeWindowType;
|
||||
|
||||
|
||||
/* Define EGLint. This must be a signed integral type large enough to contain
|
||||
* all legal attribute names and values passed into and out of EGL, whether
|
||||
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
|
||||
* handle, or other. While in general a 32-bit integer will suffice, if
|
||||
* handles are 64 bit types, then EGLint should be defined as a signed 64-bit
|
||||
* integer type.
|
||||
*/
|
||||
typedef khronos_int32_t EGLint;
|
||||
|
||||
|
||||
/* C++ / C typecast macros for special EGL handle values */
|
||||
#if defined(__cplusplus)
|
||||
#define EGL_CAST(type, value) (static_cast<type>(value))
|
||||
#else
|
||||
#define EGL_CAST(type, value) ((type) (value))
|
||||
#endif
|
||||
|
||||
#endif /* __eglplatform_h */
|
|
@ -1,675 +0,0 @@
|
|||
#ifndef __gl2_h_
|
||||
#define __gl2_h_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013-2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
/*
|
||||
** This header is generated from the Khronos OpenGL / OpenGL ES XML
|
||||
** API Registry. The current version of the Registry, generator scripts
|
||||
** used to make the header, and the header can be found at
|
||||
** https://github.com/KhronosGroup/OpenGL-Registry
|
||||
*/
|
||||
|
||||
#include <GLES2/gl2platform.h>
|
||||
|
||||
#ifndef GL_APIENTRYP
|
||||
#define GL_APIENTRYP GL_APIENTRY*
|
||||
#endif
|
||||
|
||||
#ifndef GL_GLES_PROTOTYPES
|
||||
#define GL_GLES_PROTOTYPES 1
|
||||
#endif
|
||||
|
||||
/* Generated on date 20170325 */
|
||||
|
||||
/* Generated C header for:
|
||||
* API: gles2
|
||||
* Profile: common
|
||||
* Versions considered: 2\.[0-9]
|
||||
* Versions emitted: .*
|
||||
* Default extensions included: None
|
||||
* Additional extensions included: _nomatch_^
|
||||
* Extensions removed: _nomatch_^
|
||||
*/
|
||||
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
#define GL_ES_VERSION_2_0 1
|
||||
#include <KHR/khrplatform.h>
|
||||
typedef khronos_int8_t GLbyte;
|
||||
typedef khronos_float_t GLclampf;
|
||||
typedef khronos_int32_t GLfixed;
|
||||
typedef short GLshort;
|
||||
typedef unsigned short GLushort;
|
||||
typedef void GLvoid;
|
||||
typedef struct __GLsync *GLsync;
|
||||
typedef khronos_int64_t GLint64;
|
||||
typedef khronos_uint64_t GLuint64;
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned int GLuint;
|
||||
typedef char GLchar;
|
||||
typedef khronos_float_t GLfloat;
|
||||
typedef khronos_ssize_t GLsizeiptr;
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef int GLint;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef int GLsizei;
|
||||
typedef khronos_uint8_t GLubyte;
|
||||
#define GL_DEPTH_BUFFER_BIT 0x00000100
|
||||
#define GL_STENCIL_BUFFER_BIT 0x00000400
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
#define GL_FALSE 0
|
||||
#define GL_TRUE 1
|
||||
#define GL_POINTS 0x0000
|
||||
#define GL_LINES 0x0001
|
||||
#define GL_LINE_LOOP 0x0002
|
||||
#define GL_LINE_STRIP 0x0003
|
||||
#define GL_TRIANGLES 0x0004
|
||||
#define GL_TRIANGLE_STRIP 0x0005
|
||||
#define GL_TRIANGLE_FAN 0x0006
|
||||
#define GL_ZERO 0
|
||||
#define GL_ONE 1
|
||||
#define GL_SRC_COLOR 0x0300
|
||||
#define GL_ONE_MINUS_SRC_COLOR 0x0301
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_DST_ALPHA 0x0304
|
||||
#define GL_ONE_MINUS_DST_ALPHA 0x0305
|
||||
#define GL_DST_COLOR 0x0306
|
||||
#define GL_ONE_MINUS_DST_COLOR 0x0307
|
||||
#define GL_SRC_ALPHA_SATURATE 0x0308
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
#define GL_BLEND_EQUATION 0x8009
|
||||
#define GL_BLEND_EQUATION_RGB 0x8009
|
||||
#define GL_BLEND_EQUATION_ALPHA 0x883D
|
||||
#define GL_FUNC_SUBTRACT 0x800A
|
||||
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
|
||||
#define GL_BLEND_DST_RGB 0x80C8
|
||||
#define GL_BLEND_SRC_RGB 0x80C9
|
||||
#define GL_BLEND_DST_ALPHA 0x80CA
|
||||
#define GL_BLEND_SRC_ALPHA 0x80CB
|
||||
#define GL_CONSTANT_COLOR 0x8001
|
||||
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
|
||||
#define GL_CONSTANT_ALPHA 0x8003
|
||||
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
|
||||
#define GL_BLEND_COLOR 0x8005
|
||||
#define GL_ARRAY_BUFFER 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
|
||||
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
|
||||
#define GL_STREAM_DRAW 0x88E0
|
||||
#define GL_STATIC_DRAW 0x88E4
|
||||
#define GL_DYNAMIC_DRAW 0x88E8
|
||||
#define GL_BUFFER_SIZE 0x8764
|
||||
#define GL_BUFFER_USAGE 0x8765
|
||||
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
#define GL_FRONT_AND_BACK 0x0408
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
#define GL_BLEND 0x0BE2
|
||||
#define GL_DITHER 0x0BD0
|
||||
#define GL_STENCIL_TEST 0x0B90
|
||||
#define GL_DEPTH_TEST 0x0B71
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
#define GL_POLYGON_OFFSET_FILL 0x8037
|
||||
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
|
||||
#define GL_SAMPLE_COVERAGE 0x80A0
|
||||
#define GL_NO_ERROR 0
|
||||
#define GL_INVALID_ENUM 0x0500
|
||||
#define GL_INVALID_VALUE 0x0501
|
||||
#define GL_INVALID_OPERATION 0x0502
|
||||
#define GL_OUT_OF_MEMORY 0x0505
|
||||
#define GL_CW 0x0900
|
||||
#define GL_CCW 0x0901
|
||||
#define GL_LINE_WIDTH 0x0B21
|
||||
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
|
||||
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
|
||||
#define GL_CULL_FACE_MODE 0x0B45
|
||||
#define GL_FRONT_FACE 0x0B46
|
||||
#define GL_DEPTH_RANGE 0x0B70
|
||||
#define GL_DEPTH_WRITEMASK 0x0B72
|
||||
#define GL_DEPTH_CLEAR_VALUE 0x0B73
|
||||
#define GL_DEPTH_FUNC 0x0B74
|
||||
#define GL_STENCIL_CLEAR_VALUE 0x0B91
|
||||
#define GL_STENCIL_FUNC 0x0B92
|
||||
#define GL_STENCIL_FAIL 0x0B94
|
||||
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
|
||||
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
|
||||
#define GL_STENCIL_REF 0x0B97
|
||||
#define GL_STENCIL_VALUE_MASK 0x0B93
|
||||
#define GL_STENCIL_WRITEMASK 0x0B98
|
||||
#define GL_STENCIL_BACK_FUNC 0x8800
|
||||
#define GL_STENCIL_BACK_FAIL 0x8801
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
|
||||
#define GL_STENCIL_BACK_REF 0x8CA3
|
||||
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
|
||||
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
|
||||
#define GL_VIEWPORT 0x0BA2
|
||||
#define GL_SCISSOR_BOX 0x0C10
|
||||
#define GL_COLOR_CLEAR_VALUE 0x0C22
|
||||
#define GL_COLOR_WRITEMASK 0x0C23
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
|
||||
#define GL_SUBPIXEL_BITS 0x0D50
|
||||
#define GL_RED_BITS 0x0D52
|
||||
#define GL_GREEN_BITS 0x0D53
|
||||
#define GL_BLUE_BITS 0x0D54
|
||||
#define GL_ALPHA_BITS 0x0D55
|
||||
#define GL_DEPTH_BITS 0x0D56
|
||||
#define GL_STENCIL_BITS 0x0D57
|
||||
#define GL_POLYGON_OFFSET_UNITS 0x2A00
|
||||
#define GL_POLYGON_OFFSET_FACTOR 0x8038
|
||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||
#define GL_SAMPLE_BUFFERS 0x80A8
|
||||
#define GL_SAMPLES 0x80A9
|
||||
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
|
||||
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
|
||||
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
|
||||
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
|
||||
#define GL_DONT_CARE 0x1100
|
||||
#define GL_FASTEST 0x1101
|
||||
#define GL_NICEST 0x1102
|
||||
#define GL_GENERATE_MIPMAP_HINT 0x8192
|
||||
#define GL_BYTE 0x1400
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_SHORT 0x1402
|
||||
#define GL_UNSIGNED_SHORT 0x1403
|
||||
#define GL_INT 0x1404
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
#define GL_FIXED 0x140C
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
#define GL_ALPHA 0x1906
|
||||
#define GL_RGB 0x1907
|
||||
#define GL_RGBA 0x1908
|
||||
#define GL_LUMINANCE 0x1909
|
||||
#define GL_LUMINANCE_ALPHA 0x190A
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
|
||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_MAX_VERTEX_ATTRIBS 0x8869
|
||||
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
|
||||
#define GL_MAX_VARYING_VECTORS 0x8DFC
|
||||
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
|
||||
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
|
||||
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
|
||||
#define GL_SHADER_TYPE 0x8B4F
|
||||
#define GL_DELETE_STATUS 0x8B80
|
||||
#define GL_LINK_STATUS 0x8B82
|
||||
#define GL_VALIDATE_STATUS 0x8B83
|
||||
#define GL_ATTACHED_SHADERS 0x8B85
|
||||
#define GL_ACTIVE_UNIFORMS 0x8B86
|
||||
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
|
||||
#define GL_ACTIVE_ATTRIBUTES 0x8B89
|
||||
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||
#define GL_NEVER 0x0200
|
||||
#define GL_LESS 0x0201
|
||||
#define GL_EQUAL 0x0202
|
||||
#define GL_LEQUAL 0x0203
|
||||
#define GL_GREATER 0x0204
|
||||
#define GL_NOTEQUAL 0x0205
|
||||
#define GL_GEQUAL 0x0206
|
||||
#define GL_ALWAYS 0x0207
|
||||
#define GL_KEEP 0x1E00
|
||||
#define GL_REPLACE 0x1E01
|
||||
#define GL_INCR 0x1E02
|
||||
#define GL_DECR 0x1E03
|
||||
#define GL_INVERT 0x150A
|
||||
#define GL_INCR_WRAP 0x8507
|
||||
#define GL_DECR_WRAP 0x8508
|
||||
#define GL_VENDOR 0x1F00
|
||||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#define GL_NEAREST 0x2600
|
||||
#define GL_LINEAR 0x2601
|
||||
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
|
||||
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
|
||||
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
|
||||
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
#define GL_TEXTURE 0x1702
|
||||
#define GL_TEXTURE_CUBE_MAP 0x8513
|
||||
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
|
||||
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_TEXTURE1 0x84C1
|
||||
#define GL_TEXTURE2 0x84C2
|
||||
#define GL_TEXTURE3 0x84C3
|
||||
#define GL_TEXTURE4 0x84C4
|
||||
#define GL_TEXTURE5 0x84C5
|
||||
#define GL_TEXTURE6 0x84C6
|
||||
#define GL_TEXTURE7 0x84C7
|
||||
#define GL_TEXTURE8 0x84C8
|
||||
#define GL_TEXTURE9 0x84C9
|
||||
#define GL_TEXTURE10 0x84CA
|
||||
#define GL_TEXTURE11 0x84CB
|
||||
#define GL_TEXTURE12 0x84CC
|
||||
#define GL_TEXTURE13 0x84CD
|
||||
#define GL_TEXTURE14 0x84CE
|
||||
#define GL_TEXTURE15 0x84CF
|
||||
#define GL_TEXTURE16 0x84D0
|
||||
#define GL_TEXTURE17 0x84D1
|
||||
#define GL_TEXTURE18 0x84D2
|
||||
#define GL_TEXTURE19 0x84D3
|
||||
#define GL_TEXTURE20 0x84D4
|
||||
#define GL_TEXTURE21 0x84D5
|
||||
#define GL_TEXTURE22 0x84D6
|
||||
#define GL_TEXTURE23 0x84D7
|
||||
#define GL_TEXTURE24 0x84D8
|
||||
#define GL_TEXTURE25 0x84D9
|
||||
#define GL_TEXTURE26 0x84DA
|
||||
#define GL_TEXTURE27 0x84DB
|
||||
#define GL_TEXTURE28 0x84DC
|
||||
#define GL_TEXTURE29 0x84DD
|
||||
#define GL_TEXTURE30 0x84DE
|
||||
#define GL_TEXTURE31 0x84DF
|
||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||
#define GL_REPEAT 0x2901
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#define GL_MIRRORED_REPEAT 0x8370
|
||||
#define GL_FLOAT_VEC2 0x8B50
|
||||
#define GL_FLOAT_VEC3 0x8B51
|
||||
#define GL_FLOAT_VEC4 0x8B52
|
||||
#define GL_INT_VEC2 0x8B53
|
||||
#define GL_INT_VEC3 0x8B54
|
||||
#define GL_INT_VEC4 0x8B55
|
||||
#define GL_BOOL 0x8B56
|
||||
#define GL_BOOL_VEC2 0x8B57
|
||||
#define GL_BOOL_VEC3 0x8B58
|
||||
#define GL_BOOL_VEC4 0x8B59
|
||||
#define GL_FLOAT_MAT2 0x8B5A
|
||||
#define GL_FLOAT_MAT3 0x8B5B
|
||||
#define GL_FLOAT_MAT4 0x8B5C
|
||||
#define GL_SAMPLER_2D 0x8B5E
|
||||
#define GL_SAMPLER_CUBE 0x8B60
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
|
||||
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
|
||||
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
|
||||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_SHADER_SOURCE_LENGTH 0x8B88
|
||||
#define GL_SHADER_COMPILER 0x8DFA
|
||||
#define GL_SHADER_BINARY_FORMATS 0x8DF8
|
||||
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
|
||||
#define GL_LOW_FLOAT 0x8DF0
|
||||
#define GL_MEDIUM_FLOAT 0x8DF1
|
||||
#define GL_HIGH_FLOAT 0x8DF2
|
||||
#define GL_LOW_INT 0x8DF3
|
||||
#define GL_MEDIUM_INT 0x8DF4
|
||||
#define GL_HIGH_INT 0x8DF5
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
#define GL_RENDERBUFFER 0x8D41
|
||||
#define GL_RGBA4 0x8056
|
||||
#define GL_RGB5_A1 0x8057
|
||||
#define GL_RGB565 0x8D62
|
||||
#define GL_DEPTH_COMPONENT16 0x81A5
|
||||
#define GL_STENCIL_INDEX8 0x8D48
|
||||
#define GL_RENDERBUFFER_WIDTH 0x8D42
|
||||
#define GL_RENDERBUFFER_HEIGHT 0x8D43
|
||||
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
|
||||
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
|
||||
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
|
||||
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
|
||||
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
|
||||
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
|
||||
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
|
||||
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||
#define GL_DEPTH_ATTACHMENT 0x8D00
|
||||
#define GL_STENCIL_ATTACHMENT 0x8D20
|
||||
#define GL_NONE 0
|
||||
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
|
||||
#define GL_FRAMEBUFFER_BINDING 0x8CA6
|
||||
#define GL_RENDERBUFFER_BINDING 0x8CA7
|
||||
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
|
||||
typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
|
||||
typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
|
||||
typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
|
||||
typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
|
||||
typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
|
||||
typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
|
||||
typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
|
||||
typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
|
||||
typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
|
||||
typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
|
||||
typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||
typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
|
||||
typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
|
||||
typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
|
||||
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
|
||||
typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
|
||||
typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
|
||||
typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
|
||||
typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
|
||||
typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
|
||||
typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
|
||||
typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
|
||||
typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
|
||||
typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
|
||||
typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
|
||||
typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
|
||||
typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
|
||||
typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
|
||||
typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
|
||||
typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
|
||||
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||
typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
|
||||
typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
|
||||
typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
|
||||
typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
|
||||
typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
|
||||
typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
|
||||
typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
|
||||
typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
|
||||
typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
|
||||
typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
|
||||
typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
|
||||
typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
|
||||
typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
|
||||
typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
|
||||
typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
|
||||
typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
|
||||
typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
|
||||
typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
|
||||
typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
|
||||
typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
|
||||
typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
|
||||
typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
|
||||
typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
|
||||
typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
|
||||
typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
|
||||
typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
|
||||
typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
|
||||
typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
|
||||
typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
|
||||
typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
|
||||
typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
|
||||
typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
|
||||
typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
|
||||
typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||
typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
|
||||
typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
|
||||
typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
|
||||
typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
|
||||
typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
|
||||
typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
|
||||
typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
|
||||
typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||
typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
#if GL_GLES_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
|
||||
GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
|
||||
GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
|
||||
GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
|
||||
GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
|
||||
GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
|
||||
GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
|
||||
GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
|
||||
GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
|
||||
GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||
GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
|
||||
GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
|
||||
GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
|
||||
GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
|
||||
GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
|
||||
GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
|
||||
GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
|
||||
GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
|
||||
GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
|
||||
GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
|
||||
GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
|
||||
GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
|
||||
GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
|
||||
GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
|
||||
GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
|
||||
GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
|
||||
GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
|
||||
GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
|
||||
GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
|
||||
GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||
GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
|
||||
GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
|
||||
GL_APICALL void GL_APIENTRY glFinish (void);
|
||||
GL_APICALL void GL_APIENTRY glFlush (void);
|
||||
GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
|
||||
GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
|
||||
GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
|
||||
GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
|
||||
GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
|
||||
GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
|
||||
GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
|
||||
GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
|
||||
GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
|
||||
GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
|
||||
GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
|
||||
GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
|
||||
GL_APICALL GLenum GL_APIENTRY glGetError (void);
|
||||
GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
|
||||
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
|
||||
GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
|
||||
GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
|
||||
GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
|
||||
GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
|
||||
GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
|
||||
GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
|
||||
GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
|
||||
GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
|
||||
GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
|
||||
GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
|
||||
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||
GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
|
||||
GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
|
||||
GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
|
||||
GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
|
||||
GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
|
||||
GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
|
||||
GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
|
||||
GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
|
||||
GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
|
||||
GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
|
||||
GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
|
||||
GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
|
||||
GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
||||
GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
|
||||
GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
|
||||
GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
|
||||
GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
#endif
|
||||
#endif /* GL_ES_VERSION_2_0 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,551 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2017 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.
|
||||
//
|
||||
// gl2ext_angle.h: ANGLE modifications to the gl2ext.h header file.
|
||||
// Currently we don't include this file directly, we patch gl2ext.h
|
||||
// to include it implicitly so it is visible throughout our code.
|
||||
|
||||
#ifndef INCLUDE_GLES2_GL2EXT_ANGLE_H_
|
||||
#define INCLUDE_GLES2_GL2EXT_ANGLE_H_
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef GL_ANGLE_client_arrays
|
||||
#define GL_ANGLE_client_arrays 1
|
||||
#define GL_CLIENT_ARRAYS_ANGLE 0x93AA
|
||||
#endif /* GL_ANGLE_client_arrays */
|
||||
|
||||
#ifndef GL_ANGLE_request_extension
|
||||
#define GL_ANGLE_request_extension 1
|
||||
#define GL_REQUESTABLE_EXTENSIONS_ANGLE 0x93A8
|
||||
#define GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE 0x93A8
|
||||
typedef void (GL_APIENTRYP PFNGLREQUESTEXTENSIONANGLEPROC) (const GLchar *name);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glRequestExtensionANGLE (const GLchar *name);
|
||||
#endif
|
||||
#endif /* GL_ANGLE_webgl_compatibility */
|
||||
|
||||
#ifndef GL_ANGLE_robust_resource_initialization
|
||||
#define GL_ANGLE_robust_resource_initialization 1
|
||||
#define GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93AB
|
||||
#endif /* GL_ANGLE_robust_resource_initialization */
|
||||
|
||||
#ifndef GL_CHROMIUM_framebuffer_mixed_samples
|
||||
#define GL_CHROMIUM_frambuffer_mixed_samples 1
|
||||
#define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
|
||||
typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONCHROMIUMPROC) (GLenum components);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
|
||||
#endif
|
||||
#endif /* GL_CHROMIUM_framebuffer_mixed_samples */
|
||||
|
||||
#ifndef GL_CHROMIUM_bind_generates_resource
|
||||
#define GL_CHROMIUM_bind_generates_resource 1
|
||||
#define GL_BIND_GENERATES_RESOURCE_CHROMIUM 0x9244
|
||||
#endif /* GL_CHROMIUM_bind_generates_resource */
|
||||
|
||||
// needed by NV_path_rendering (and thus CHROMIUM_path_rendering)
|
||||
// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
|
||||
#ifndef GL_EXT_direct_state_access
|
||||
#define GL_EXT_direct_state_access 1
|
||||
typedef void(GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC)(GLenum matrixMode, const GLfloat *m);
|
||||
typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC)(GLenum matrixMode);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glMatrixLoadfEXT(GLenum matrixMode, const GLfloat *m);
|
||||
GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT(GLenum matrixMode);
|
||||
#endif
|
||||
#endif /* GL_EXT_direct_state_access */
|
||||
|
||||
#ifndef GL_CHROMIUM_path_rendering
|
||||
#define GL_CHROMIUM_path_rendering 1
|
||||
#define GL_PATH_MODELVIEW_CHROMIUM 0x1700
|
||||
#define GL_PATH_PROJECTION_CHROMIUM 0x1701
|
||||
#define GL_CLOSE_PATH_CHROMIUM 0x00
|
||||
#define GL_MOVE_TO_CHROMIUM 0x02
|
||||
#define GL_LINE_TO_CHROMIUM 0x04
|
||||
#define GL_QUADRATIC_CURVE_TO_CHROMIUM 0x0A
|
||||
#define GL_CUBIC_CURVE_TO_CHROMIUM 0x0C
|
||||
#define GL_CONIC_CURVE_TO_CHROMIUM 0x1A
|
||||
#define GL_PATH_MODELVIEW_MATRIX_CHROMIUM 0x0BA6
|
||||
#define GL_PATH_PROJECTION_MATRIX_CHROMIUM 0x0BA7
|
||||
#define GL_PATH_STROKE_WIDTH_CHROMIUM 0x9075
|
||||
#define GL_PATH_END_CAPS_CHROMIUM 0x9076
|
||||
#define GL_PATH_JOIN_STYLE_CHROMIUM 0x9079
|
||||
#define GL_PATH_MITER_LIMIT_CHROMIUM 0x907a
|
||||
#define GL_PATH_STROKE_BOUND_CHROMIUM 0x9086
|
||||
#define GL_FLAT_CHROMIUM 0x1D00
|
||||
#define GL_SQUARE_CHROMIUM 0x90a3
|
||||
#define GL_ROUND_CHROMIUM 0x90a4
|
||||
#define GL_BEVEL_CHROMIUM 0x90A6
|
||||
#define GL_MITER_REVERT_CHROMIUM 0x90A7
|
||||
#define GL_COUNT_UP_CHROMIUM 0x9088
|
||||
#define GL_COUNT_DOWN_CHROMIUM 0x9089
|
||||
#define GL_CONVEX_HULL_CHROMIUM 0x908B
|
||||
#define GL_BOUNDING_BOX_CHROMIUM 0x908D
|
||||
#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM 0x909C
|
||||
#define GL_EYE_LINEAR_CHROMIUM 0x2400
|
||||
#define GL_OBJECT_LINEAR_CHROMIUM 0x2401
|
||||
#define GL_CONSTANT_CHROMIUM 0x8576
|
||||
#define GL_TRANSLATE_X_CHROMIUM 0x908E
|
||||
#define GL_TRANSLATE_Y_CHROMIUM 0x908F
|
||||
#define GL_TRANSLATE_2D_CHROMIUM 0x9090
|
||||
#define GL_TRANSLATE_3D_CHROMIUM 0x9091
|
||||
#define GL_AFFINE_2D_CHROMIUM 0x9092
|
||||
#define GL_AFFINE_3D_CHROMIUM 0x9094
|
||||
#define GL_TRANSPOSE_AFFINE_2D_CHROMIUM 0x9096
|
||||
#define GL_TRANSPOSE_AFFINE_3D_CHROMIUM 0x9098
|
||||
typedef void(GL_APIENTRYP PFNGLMATRIXLOADFCHROMIUMPROC)(GLenum matrixMode, const GLfloat *m);
|
||||
typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYCHROMIUMPROC)(GLenum matrixMode);
|
||||
typedef GLuint(GL_APIENTRYP PFNGLGENPATHSCHROMIUMPROC)(GLsizei range);
|
||||
typedef void(GL_APIENTRYP PFNGLDELETEPATHSCHROMIUMPROC)(GLuint path, GLsizei range);
|
||||
typedef GLboolean(GL_APIENTRYP PFNGLISPATHCHROMIUMPROC)(GLuint path);
|
||||
typedef void(GL_APIENTRYP PFNGLPATHCOMMANDSCHROMIUMPROC)(GLuint path,
|
||||
GLsizei numCommands,
|
||||
const GLubyte *commands,
|
||||
GLsizei numCoords,
|
||||
GLenum coordType,
|
||||
const void *coords);
|
||||
typedef void(GL_APIENTRYP PFNGLPATHPARAMETERICHROMIUMPROC)(GLuint path, GLenum pname, GLint value);
|
||||
typedef void(GL_APIENTRYP PFNGLPATHPARAMETERFCHROMIUMPROC)(GLuint path,
|
||||
GLenum pname,
|
||||
GLfloat value);
|
||||
typedef void(GL_APIENTRYP PFNGLGETPATHPARAMETERIVCHROMIUMPROC)(GLuint path,
|
||||
GLenum pname,
|
||||
GLint *value);
|
||||
typedef void(GL_APIENTRYP PFNGLGETPATHPARAMETERFVCHROMIUMPROC)(GLuint path,
|
||||
GLenum pname,
|
||||
GLfloat *value);
|
||||
typedef void(GL_APIENTRYP PFNGLPATHSTENCILFUNCCHROMIUMPROC)(GLenum func, GLint ref, GLuint mask);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILFILLPATHCHROMIUMPROC)(GLuint path,
|
||||
GLenum fillMode,
|
||||
GLuint mask);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILSTROKEPATHCHROMIUMPROC)(GLuint path,
|
||||
GLint reference,
|
||||
GLuint mask);
|
||||
typedef void(GL_APIENTRYP PFNGLCOVERFILLPATHCHROMIUMPROC)(GLuint path, GLenum coverMode);
|
||||
typedef void(GL_APIENTRYP PFNGLCOVERSTROKEPATHCHROMIUMPROC)(GLuint path, GLenum coverMode);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHCHROMIUMPROC)(GLuint path,
|
||||
GLenum fillMode,
|
||||
GLuint mask,
|
||||
GLenum coverMode);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHCHROMIUMPROC)(GLuint path,
|
||||
GLint reference,
|
||||
GLuint mask,
|
||||
GLenum coverMode);
|
||||
typedef void(GL_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDCHROMIUMPROC)(GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
typedef void(GL_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDCHROMIUMPROC)(
|
||||
GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDCHROMIUMPROC)(
|
||||
GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum fillMode,
|
||||
GLuint mask,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDCHROMIUMPROC)(
|
||||
GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLint reference,
|
||||
GLuint mask,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDCHROMIUMPROC)(
|
||||
GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum fillMode,
|
||||
GLuint mask,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDCHROMIUMPROC)(
|
||||
GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLint reference,
|
||||
GLuint mask,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
|
||||
typedef void(GL_APIENTRY PFNGLBINDFRAGMENTINPUTLOCATIONCHROMIUMPROC)(GLuint program,
|
||||
GLint location,
|
||||
const GLchar *name);
|
||||
typedef void(GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENCHROMIUMPROC)(GLuint program,
|
||||
GLint location,
|
||||
GLenum genMode,
|
||||
GLint components,
|
||||
const GLfloat *coeffs);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glMatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *m);
|
||||
GL_APICALL void GL_APIENTRY glMatrixLoadIdentityCHROMIUM(GLenum matrixMode);
|
||||
GL_APICALL GLuint GL_APIENTRY glGenPathsCHROMIUM(GLsizei range);
|
||||
GL_APICALL void GL_APIENTRY glDeletePathsCHROMIUM(GLuint path, GLsizei range);
|
||||
GL_APICALL GLboolean GL_APIENTRY glIsPathCHROMIUM(GLuint path);
|
||||
GL_APICALL void GL_APIENTRY glPathCommandsCHROMIUM(GLuint path,
|
||||
GLsizei numCommands,
|
||||
const GLubyte *commands,
|
||||
GLsizei numCoords,
|
||||
GLenum coordType,
|
||||
const void *coords);
|
||||
GL_APICALL void GL_APIENTRY glPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value);
|
||||
GL_APICALL void GL_APIENTRY glPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value);
|
||||
GL_APICALL void GL_APIENTRY glGetPathParameterivCHROMIUM(GLuint path, GLenum pname, GLint *value);
|
||||
GL_APICALL void GL_APIENTRY glGetPathParameterfvCHROMIUM(GLuint path, GLenum pname, GLfloat *value);
|
||||
GL_APICALL void GL_APIENTRY glPathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glStencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask);
|
||||
GL_APICALL void GL_APIENTRY glCoverFillPathCHROMIUM(GLuint path, GLenum coverMode);
|
||||
GL_APICALL void GL_APIENTRY glCoverStrokePathCHROMIUM(GLuint path, GLenum coverMode);
|
||||
GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathCHROMIUM(GLuint path,
|
||||
GLenum fillMode,
|
||||
GLuint mask,
|
||||
GLenum coverMode);
|
||||
GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathCHROMIUM(GLuint path,
|
||||
GLint reference,
|
||||
GLuint mask,
|
||||
GLenum coverMode);
|
||||
GL_APICALL void GL_APIENTRY glCoverFillPathInstancedCHROMIUM(GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
GL_APICALL void GL_APIENTRY glCoverStrokePathInstancedCHROMIUM(GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
GL_APICALL void GL_APIENTRY glStencilFillPathInstancedCHROMIUM(GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum fillMode,
|
||||
GLuint mask,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
GL_APICALL void GL_APIENTRY glStencilStrokePathInstancedCHROMIUM(GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLint reference,
|
||||
GLuint mask,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
GL_APICALL void GL_APIENTRY
|
||||
glStencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLenum fillMode,
|
||||
GLuint mask,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
|
||||
GL_APICALL void GL_APIENTRY
|
||||
glStencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths,
|
||||
GLenum pathNameType,
|
||||
const void *paths,
|
||||
GLuint pathBase,
|
||||
GLint reference,
|
||||
GLuint mask,
|
||||
GLenum coverMode,
|
||||
GLenum transformType,
|
||||
const GLfloat *transformValues);
|
||||
|
||||
GL_APICALL void GL_APIENTRY glBindFragmentInputLocationCHROMIUM(GLuint program,
|
||||
GLint location,
|
||||
const GLchar *name);
|
||||
GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenCHROMIUM(GLuint program,
|
||||
GLint location,
|
||||
GLenum genMode,
|
||||
GLint components,
|
||||
const GLfloat *coeffs);
|
||||
|
||||
#endif
|
||||
#endif /* GL_CHROMIUM_path_rendering */
|
||||
|
||||
#ifndef GL_CHROMIUM_copy_texture
|
||||
#define GL_CHROMIUM_copy_texture 1
|
||||
typedef void(GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUMPROC)(GLuint sourceId,
|
||||
GLint sourceLevel,
|
||||
GLenum destTarget,
|
||||
GLuint destId,
|
||||
GLint destLevel,
|
||||
GLint internalFormat,
|
||||
GLenum destType,
|
||||
GLboolean unpackFlipY,
|
||||
GLboolean unpackPremultiplyAlpha,
|
||||
GLboolean unpackUnmultiplyAlpha);
|
||||
typedef void(GL_APIENTRYP PFNGLCOPYSUBTEXTURECHROMIUMPROC)(GLuint sourceId,
|
||||
GLint sourceLevel,
|
||||
GLenum destTarget,
|
||||
GLuint destId,
|
||||
GLint destLevel,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLboolean unpackFlipY,
|
||||
GLboolean unpackPremultiplyAlpha,
|
||||
GLboolean unpackUnmultiplyAlpha);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM(GLuint sourceId,
|
||||
GLint sourceLevel,
|
||||
GLenum destTarget,
|
||||
GLuint destId,
|
||||
GLint destLevel,
|
||||
GLint internalFormat,
|
||||
GLenum destType,
|
||||
GLboolean unpackFlipY,
|
||||
GLboolean unpackPremultiplyAlpha,
|
||||
GLboolean unpackUnmultiplyAlpha);
|
||||
GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM(GLuint sourceId,
|
||||
GLint sourceLevel,
|
||||
GLenum destTarget,
|
||||
GLuint destId,
|
||||
GLint destLevel,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint x,
|
||||
GLint y,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLboolean unpackFlipY,
|
||||
GLboolean unpackPremultiplyAlpha,
|
||||
GLboolean unpackUnmultiplyAlpha);
|
||||
#endif
|
||||
#endif /* GL_CHROMIUM_copy_texture */
|
||||
|
||||
#ifndef GL_CHROMIUM_compressed_copy_texture
|
||||
#define GL_CHROMIUM_compressed_copy_texture 1
|
||||
typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC)(GLuint sourceId, GLuint destId);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
|
||||
#endif
|
||||
#endif /* GL_CHROMIUM_compressed_copy_texture */
|
||||
|
||||
#ifndef GL_CHROMIUM_sync_query
|
||||
#define GL_CHROMIUM_sync_query 1
|
||||
#define GL_COMMANDS_COMPLETED_CHROMIUM 0x84F7
|
||||
#endif /* GL_CHROMIUM_sync_query */
|
||||
|
||||
#ifndef GL_EXT_texture_compression_s3tc_srgb
|
||||
#define GL_EXT_texture_compression_s3tc_srgb 1
|
||||
#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
|
||||
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
|
||||
#endif /* GL_EXT_texture_compression_s3tc_srgb */
|
||||
|
||||
#ifndef GL_ANGLE_lossy_etc_decode
|
||||
#define GL_ANGLE_lossy_etc_decode 1
|
||||
#define GL_ETC1_RGB8_LOSSY_DECODE_ANGLE 0x9690
|
||||
#define GL_COMPRESSED_R11_LOSSY_DECODE_EAC_ANGLE 0x9691
|
||||
#define GL_COMPRESSED_SIGNED_R11_LOSSY_DECODE_EAC_ANGLE 0x9692
|
||||
#define GL_COMPRESSED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9693
|
||||
#define GL_COMPRESSED_SIGNED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9694
|
||||
#define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE 0x9695
|
||||
#define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE 0x9696
|
||||
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9697
|
||||
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9698
|
||||
#define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x9699
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A
|
||||
#endif /* GL_ANGLE_lossy_etc_decode */
|
||||
|
||||
#ifndef GL_ANGLE_robust_client_memory
|
||||
#define GL_ANGLE_robust_client_memory 1
|
||||
typedef void (GL_APIENTRYP PFNGLGETBOOLEANVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETFLOATVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVROBUSTANGLE) (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETINTEGERVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVROBUSTANGLE) (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSHADERIVROBUSTANGLE) (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
|
||||
typedef void (GL_APIENTRYP PFNGLREADPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETQUERYIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVROBUSTANGLE) (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
|
||||
typedef void (GL_APIENTRYP PFNGETINTERNALFORMATIVROBUSTANGLE) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVROBUSTANGLE) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETINTEGER64VROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVROBUSTANGLE) (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVROBUSTANGLE) (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETPOINTERVROBUSTANGLEROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
||||
typedef void (GL_APIENTRYP PFNGLREADNPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *data);
|
||||
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
||||
typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
||||
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glGetBooleanvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
||||
GL_APICALL void GL_APIENTRY glGetBufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetFloatvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
|
||||
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivRobustANGLE (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetIntegervRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
|
||||
GL_APICALL void GL_APIENTRY glGetProgramivRobustANGLE (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetShaderivRobustANGLE (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribfvRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribPointervRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
|
||||
GL_APICALL void GL_APIENTRY glReadPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glTexImage2DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glTexSubImage2DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glTexImage3DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glTexSubImage3DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexImage2DRobustANGLE(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexSubImage2DRobustANGLE(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexImage3DRobustANGLE(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DRobustANGLE(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data);
|
||||
GL_APICALL void GL_APIENTRY glGetQueryivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetQueryObjectuivRobustANGLE (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetBufferPointervRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
||||
GL_APICALL void GL_APIENTRY glGetIntegeri_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
|
||||
GL_APICALL void GL_APIENTRY glGetInternalformativRobustANGLE (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribIivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetVertexAttribIuivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetActiveUniformBlockivRobustANGLE (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetInteger64vRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
||||
GL_APICALL void GL_APIENTRY glGetInteger64i_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
|
||||
GL_APICALL void GL_APIENTRY glGetBufferParameteri64vRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
||||
GL_APICALL void GL_APIENTRY glSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
||||
GL_APICALL void GL_APIENTRY glSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
|
||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetFramebufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetProgramInterfaceivRobustANGLE (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetBooleani_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
|
||||
GL_APICALL void GL_APIENTRY glGetMultisamplefvRobustANGLE (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
|
||||
GL_APICALL void GL_APIENTRY glGetTexLevelParameterivRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetTexLevelParameterfvRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetPointervRobustANGLERobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
|
||||
GL_APICALL void GL_APIENTRY glReadnPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *data);
|
||||
GL_APICALL void GL_APIENTRY glGetnUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
|
||||
GL_APICALL void GL_APIENTRY glGetnUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetnUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
GL_APICALL void GL_APIENTRY glSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
|
||||
GL_APICALL void GL_APIENTRY glSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
|
||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetQueryObjectivRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
|
||||
GL_APICALL void GL_APIENTRY glGetQueryObjecti64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
|
||||
GL_APICALL void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
|
||||
#endif
|
||||
#endif /* GL_ANGLE_robust_client_memory */
|
||||
|
||||
#ifndef GL_ANGLE_program_cache_control
|
||||
#define GL_ANGLE_program_cache_control 1
|
||||
#define GL_PROGRAM_CACHE_ENABLED_ANGLE 0x93AC
|
||||
#endif /* GL_ANGLE_program_cache_control */
|
||||
|
||||
#ifndef GL_ANGLE_multiview
|
||||
#define GL_ANGLE_multiview 1
|
||||
// The next four enums coincide with the enums introduced by the GL_OVR_multiview extension and use the values reserved by that extension.
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE 0x9630
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE 0x9632
|
||||
#define GL_MAX_VIEWS_ANGLE 0x9631
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE 0x9633
|
||||
// The next four enums are reserved specifically for ANGLE.
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE 0x969B
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE 0x969C
|
||||
#define GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE 0x969D
|
||||
#define GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE 0x969E
|
||||
typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWLAYEREDANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
|
||||
typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWSIDEBYSIDEANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewLayeredANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
|
||||
GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets);
|
||||
#endif
|
||||
#endif /* GL_ANGLE_multiview */
|
||||
|
||||
#ifndef GL_ANGLE_texture_rectangle
|
||||
#define GL_ANGLE_texture_rectangle 1
|
||||
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE 0x84F8
|
||||
#define GL_TEXTURE_RECTANGLE_ANGLE 0x84F5
|
||||
#define GL_TEXTURE_BINDING_RECTANGLE_ANGLE 0x84F6
|
||||
#define GL_SAMPLER_2D_RECT_ANGLE 0x8B63
|
||||
#endif /* GL_ANGLE_texture_rectangle */
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // INCLUDE_GLES2_GL2EXT_ANGLE_H_
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef __gl2platform_h_
|
||||
#define __gl2platform_h_
|
||||
|
||||
/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */
|
||||
|
||||
/*
|
||||
* This document is licensed under the SGI Free Software B License Version
|
||||
* 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "OpenGL-ES" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
#ifndef GL_APICALL
|
||||
#define GL_APICALL KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef GL_APIENTRY
|
||||
#define GL_APIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
#endif /* __gl2platform_h_ */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,30 +0,0 @@
|
|||
#ifndef __gl3platform_h_
|
||||
#define __gl3platform_h_
|
||||
|
||||
/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */
|
||||
|
||||
/*
|
||||
* This document is licensed under the SGI Free Software B License Version
|
||||
* 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "OpenGL-ES" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
#ifndef GL_APICALL
|
||||
#define GL_APICALL KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef GL_APIENTRY
|
||||
#define GL_APIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
#endif /* __gl3platform_h_ */
|
|
@ -1,591 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2013 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 GLSLANG_SHADERLANG_H_
|
||||
#define GLSLANG_SHADERLANG_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "KHR/khrplatform.h"
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
// This is the platform independent interface between an OGL driver
|
||||
// and the shading language compiler.
|
||||
//
|
||||
|
||||
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
|
||||
#include "ShaderVars.h"
|
||||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented every time the API changes.
|
||||
#define ANGLE_SH_VERSION 182
|
||||
|
||||
enum ShShaderSpec
|
||||
{
|
||||
SH_GLES2_SPEC,
|
||||
SH_WEBGL_SPEC,
|
||||
|
||||
SH_GLES3_SPEC,
|
||||
SH_WEBGL2_SPEC,
|
||||
|
||||
SH_GLES3_1_SPEC,
|
||||
SH_WEBGL3_SPEC,
|
||||
};
|
||||
|
||||
enum ShShaderOutput
|
||||
{
|
||||
// ESSL output only supported in some configurations.
|
||||
SH_ESSL_OUTPUT = 0x8B45,
|
||||
|
||||
// GLSL output only supported in some configurations.
|
||||
SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
|
||||
// Note: GL introduced core profiles in 1.5.
|
||||
SH_GLSL_130_OUTPUT = 0x8B47,
|
||||
SH_GLSL_140_OUTPUT = 0x8B80,
|
||||
SH_GLSL_150_CORE_OUTPUT = 0x8B81,
|
||||
SH_GLSL_330_CORE_OUTPUT = 0x8B82,
|
||||
SH_GLSL_400_CORE_OUTPUT = 0x8B83,
|
||||
SH_GLSL_410_CORE_OUTPUT = 0x8B84,
|
||||
SH_GLSL_420_CORE_OUTPUT = 0x8B85,
|
||||
SH_GLSL_430_CORE_OUTPUT = 0x8B86,
|
||||
SH_GLSL_440_CORE_OUTPUT = 0x8B87,
|
||||
SH_GLSL_450_CORE_OUTPUT = 0x8B88,
|
||||
|
||||
// Prefer using these to specify HLSL output type:
|
||||
SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9
|
||||
SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11
|
||||
SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A, // D3D 11 feature level 9_3
|
||||
|
||||
// Output specialized GLSL to be fed to glslang for Vulkan SPIR.
|
||||
SH_GLSL_VULKAN_OUTPUT = 0x8B4B,
|
||||
};
|
||||
|
||||
// Compile options.
|
||||
// The Compile options type is defined in ShaderVars.h, to allow ANGLE to import the ShaderVars
|
||||
// header without needing the ShaderLang header. This avoids some conflicts with glslang.
|
||||
|
||||
const ShCompileOptions SH_VALIDATE = 0;
|
||||
const ShCompileOptions SH_VALIDATE_LOOP_INDEXING = UINT64_C(1) << 0;
|
||||
const ShCompileOptions SH_INTERMEDIATE_TREE = UINT64_C(1) << 1;
|
||||
const ShCompileOptions SH_OBJECT_CODE = UINT64_C(1) << 2;
|
||||
const ShCompileOptions SH_VARIABLES = UINT64_C(1) << 3;
|
||||
const ShCompileOptions SH_LINE_DIRECTIVES = UINT64_C(1) << 4;
|
||||
const ShCompileOptions SH_SOURCE_PATH = UINT64_C(1) << 5;
|
||||
|
||||
// This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20 on AMD.
|
||||
// From GLSL >= 4.20, it's optional to add invariant for fragment input, but GPU vendors have
|
||||
// different implementations about this. Some drivers forbid invariant in fragment for GLSL>= 4.20,
|
||||
// e.g. Linux Mesa, some drivers treat that as optional, e.g. NVIDIA, some drivers require invariant
|
||||
// must match between vertex and fragment shader, e.g. AMD. The behavior on AMD is obviously wrong.
|
||||
// Remove invariant for input in fragment shader to workaround the restriction on Intel Mesa.
|
||||
// But don't remove on AMD Linux to avoid triggering the bug on AMD.
|
||||
const ShCompileOptions SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT = UINT64_C(1) << 6;
|
||||
|
||||
// Due to spec difference between GLSL 4.1 or lower and ESSL3, some platforms (for example, Mac OSX
|
||||
// core profile) require a variable's "invariant"/"centroid" qualifiers to match between vertex and
|
||||
// fragment shader. A simple solution to allow such shaders to link is to omit the two qualifiers.
|
||||
// AMD driver in Linux requires invariant qualifier to match between vertex and fragment shaders,
|
||||
// while ESSL3 disallows invariant qualifier in fragment shader and GLSL >= 4.2 doesn't require
|
||||
// invariant qualifier to match between shaders. Remove invariant qualifier from vertex shader to
|
||||
// workaround AMD driver bug.
|
||||
// Note that the two flags take effect on ESSL3 input shaders translated to GLSL 4.1 or lower and to
|
||||
// GLSL 4.2 or newer on Linux AMD.
|
||||
// TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break some
|
||||
// developers' content. A more complex workaround of dynamically generating, compiling, and
|
||||
// re-linking shaders that use these qualifiers should be implemented.
|
||||
const ShCompileOptions SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3 = UINT64_C(1) << 7;
|
||||
|
||||
// This flag works around bug in Intel Mac drivers related to abs(i) where
|
||||
// i is an integer.
|
||||
const ShCompileOptions SH_EMULATE_ABS_INT_FUNCTION = UINT64_C(1) << 8;
|
||||
|
||||
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
|
||||
// This flag only enforces (and can only enforce) the packing
|
||||
// restrictions for uniform variables in both vertex and fragment
|
||||
// shaders. ShCheckVariablesWithinPackingLimits() lets embedders
|
||||
// enforce the packing restrictions for varying variables during
|
||||
// program link time.
|
||||
const ShCompileOptions SH_ENFORCE_PACKING_RESTRICTIONS = UINT64_C(1) << 9;
|
||||
|
||||
// This flag ensures all indirect (expression-based) array indexing
|
||||
// is clamped to the bounds of the array. This ensures, for example,
|
||||
// that you cannot read off the end of a uniform, whether an array
|
||||
// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
|
||||
// specified in the ShBuiltInResources when constructing the
|
||||
// compiler, selects the strategy for the clamping implementation.
|
||||
const ShCompileOptions SH_CLAMP_INDIRECT_ARRAY_BOUNDS = UINT64_C(1) << 10;
|
||||
|
||||
// This flag limits the complexity of an expression.
|
||||
const ShCompileOptions SH_LIMIT_EXPRESSION_COMPLEXITY = UINT64_C(1) << 11;
|
||||
|
||||
// This flag limits the depth of the call stack.
|
||||
const ShCompileOptions SH_LIMIT_CALL_STACK_DEPTH = UINT64_C(1) << 12;
|
||||
|
||||
// This flag initializes gl_Position to vec4(0,0,0,0) at the
|
||||
// beginning of the vertex shader's main(), and has no effect in the
|
||||
// fragment shader. It is intended as a workaround for drivers which
|
||||
// incorrectly fail to link programs if gl_Position is not written.
|
||||
const ShCompileOptions SH_INIT_GL_POSITION = UINT64_C(1) << 13;
|
||||
|
||||
// This flag replaces
|
||||
// "a && b" with "a ? b : false",
|
||||
// "a || b" with "a ? true : b".
|
||||
// This is to work around a MacOSX driver bug that |b| is executed
|
||||
// independent of |a|'s value.
|
||||
const ShCompileOptions SH_UNFOLD_SHORT_CIRCUIT = UINT64_C(1) << 14;
|
||||
|
||||
// This flag initializes output variables to 0 at the beginning of main().
|
||||
// It is to avoid undefined behaviors.
|
||||
const ShCompileOptions SH_INIT_OUTPUT_VARIABLES = UINT64_C(1) << 15;
|
||||
|
||||
// This flag scalarizes vec/ivec/bvec/mat constructor args.
|
||||
// It is intended as a workaround for Linux/Mac driver bugs.
|
||||
const ShCompileOptions SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = UINT64_C(1) << 16;
|
||||
|
||||
// This flag overwrites a struct name with a unique prefix.
|
||||
// It is intended as a workaround for drivers that do not handle
|
||||
// struct scopes correctly, including all Mac drivers and Linux AMD.
|
||||
const ShCompileOptions SH_REGENERATE_STRUCT_NAMES = UINT64_C(1) << 17;
|
||||
|
||||
// This flag makes the compiler not prune unused function early in the
|
||||
// compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH
|
||||
// helps avoid bad shaders causing stack overflows.
|
||||
const ShCompileOptions SH_DONT_PRUNE_UNUSED_FUNCTIONS = UINT64_C(1) << 18;
|
||||
|
||||
// This flag works around a bug in NVIDIA 331 series drivers related
|
||||
// to pow(x, y) where y is a constant vector.
|
||||
const ShCompileOptions SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = UINT64_C(1) << 19;
|
||||
|
||||
// This flag works around bugs in Mac drivers related to do-while by
|
||||
// transforming them into an other construct.
|
||||
const ShCompileOptions SH_REWRITE_DO_WHILE_LOOPS = UINT64_C(1) << 20;
|
||||
|
||||
// This flag works around a bug in the HLSL compiler optimizer that folds certain
|
||||
// constant pow expressions incorrectly. Only applies to the HLSL back-end. It works
|
||||
// by expanding the integer pow expressions into a series of multiplies.
|
||||
const ShCompileOptions SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS = UINT64_C(1) << 21;
|
||||
|
||||
// Flatten "#pragma STDGL invariant(all)" into the declarations of
|
||||
// varying variables and built-in GLSL variables. This compiler
|
||||
// option is enabled automatically when needed.
|
||||
const ShCompileOptions SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL = UINT64_C(1) << 22;
|
||||
|
||||
// Some drivers do not take into account the base level of the texture in the results of the
|
||||
// HLSL GetDimensions builtin. This flag instructs the compiler to manually add the base level
|
||||
// offsetting.
|
||||
const ShCompileOptions SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = UINT64_C(1) << 23;
|
||||
|
||||
// This flag works around an issue in translating GLSL function texelFetchOffset on
|
||||
// INTEL drivers. It works by translating texelFetchOffset into texelFetch.
|
||||
const ShCompileOptions SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = UINT64_C(1) << 24;
|
||||
|
||||
// This flag works around condition bug of for and while loops in Intel Mac OSX drivers.
|
||||
// Condition calculation is not correct. Rewrite it from "CONDITION" to "CONDITION && true".
|
||||
const ShCompileOptions SH_ADD_AND_TRUE_TO_LOOP_CONDITION = UINT64_C(1) << 25;
|
||||
|
||||
// This flag works around a bug in evaluating unary minus operator on integer on some INTEL
|
||||
// drivers. It works by translating -(int) into ~(int) + 1.
|
||||
const ShCompileOptions SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR = UINT64_C(1) << 26;
|
||||
|
||||
// This flag works around a bug in evaluating isnan() on some INTEL D3D and Mac OSX drivers.
|
||||
// It works by using an expression to emulate this function.
|
||||
const ShCompileOptions SH_EMULATE_ISNAN_FLOAT_FUNCTION = UINT64_C(1) << 27;
|
||||
|
||||
// This flag will use all uniforms of unused std140 and shared uniform blocks at the
|
||||
// beginning of the vertex/fragment shader's main(). It is intended as a workaround for Mac
|
||||
// drivers with shader version 4.10. In those drivers, they will treat unused
|
||||
// std140 and shared uniform blocks' members as inactive. However, WebGL2.0 based on
|
||||
// OpenGL ES3.0.4 requires all members of a named uniform block declared with a shared or std140
|
||||
// layout qualifier to be considered active. The uniform block itself is also considered active.
|
||||
const ShCompileOptions SH_USE_UNUSED_STANDARD_SHARED_BLOCKS = UINT64_C(1) << 28;
|
||||
|
||||
// This flag works around a bug in unary minus operator on float numbers on Intel
|
||||
// Mac OSX 10.11 drivers. It works by translating -float into 0.0 - float.
|
||||
const ShCompileOptions SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR = UINT64_C(1) << 29;
|
||||
|
||||
// This flag works around a bug in evaluating atan(y, x) on some NVIDIA OpenGL drivers.
|
||||
// It works by using an expression to emulate this function.
|
||||
const ShCompileOptions SH_EMULATE_ATAN2_FLOAT_FUNCTION = UINT64_C(1) << 30;
|
||||
|
||||
// Set to 1 to translate gl_ViewID_OVR to an uniform so that the extension can be emulated.
|
||||
// "uniform highp uint ViewID_OVR".
|
||||
const ShCompileOptions SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM = UINT64_C(1) << 31;
|
||||
|
||||
// Set to initialize uninitialized local variables. Should only be used with GLSL output. In HLSL
|
||||
// output variables are initialized regardless of if this flag is set.
|
||||
const ShCompileOptions SH_INITIALIZE_UNINITIALIZED_LOCALS = UINT64_C(1) << 32;
|
||||
|
||||
// The flag modifies the shader in the following way:
|
||||
// Every occurrence of gl_InstanceID is replaced by the global temporary variable InstanceID.
|
||||
// Every occurrence of gl_ViewID_OVR is replaced by the varying variable ViewID_OVR.
|
||||
// At the beginning of the body of main() in a vertex shader the following initializers are added:
|
||||
// ViewID_OVR = uint(gl_InstanceID) % num_views;
|
||||
// InstanceID = gl_InstanceID / num_views;
|
||||
// ViewID_OVR is added as a varying variable to both the vertex and fragment shaders.
|
||||
const ShCompileOptions SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW = UINT64_C(1) << 33;
|
||||
|
||||
// With the flag enabled the GLSL/ESSL vertex shader is modified to include code for viewport
|
||||
// selection in the following way:
|
||||
// - Code to enable the extension NV_viewport_array2 is included.
|
||||
// - Code to select the viewport index or layer is inserted at the beginning of main after
|
||||
// ViewID_OVR's initialization.
|
||||
// - A declaration of the uniform multiviewBaseViewLayerIndex.
|
||||
// Note: The SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW flag also has to be enabled to have the
|
||||
// temporary variable ViewID_OVR declared and initialized.
|
||||
const ShCompileOptions SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER = UINT64_C(1) << 34;
|
||||
|
||||
// If the flag is enabled, gl_PointSize is clamped to the maximum point size specified in
|
||||
// ShBuiltInResources in vertex shaders.
|
||||
const ShCompileOptions SH_CLAMP_POINT_SIZE = UINT64_C(1) << 35;
|
||||
|
||||
// Defines alternate strategies for implementing array index clamping.
|
||||
enum ShArrayIndexClampingStrategy
|
||||
{
|
||||
// Use the clamp intrinsic for array index clamping.
|
||||
SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
|
||||
|
||||
// Use a user-defined function for array index clamping.
|
||||
SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
|
||||
};
|
||||
|
||||
// The 64 bits hash function. The first parameter is the input string; the
|
||||
// second parameter is the string length.
|
||||
using ShHashFunction64 = khronos_uint64_t (*)(const char *, size_t);
|
||||
|
||||
//
|
||||
// Implementation dependent built-in resources (constants and extensions).
|
||||
// The names for these resources has been obtained by stripping gl_/GL_.
|
||||
//
|
||||
struct ShBuiltInResources
|
||||
{
|
||||
// Constants.
|
||||
int MaxVertexAttribs;
|
||||
int MaxVertexUniformVectors;
|
||||
int MaxVaryingVectors;
|
||||
int MaxVertexTextureImageUnits;
|
||||
int MaxCombinedTextureImageUnits;
|
||||
int MaxTextureImageUnits;
|
||||
int MaxFragmentUniformVectors;
|
||||
int MaxDrawBuffers;
|
||||
|
||||
// Extensions.
|
||||
// Set to 1 to enable the extension, else 0.
|
||||
int OES_standard_derivatives;
|
||||
int OES_EGL_image_external;
|
||||
int OES_EGL_image_external_essl3;
|
||||
int NV_EGL_stream_consumer_external;
|
||||
int ARB_texture_rectangle;
|
||||
int EXT_blend_func_extended;
|
||||
int EXT_draw_buffers;
|
||||
int EXT_frag_depth;
|
||||
int EXT_shader_texture_lod;
|
||||
int WEBGL_debug_shader_precision;
|
||||
int EXT_shader_framebuffer_fetch;
|
||||
int NV_shader_framebuffer_fetch;
|
||||
int ARM_shader_framebuffer_fetch;
|
||||
int OVR_multiview;
|
||||
int EXT_YUV_target;
|
||||
int OES_geometry_shader;
|
||||
|
||||
// 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 ESSL 1.00 version of the
|
||||
// fragment language. Does not affect versions of the language where highp
|
||||
// support is mandatory.
|
||||
// Default is 0.
|
||||
int FragmentPrecisionHigh;
|
||||
|
||||
// GLSL ES 3.0 constants.
|
||||
int MaxVertexOutputVectors;
|
||||
int MaxFragmentInputVectors;
|
||||
int MinProgramTexelOffset;
|
||||
int MaxProgramTexelOffset;
|
||||
|
||||
// Extension constants.
|
||||
|
||||
// Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT for OpenGL ES output context.
|
||||
// Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS for OpenGL output context.
|
||||
// GLES SL version 100 gl_MaxDualSourceDrawBuffersEXT value for EXT_blend_func_extended.
|
||||
int MaxDualSourceDrawBuffers;
|
||||
|
||||
// Value of GL_MAX_VIEWS_OVR.
|
||||
int MaxViewsOVR;
|
||||
|
||||
// Name Hashing.
|
||||
// Set a 64 bit hash function to enable user-defined name hashing.
|
||||
// Default is NULL.
|
||||
ShHashFunction64 HashFunction;
|
||||
|
||||
// Selects a strategy to use when implementing array index clamping.
|
||||
// Default is SH_CLAMP_WITH_CLAMP_INTRINSIC.
|
||||
ShArrayIndexClampingStrategy ArrayIndexClampingStrategy;
|
||||
|
||||
// The maximum complexity an expression can be when SH_LIMIT_EXPRESSION_COMPLEXITY is turned on.
|
||||
int MaxExpressionComplexity;
|
||||
|
||||
// The maximum depth a call stack can be.
|
||||
int MaxCallStackDepth;
|
||||
|
||||
// The maximum number of parameters a function can have when SH_LIMIT_EXPRESSION_COMPLEXITY is
|
||||
// turned on.
|
||||
int MaxFunctionParameters;
|
||||
|
||||
// GLES 3.1 constants
|
||||
|
||||
// texture gather offset constraints.
|
||||
int MinProgramTextureGatherOffset;
|
||||
int MaxProgramTextureGatherOffset;
|
||||
|
||||
// maximum number of available image units
|
||||
int MaxImageUnits;
|
||||
|
||||
// maximum number of image uniforms in a vertex shader
|
||||
int MaxVertexImageUniforms;
|
||||
|
||||
// maximum number of image uniforms in a fragment shader
|
||||
int MaxFragmentImageUniforms;
|
||||
|
||||
// maximum number of image uniforms in a compute shader
|
||||
int MaxComputeImageUniforms;
|
||||
|
||||
// maximum total number of image uniforms in a program
|
||||
int MaxCombinedImageUniforms;
|
||||
|
||||
// maximum number of uniform locations
|
||||
int MaxUniformLocations;
|
||||
|
||||
// maximum number of ssbos and images in a shader
|
||||
int MaxCombinedShaderOutputResources;
|
||||
|
||||
// maximum number of groups in each dimension
|
||||
std::array<int, 3> MaxComputeWorkGroupCount;
|
||||
// maximum number of threads per work group in each dimension
|
||||
std::array<int, 3> MaxComputeWorkGroupSize;
|
||||
|
||||
// maximum number of total uniform components
|
||||
int MaxComputeUniformComponents;
|
||||
|
||||
// maximum number of texture image units in a compute shader
|
||||
int MaxComputeTextureImageUnits;
|
||||
|
||||
// maximum number of atomic counters in a compute shader
|
||||
int MaxComputeAtomicCounters;
|
||||
|
||||
// maximum number of atomic counter buffers in a compute shader
|
||||
int MaxComputeAtomicCounterBuffers;
|
||||
|
||||
// maximum number of atomic counters in a vertex shader
|
||||
int MaxVertexAtomicCounters;
|
||||
|
||||
// maximum number of atomic counters in a fragment shader
|
||||
int MaxFragmentAtomicCounters;
|
||||
|
||||
// maximum number of atomic counters in a program
|
||||
int MaxCombinedAtomicCounters;
|
||||
|
||||
// maximum binding for an atomic counter
|
||||
int MaxAtomicCounterBindings;
|
||||
|
||||
// maximum number of atomic counter buffers in a vertex shader
|
||||
int MaxVertexAtomicCounterBuffers;
|
||||
|
||||
// maximum number of atomic counter buffers in a fragment shader
|
||||
int MaxFragmentAtomicCounterBuffers;
|
||||
|
||||
// maximum number of atomic counter buffers in a program
|
||||
int MaxCombinedAtomicCounterBuffers;
|
||||
|
||||
// maximum number of buffer object storage in machine units
|
||||
int MaxAtomicCounterBufferSize;
|
||||
|
||||
// maximum number of uniform block bindings
|
||||
int MaxUniformBufferBindings;
|
||||
|
||||
// maximum number of shader storage buffer bindings
|
||||
int MaxShaderStorageBufferBindings;
|
||||
|
||||
// maximum point size (higher limit from ALIASED_POINT_SIZE_RANGE)
|
||||
float MaxPointSize;
|
||||
|
||||
// OES_geometry_shader constants
|
||||
int MaxGeometryUniformComponents;
|
||||
int MaxGeometryUniformBlocks;
|
||||
int MaxGeometryInputComponents;
|
||||
int MaxGeometryOutputComponents;
|
||||
int MaxGeometryOutputVertices;
|
||||
int MaxGeometryTotalOutputComponents;
|
||||
int MaxGeometryTextureImageUnits;
|
||||
int MaxGeometryAtomicCounterBuffers;
|
||||
int MaxGeometryAtomicCounters;
|
||||
int MaxGeometryShaderStorageBlocks;
|
||||
int MaxGeometryShaderInvocations;
|
||||
int MaxGeometryImageUniforms;
|
||||
};
|
||||
|
||||
//
|
||||
// ShHandle held by but opaque to the driver. It is allocated,
|
||||
// managed, and de-allocated by the compiler. Its contents
|
||||
// are defined by and used by the compiler.
|
||||
//
|
||||
// If handle creation fails, 0 will be returned.
|
||||
//
|
||||
using ShHandle = void *;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other compiler operations.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
bool Initialize();
|
||||
//
|
||||
// Driver should call this at shutdown.
|
||||
// If the function succeeds, the return value is true, else false.
|
||||
//
|
||||
bool Finalize();
|
||||
|
||||
//
|
||||
// Initialize built-in resources with minimum expected values.
|
||||
// Parameters:
|
||||
// resources: The object to initialize. Will be comparable with memcmp.
|
||||
//
|
||||
void InitBuiltInResources(ShBuiltInResources *resources);
|
||||
|
||||
//
|
||||
// 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.
|
||||
const std::string &GetBuiltInResourcesString(const ShHandle handle);
|
||||
|
||||
//
|
||||
// Driver calls these to create and destroy compiler objects.
|
||||
//
|
||||
// Returns the handle of constructed compiler, null if the requested compiler is not supported.
|
||||
// Parameters:
|
||||
// type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
|
||||
// spec: Specifies the language spec the compiler must conform to - SH_GLES2_SPEC or SH_WEBGL_SPEC.
|
||||
// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
|
||||
// SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
|
||||
// be supported in some configurations.
|
||||
// resources: Specifies the built-in resources.
|
||||
ShHandle ConstructCompiler(sh::GLenum type,
|
||||
ShShaderSpec spec,
|
||||
ShShaderOutput output,
|
||||
const ShBuiltInResources *resources);
|
||||
void Destruct(ShHandle handle);
|
||||
|
||||
//
|
||||
// Compiles the given shader source.
|
||||
// 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 containing the shader
|
||||
// source code.
|
||||
// numStrings: Specifies the number of elements in shaderStrings array.
|
||||
// compileOptions: A mask containing the following parameters:
|
||||
// SH_VALIDATE: Validates shader to ensure that it conforms to the spec
|
||||
// specified during compiler construction.
|
||||
// SH_VALIDATE_LOOP_INDEXING: Validates loop and indexing in the shader to
|
||||
// ensure that they do not exceed the minimum
|
||||
// functionality mandated in GLSL 1.0 spec,
|
||||
// Appendix A, Section 4 and 5.
|
||||
// There is no need to specify this parameter when
|
||||
// compiling for WebGL - it is implied.
|
||||
// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
|
||||
// Can be queried by calling sh::GetInfoLog().
|
||||
// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
|
||||
// Can be queried by calling sh::GetObjectCode().
|
||||
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
|
||||
// Can be queried by calling ShGetVariableInfo().
|
||||
//
|
||||
bool Compile(const ShHandle handle,
|
||||
const char *const shaderStrings[],
|
||||
size_t numStrings,
|
||||
ShCompileOptions compileOptions);
|
||||
|
||||
// Clears the results from the previous compilation.
|
||||
void ClearResults(const ShHandle handle);
|
||||
|
||||
// Return the version of the shader language.
|
||||
int GetShaderVersion(const ShHandle handle);
|
||||
|
||||
// Return the currently set language output type.
|
||||
ShShaderOutput GetShaderOutputType(const ShHandle handle);
|
||||
|
||||
// Returns null-terminated information log for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
const std::string &GetInfoLog(const ShHandle handle);
|
||||
|
||||
// Returns null-terminated object code for a compiled shader.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
const std::string &GetObjectCode(const ShHandle handle);
|
||||
|
||||
// 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
|
||||
const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle);
|
||||
|
||||
// Shader variable inspection.
|
||||
// Returns a pointer to a list of variables of the designated type.
|
||||
// (See ShaderVars.h for type definitions, included above)
|
||||
// Returns NULL on failure.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
const std::vector<sh::Uniform> *GetUniforms(const ShHandle handle);
|
||||
const std::vector<sh::Varying> *GetVaryings(const ShHandle handle);
|
||||
const std::vector<sh::Varying> *GetInputVaryings(const ShHandle handle);
|
||||
const std::vector<sh::Varying> *GetOutputVaryings(const ShHandle handle);
|
||||
const std::vector<sh::Attribute> *GetAttributes(const ShHandle handle);
|
||||
const std::vector<sh::OutputVariable> *GetOutputVariables(const ShHandle handle);
|
||||
const std::vector<sh::InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle);
|
||||
const std::vector<sh::InterfaceBlock> *GetUniformBlocks(const ShHandle handle);
|
||||
const std::vector<sh::InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle);
|
||||
sh::WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle);
|
||||
// Returns the number of views specified through the num_views layout qualifier. If num_views is
|
||||
// not set, the function returns -1.
|
||||
int GetVertexShaderNumViews(const ShHandle handle);
|
||||
|
||||
// Returns true if the passed in variables pack in maxVectors followingthe packing rules from the
|
||||
// GLSL 1.017 spec, Appendix A, section 7.
|
||||
// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
|
||||
// flag above.
|
||||
// Parameters:
|
||||
// maxVectors: the available rows of registers.
|
||||
// variables: an array of variables.
|
||||
bool CheckVariablesWithinPackingLimits(int maxVectors,
|
||||
const std::vector<sh::ShaderVariable> &variables);
|
||||
|
||||
// Gives the compiler-assigned register for a uniform block.
|
||||
// The method writes the value to the output variable "indexOut".
|
||||
// Returns true if it found a valid uniform block, false otherwise.
|
||||
// Parameters:
|
||||
// handle: Specifies the compiler
|
||||
// uniformBlockName: Specifies the uniform block
|
||||
// indexOut: output variable that stores the assigned register
|
||||
bool GetUniformBlockRegister(const ShHandle handle,
|
||||
const std::string &uniformBlockName,
|
||||
unsigned int *indexOut);
|
||||
|
||||
// Gives a map from uniform names to compiler-assigned registers in the default uniform block.
|
||||
// Note that the map contains also registers of samplers that have been extracted from structs.
|
||||
const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle);
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // GLSLANG_SHADERLANG_H_
|
|
@ -1,269 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013-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.
|
||||
//
|
||||
// ShaderVars.h:
|
||||
// Types to represent GL variables (varyings, uniforms, etc)
|
||||
//
|
||||
|
||||
#ifndef GLSLANG_SHADERVARS_H_
|
||||
#define GLSLANG_SHADERVARS_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// This type is defined here to simplify ANGLE's integration with glslang for SPIRv.
|
||||
using ShCompileOptions = uint64_t;
|
||||
|
||||
namespace sh
|
||||
{
|
||||
// GLenum alias
|
||||
typedef unsigned int GLenum;
|
||||
|
||||
// Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
|
||||
enum InterpolationType
|
||||
{
|
||||
INTERPOLATION_SMOOTH,
|
||||
INTERPOLATION_CENTROID,
|
||||
INTERPOLATION_FLAT
|
||||
};
|
||||
|
||||
// Validate link & SSO consistency of interpolation qualifiers
|
||||
bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
|
||||
|
||||
// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
|
||||
enum BlockLayoutType
|
||||
{
|
||||
BLOCKLAYOUT_STANDARD,
|
||||
BLOCKLAYOUT_PACKED,
|
||||
BLOCKLAYOUT_SHARED
|
||||
};
|
||||
|
||||
// Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec
|
||||
enum class BlockType
|
||||
{
|
||||
BLOCK_UNIFORM,
|
||||
BLOCK_BUFFER,
|
||||
|
||||
// Required in OpenGL ES 3.1 extension GL_OES_shader_io_blocks.
|
||||
// TODO(jiawei.shao@intel.com): add BLOCK_OUT.
|
||||
BLOCK_IN
|
||||
};
|
||||
|
||||
// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
|
||||
// Note: we must override the copy constructor and assignment operator so we can
|
||||
// work around excessive GCC binary bloating:
|
||||
// See https://code.google.com/p/angleproject/issues/detail?id=697
|
||||
struct ShaderVariable
|
||||
{
|
||||
ShaderVariable();
|
||||
ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
|
||||
~ShaderVariable();
|
||||
ShaderVariable(const ShaderVariable &other);
|
||||
ShaderVariable &operator=(const ShaderVariable &other);
|
||||
|
||||
bool isArray() const { return arraySize > 0; }
|
||||
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;
|
||||
|
||||
bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
|
||||
|
||||
GLenum type;
|
||||
GLenum precision;
|
||||
std::string name;
|
||||
std::string mappedName;
|
||||
unsigned int arraySize;
|
||||
bool staticUse;
|
||||
std::vector<ShaderVariable> fields;
|
||||
std::string structName;
|
||||
|
||||
protected:
|
||||
bool isSameVariableAtLinkTime(const ShaderVariable &other,
|
||||
bool matchPrecision,
|
||||
bool matchName) const;
|
||||
|
||||
bool operator==(const ShaderVariable &other) const;
|
||||
bool operator!=(const ShaderVariable &other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
// A variable with an integer location to pass back to the GL API: either uniform (can have location
|
||||
// in GLES3.1+), vertex shader input or fragment shader output.
|
||||
struct VariableWithLocation : public ShaderVariable
|
||||
{
|
||||
VariableWithLocation();
|
||||
~VariableWithLocation();
|
||||
VariableWithLocation(const VariableWithLocation &other);
|
||||
VariableWithLocation &operator=(const VariableWithLocation &other);
|
||||
bool operator==(const VariableWithLocation &other) const;
|
||||
bool operator!=(const VariableWithLocation &other) const { return !operator==(other); }
|
||||
|
||||
int location;
|
||||
};
|
||||
|
||||
struct Uniform : public VariableWithLocation
|
||||
{
|
||||
Uniform();
|
||||
~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);
|
||||
}
|
||||
|
||||
int binding;
|
||||
int offset;
|
||||
|
||||
// Decide whether two uniforms are the same at shader link time,
|
||||
// assuming one from vertex shader and the other from fragment shader.
|
||||
// GLSL ES Spec 3.00.3, section 4.3.5.
|
||||
// GLSL ES Spec 3.10.4, section 4.4.5
|
||||
bool isSameUniformAtLinkTime(const Uniform &other) const;
|
||||
};
|
||||
|
||||
struct Attribute : public VariableWithLocation
|
||||
{
|
||||
Attribute();
|
||||
~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); }
|
||||
};
|
||||
|
||||
struct OutputVariable : public VariableWithLocation
|
||||
{
|
||||
OutputVariable();
|
||||
~OutputVariable();
|
||||
OutputVariable(const OutputVariable &other);
|
||||
OutputVariable &operator=(const OutputVariable &other);
|
||||
bool operator==(const OutputVariable &other) const;
|
||||
bool operator!=(const OutputVariable &other) const { return !operator==(other); }
|
||||
};
|
||||
|
||||
struct InterfaceBlockField : public ShaderVariable
|
||||
{
|
||||
InterfaceBlockField();
|
||||
~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;
|
||||
};
|
||||
|
||||
struct Varying : public VariableWithLocation
|
||||
{
|
||||
Varying();
|
||||
~Varying();
|
||||
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.
|
||||
// Invariance needs to match only in ESSL1. Relevant spec sections:
|
||||
// GLSL ES 3.00.4, sections 4.6.1 and 4.3.9.
|
||||
// GLSL ES 1.00.17, section 4.6.4.
|
||||
bool isSameVaryingAtLinkTime(const Varying &other, int shaderVersion) const;
|
||||
|
||||
// Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1.
|
||||
bool isSameVaryingAtLinkTime(const Varying &other) const;
|
||||
|
||||
InterpolationType interpolation;
|
||||
bool isInvariant;
|
||||
};
|
||||
|
||||
struct InterfaceBlock
|
||||
{
|
||||
InterfaceBlock();
|
||||
~InterfaceBlock();
|
||||
InterfaceBlock(const InterfaceBlock &other);
|
||||
InterfaceBlock &operator=(const InterfaceBlock &other);
|
||||
|
||||
// Fields from blocks with non-empty instance names are prefixed with the block name.
|
||||
std::string fieldPrefix() const;
|
||||
std::string fieldMappedPrefix() const;
|
||||
|
||||
// Decide whether two interface blocks are the same at shader link time.
|
||||
bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const;
|
||||
|
||||
bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; }
|
||||
|
||||
std::string name;
|
||||
std::string mappedName;
|
||||
std::string instanceName;
|
||||
unsigned int arraySize;
|
||||
BlockLayoutType layout;
|
||||
bool isRowMajorLayout;
|
||||
int binding;
|
||||
bool staticUse;
|
||||
BlockType blockType;
|
||||
std::vector<InterfaceBlockField> fields;
|
||||
};
|
||||
|
||||
struct WorkGroupSize
|
||||
{
|
||||
void fill(int fillValue);
|
||||
void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
|
||||
|
||||
int &operator[](size_t index);
|
||||
int operator[](size_t index) const;
|
||||
size_t size() const;
|
||||
|
||||
// Checks whether two work group size declarations match.
|
||||
// Two work group size declarations are the same if the explicitly specified elements are the
|
||||
// same or if one of them is specified as one and the other one is not specified
|
||||
bool isWorkGroupSizeMatching(const WorkGroupSize &right) const;
|
||||
|
||||
// Checks whether any of the values are set.
|
||||
bool isAnyValueSet() const;
|
||||
|
||||
// Checks whether all of the values are set.
|
||||
bool isDeclared() const;
|
||||
|
||||
// Checks whether either all of the values are set, or none of them are.
|
||||
bool isLocalSizeValid() const;
|
||||
|
||||
int localSizeQualifiers[3];
|
||||
};
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // GLSLANG_SHADERVARS_H_
|
|
@ -1,285 +0,0 @@
|
|||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2009 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by sending them to the public Khronos Bugzilla
|
||||
* (http://khronos.org/bugzilla) by filing a bug against product
|
||||
* "Khronos (general)" component "Registry".
|
||||
*
|
||||
* A predefined template which fills in some of the bug fields can be
|
||||
* reached using http://tinyurl.com/khrplatform-h-bugreport, but you
|
||||
* must create a Bugzilla login first.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# include <sys/cdefs.h>
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default"))) __NDK_FPABI__
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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_gl.h:
|
||||
// Includes all necessary GL headers and definitions for ANGLE.
|
||||
//
|
||||
|
||||
#ifndef ANGLEGL_H_
|
||||
#define ANGLEGL_H_
|
||||
|
||||
#include "GLES2/gl2.h"
|
||||
#include "GLES2/gl2ext.h"
|
||||
#include "GLES3/gl3.h"
|
||||
#include "GLES3/gl31.h"
|
||||
#include "GLES3/gl32.h"
|
||||
|
||||
#endif // ANGLEGL_H_
|
|
@ -1,51 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
// The render surface will then be scaled to the window dimensions.
|
||||
// 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";
|
||||
|
||||
//
|
||||
// Property: EGLRenderResolutionScaleProperty
|
||||
// Type: Single
|
||||
// Description: Use this to specify a preferred scale for the render surface compared to the window.
|
||||
// For example, if the window is 800x480, and:
|
||||
// - scale is set to 0.5f then the surface will be 400x240
|
||||
// - scale is set to 1.2f then the surface will be 960x576
|
||||
// If the window resizes or rotates then the surface will resize accordingly.
|
||||
// EGLRenderResolutionScaleProperty and EGLRenderSurfaceSizeProperty cannot both be set.
|
||||
// The scale factor should be > 0.0f.
|
||||
//
|
||||
const wchar_t EGLRenderResolutionScaleProperty[] = L"EGLRenderResolutionScaleProperty";
|
||||
|
||||
#endif // ANGLE_WINDOWSSTORE_H_
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// export.h : Defines ANGLE_EXPORT, a macro for exporting functions from the DLL
|
||||
|
||||
#ifndef LIBGLESV2_EXPORT_H_
|
||||
#define LIBGLESV2_EXPORT_H_
|
||||
|
||||
#if !defined(ANGLE_EXPORT)
|
||||
#if defined(_WIN32)
|
||||
#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
|
||||
defined(LIBANGLE_UTIL_IMPLEMENTATION)
|
||||
# define ANGLE_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define ANGLE_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
|
||||
defined(LIBANGLE_UTIL_IMPLEMENTATION)
|
||||
# define ANGLE_EXPORT __attribute__((visibility ("default")))
|
||||
# else
|
||||
# define ANGLE_EXPORT
|
||||
# endif
|
||||
#else
|
||||
# define ANGLE_EXPORT
|
||||
#endif
|
||||
#endif // !defined(ANGLE_EXPORT)
|
||||
|
||||
#endif // LIBGLESV2_EXPORT_H_
|
|
@ -1,325 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2015 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.
|
||||
|
||||
// Platform.h: The public interface ANGLE exposes to the API layer, for
|
||||
// doing platform-specific tasks like gathering data, or for tracing.
|
||||
|
||||
#ifndef ANGLE_PLATFORM_H
|
||||
#define ANGLE_PLATFORM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <array>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# if !defined(LIBANGLE_IMPLEMENTATION)
|
||||
# define ANGLE_PLATFORM_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if defined(LIBANGLE_IMPLEMENTATION)
|
||||
# define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default")))
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(ANGLE_PLATFORM_EXPORT)
|
||||
# define ANGLE_PLATFORM_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define ANGLE_APIENTRY __stdcall
|
||||
#else
|
||||
# define ANGLE_APIENTRY
|
||||
#endif
|
||||
|
||||
namespace angle
|
||||
{
|
||||
struct WorkaroundsD3D;
|
||||
using TraceEventHandle = uint64_t;
|
||||
using EGLDisplayType = void *;
|
||||
struct PlatformMethods;
|
||||
|
||||
// Use a C-like API to not trigger undefined calling behaviour.
|
||||
// Avoid using decltype here to work around sanitizer limitations.
|
||||
// TODO(jmadill): Use decltype here if/when UBSAN is fixed.
|
||||
|
||||
// System --------------------------------------------------------------
|
||||
|
||||
// Wall clock time in seconds since the epoch.
|
||||
// TODO(jmadill): investigate using an ANGLE internal time library
|
||||
using CurrentTimeFunc = double (*)(PlatformMethods *platform);
|
||||
inline double DefaultCurrentTime(PlatformMethods *platform)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Monotonically increasing time in seconds from an arbitrary fixed point in the past.
|
||||
// This function is expected to return at least millisecond-precision values. For this reason,
|
||||
// it is recommended that the fixed point be no further in the past than the epoch.
|
||||
using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform);
|
||||
inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// Logging ------------------------------------------------------------
|
||||
|
||||
// Log an error message within the platform implementation.
|
||||
using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage);
|
||||
inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage)
|
||||
{
|
||||
}
|
||||
|
||||
// Log a warning message within the platform implementation.
|
||||
using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage);
|
||||
inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage)
|
||||
{
|
||||
}
|
||||
|
||||
// Log an info message within the platform implementation.
|
||||
using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage);
|
||||
inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage)
|
||||
{
|
||||
}
|
||||
|
||||
// Tracing --------
|
||||
|
||||
// Get a pointer to the enabled state of the given trace category. The
|
||||
// embedder can dynamically change the enabled state as trace event
|
||||
// recording is started and stopped by the application. Only long-lived
|
||||
// literal strings should be given as the category name. The implementation
|
||||
// expects the returned pointer to be held permanently in a local static. If
|
||||
// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
|
||||
// addTraceEvent is expected to be called by the trace event macros.
|
||||
using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform,
|
||||
const char *categoryName);
|
||||
inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform,
|
||||
const char *categoryName)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Add a trace event to the platform tracing system. Depending on the actual
|
||||
// enabled state, this event may be recorded or dropped.
|
||||
// - phase specifies the type of event:
|
||||
// - BEGIN ('B'): Marks the beginning of a scoped event.
|
||||
// - END ('E'): Marks the end of a scoped event.
|
||||
// - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't
|
||||
// need a matching END event. Instead, at the end of the scope,
|
||||
// updateTraceEventDuration() must be called with the TraceEventHandle
|
||||
// returned from addTraceEvent().
|
||||
// - INSTANT ('I'): Standalone, instantaneous event.
|
||||
// - START ('S'): Marks the beginning of an asynchronous event (the end
|
||||
// event can occur in a different scope or thread). The id parameter is
|
||||
// used to match START/FINISH pairs.
|
||||
// - FINISH ('F'): Marks the end of an asynchronous event.
|
||||
// - COUNTER ('C'): Used to trace integer quantities that change over
|
||||
// time. The argument values are expected to be of type int.
|
||||
// - METADATA ('M'): Reserved for internal use.
|
||||
// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.
|
||||
// - name is the name of the event. Also used to match BEGIN/END and
|
||||
// START/FINISH pairs.
|
||||
// - id optionally allows events of the same name to be distinguished from
|
||||
// each other. For example, to trace the consutruction and destruction of
|
||||
// objects, specify the pointer as the id parameter.
|
||||
// - timestamp should be a time value returned from monotonicallyIncreasingTime.
|
||||
// - numArgs specifies the number of elements in argNames, argTypes, and
|
||||
// argValues.
|
||||
// - argNames is the array of argument names. Use long-lived literal strings
|
||||
// or specify the COPY flag.
|
||||
// - argTypes is the array of argument types:
|
||||
// - BOOL (1): bool
|
||||
// - UINT (2): unsigned long long
|
||||
// - INT (3): long long
|
||||
// - DOUBLE (4): double
|
||||
// - POINTER (5): void*
|
||||
// - STRING (6): char* (long-lived null-terminated char* string)
|
||||
// - COPY_STRING (7): char* (temporary null-terminated char* string)
|
||||
// - CONVERTABLE (8): WebConvertableToTraceFormat
|
||||
// - argValues is the array of argument values. Each value is the unsigned
|
||||
// long long member of a union of all supported types.
|
||||
// - flags can be 0 or one or more of the following, ORed together:
|
||||
// - COPY (0x1): treat all strings (name, argNames and argValues of type
|
||||
// string) as temporary so that they will be copied by addTraceEvent.
|
||||
// - HAS_ID (0x2): use the id argument to uniquely identify the event for
|
||||
// matching with other events of the same name.
|
||||
// - MANGLE_ID (0x4): specify this flag if the id parameter is the value
|
||||
// of a pointer.
|
||||
using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform,
|
||||
char phase,
|
||||
const unsigned char *categoryEnabledFlag,
|
||||
const char *name,
|
||||
unsigned long long id,
|
||||
double timestamp,
|
||||
int numArgs,
|
||||
const char **argNames,
|
||||
const unsigned char *argTypes,
|
||||
const unsigned long long *argValues,
|
||||
unsigned char flags);
|
||||
inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform,
|
||||
char phase,
|
||||
const unsigned char *categoryEnabledFlag,
|
||||
const char *name,
|
||||
unsigned long long id,
|
||||
double timestamp,
|
||||
int numArgs,
|
||||
const char **argNames,
|
||||
const unsigned char *argTypes,
|
||||
const unsigned long long *argValues,
|
||||
unsigned char flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the duration field of a COMPLETE trace event.
|
||||
using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform,
|
||||
const unsigned char *categoryEnabledFlag,
|
||||
const char *name,
|
||||
angle::TraceEventHandle eventHandle);
|
||||
inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform,
|
||||
const unsigned char *categoryEnabledFlag,
|
||||
const char *name,
|
||||
angle::TraceEventHandle eventHandle)
|
||||
{
|
||||
}
|
||||
|
||||
// Callbacks for reporting histogram data.
|
||||
// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50
|
||||
// would do.
|
||||
using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform,
|
||||
const char *name,
|
||||
int sample,
|
||||
int min,
|
||||
int max,
|
||||
int bucketCount);
|
||||
inline void DefaultHistogramCustomCounts(PlatformMethods *platform,
|
||||
const char *name,
|
||||
int sample,
|
||||
int min,
|
||||
int max,
|
||||
int bucketCount)
|
||||
{
|
||||
}
|
||||
// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample
|
||||
// value.
|
||||
using HistogramEnumerationFunc = void (*)(PlatformMethods *platform,
|
||||
const char *name,
|
||||
int sample,
|
||||
int boundaryValue);
|
||||
inline void DefaultHistogramEnumeration(PlatformMethods *platform,
|
||||
const char *name,
|
||||
int sample,
|
||||
int boundaryValue)
|
||||
{
|
||||
}
|
||||
// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
|
||||
using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample);
|
||||
inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample)
|
||||
{
|
||||
}
|
||||
// Boolean histograms track two-state variables.
|
||||
using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample);
|
||||
inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample)
|
||||
{
|
||||
}
|
||||
|
||||
// Allows us to programatically override ANGLE's default workarounds for testing purposes.
|
||||
using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform,
|
||||
angle::WorkaroundsD3D *workaroundsD3D);
|
||||
inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform,
|
||||
angle::WorkaroundsD3D *workaroundsD3D)
|
||||
{
|
||||
}
|
||||
|
||||
// Callback on a successful program link with the program binary. Can be used to store
|
||||
// shaders to disk. Keys are a 160-bit SHA-1 hash.
|
||||
using ProgramKeyType = std::array<uint8_t, 20>;
|
||||
using CacheProgramFunc = void (*)(PlatformMethods *platform,
|
||||
const ProgramKeyType &key,
|
||||
size_t programSize,
|
||||
const uint8_t *programBytes);
|
||||
inline void DefaultCacheProgram(PlatformMethods *platform,
|
||||
const ProgramKeyType &key,
|
||||
size_t programSize,
|
||||
const uint8_t *programBytes)
|
||||
{
|
||||
}
|
||||
|
||||
// Platform methods are enumerated here once.
|
||||
#define ANGLE_PLATFORM_OP(OP) \
|
||||
OP(currentTime, CurrentTime) \
|
||||
OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \
|
||||
OP(logError, LogError) \
|
||||
OP(logWarning, LogWarning) \
|
||||
OP(logInfo, LogInfo) \
|
||||
OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \
|
||||
OP(addTraceEvent, AddTraceEvent) \
|
||||
OP(updateTraceEventDuration, UpdateTraceEventDuration) \
|
||||
OP(histogramCustomCounts, HistogramCustomCounts) \
|
||||
OP(histogramEnumeration, HistogramEnumeration) \
|
||||
OP(histogramSparse, HistogramSparse) \
|
||||
OP(histogramBoolean, HistogramBoolean) \
|
||||
OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D) \
|
||||
OP(cacheProgram, CacheProgram)
|
||||
|
||||
#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;
|
||||
|
||||
struct PlatformMethods
|
||||
{
|
||||
// User data pointer for any implementation specific members. Put it at the start of the
|
||||
// platform structure so it doesn't become overwritten if one version of the platform
|
||||
// adds or removes new members.
|
||||
void *context = 0;
|
||||
|
||||
ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF);
|
||||
};
|
||||
|
||||
#undef ANGLE_PLATFORM_METHOD_DEF
|
||||
|
||||
// Subtract one to account for the context pointer.
|
||||
constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1;
|
||||
|
||||
#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name
|
||||
#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name),
|
||||
|
||||
constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = {
|
||||
ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)};
|
||||
|
||||
#undef ANGLE_PLATFORM_METHOD_STRING2
|
||||
#undef ANGLE_PLATFORM_METHOD_STRING
|
||||
|
||||
} // namespace angle
|
||||
|
||||
extern "C" {
|
||||
|
||||
// Gets the platform methods on the passed-in EGL display. If the method name signature does not
|
||||
// match the compiled signature for this ANGLE, false is returned. On success true is returned.
|
||||
// The application should set any platform methods it cares about on the returned pointer.
|
||||
// If display is not valid, behaviour is undefined.
|
||||
|
||||
ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
|
||||
const char *const methodNames[],
|
||||
unsigned int methodNameCount,
|
||||
void *context,
|
||||
void *platformMethodsOut);
|
||||
|
||||
// Sets the platform methods back to their defaults.
|
||||
// If display is not valid, behaviour is undefined.
|
||||
ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType,
|
||||
const char *const *,
|
||||
unsigned int,
|
||||
void *,
|
||||
void *);
|
||||
typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType);
|
||||
} // namespace angle
|
||||
|
||||
// This function is not exported
|
||||
angle::PlatformMethods *ANGLEPlatformCurrent();
|
||||
|
||||
#endif // ANGLE_PLATFORM_H
|
|
@ -1,119 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2015 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.
|
||||
//
|
||||
|
||||
// WorkaroundsD3D.h: Workarounds for D3D driver bugs and other issues.
|
||||
|
||||
#ifndef ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
||||
#define ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
||||
|
||||
// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate
|
||||
// independent of ANGLE's renderer. Workarounds should also be accessible
|
||||
// outside of the Renderer.
|
||||
|
||||
namespace angle
|
||||
{
|
||||
struct CompilerWorkaroundsD3D
|
||||
{
|
||||
bool skipOptimization = false;
|
||||
bool useMaxOptimization = false;
|
||||
|
||||
// IEEE strictness needs to be enabled for NANs to work.
|
||||
bool enableIEEEStrictness = false;
|
||||
};
|
||||
|
||||
struct WorkaroundsD3D
|
||||
{
|
||||
// On some systems, having extra rendertargets than necessary slows down the shader.
|
||||
// We can fix this by optimizing those out of the shader. At the same time, we can
|
||||
// work around a bug on some nVidia drivers that they ignore "null" render targets
|
||||
// in D3D11, by compacting the active color attachments list to omit null entries.
|
||||
bool mrtPerfWorkaround = false;
|
||||
|
||||
bool setDataFasterThanImageUpload = false;
|
||||
|
||||
// Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level
|
||||
// zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to
|
||||
// 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. There is no
|
||||
// equivalent to this in D3D11 Feature Level 9_3. This causes problems when (for example) an
|
||||
// application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST
|
||||
// (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the
|
||||
// texture. The textures' level zeros are identical, but only one texture has mips.
|
||||
bool zeroMaxLodWorkaround = false;
|
||||
|
||||
// Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite
|
||||
// emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite
|
||||
// emulation that is implemented using instanced quads.
|
||||
bool useInstancedPointSpriteEmulation = false;
|
||||
|
||||
// A bug fixed in NVIDIA driver version 347.88 < x <= 368.81 triggers a TDR when using
|
||||
// CopySubresourceRegion from a staging texture to a depth/stencil in D3D11. The workaround
|
||||
// is to use UpdateSubresource to trigger an extra copy. We disable this workaround on newer
|
||||
// NVIDIA driver versions because of a second driver bug present with the workaround enabled.
|
||||
// (See: http://anglebug.com/1452)
|
||||
bool depthStencilBlitExtraCopy = false;
|
||||
|
||||
// The HLSL optimizer has a bug with optimizing "pow" in certain integer-valued expressions.
|
||||
// We can work around this by expanding the pow into a series of multiplies if we're running
|
||||
// under the affected compiler.
|
||||
bool expandIntegerPowExpressions = false;
|
||||
|
||||
// NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform
|
||||
// feedback is used to repeatedly write to the same buffer positions.
|
||||
bool flushAfterEndingTransformFeedback = false;
|
||||
|
||||
// Some drivers (NVIDIA) do not take into account the base level of the texture in the results
|
||||
// of the HLSL GetDimensions builtin.
|
||||
bool getDimensionsIgnoresBaseLevel = false;
|
||||
|
||||
// On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location
|
||||
// is negative, even if the sum of Offset and Location is in range. This may cause errors when
|
||||
// translating GLSL's function texelFetchOffset into texture.Load, as it is valid for
|
||||
// texelFetchOffset to use negative texture coordinates as its parameter P when the sum of P
|
||||
// and Offset is in range. To work around this, we translate texelFetchOffset into texelFetch
|
||||
// by adding Offset directly to Location before reading the texture.
|
||||
bool preAddTexelFetchOffsets = false;
|
||||
|
||||
// On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly.
|
||||
// We can work around this bug by doing an internal blit to a temporary single-channel texture
|
||||
// before we sample.
|
||||
bool emulateTinyStencilTextures = false;
|
||||
|
||||
// In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly.
|
||||
// This workaroud will disable B5G6R5 support when it's Intel driver. By default, it will use
|
||||
// R8G8B8A8 format. This bug is fixed in version 4539 on Intel drivers.
|
||||
bool disableB5G6R5Support = false;
|
||||
|
||||
// On some Intel drivers, evaluating unary minus operator on integer may get wrong answer in
|
||||
// vertex shaders. To work around this bug, we translate -(int) into ~(int)+1.
|
||||
// This driver bug is fixed in 20.19.15.4624.
|
||||
bool rewriteUnaryMinusOperator = false;
|
||||
|
||||
// On some Intel drivers, using isnan() on highp float will get wrong answer. To work around
|
||||
// this bug, we use an expression to emulate function isnan().
|
||||
// Tracking bug: https://crbug.com/650547
|
||||
// This driver bug is fixed in 21.20.16.4542.
|
||||
bool emulateIsnanFloat = false;
|
||||
|
||||
// On some Intel drivers, using clear() may not take effect. One of such situation is to clear
|
||||
// a target with width or height < 16. To work around this bug, we call clear() twice on these
|
||||
// platforms. Tracking bug: https://crbug.com/655534
|
||||
bool callClearTwice = false;
|
||||
|
||||
// On some Intel drivers, copying from staging storage to constant buffer storage does not
|
||||
// seem to work. Work around this by keeping system memory storage as a canonical reference
|
||||
// for buffer data.
|
||||
// D3D11-only workaround. See http://crbug.com/593024.
|
||||
bool useSystemMemoryForConstantBuffers = false;
|
||||
|
||||
// This workaround is for the ANGLE_multiview extension. If enabled the viewport or render
|
||||
// target slice will be selected in the geometry shader stage. The workaround flag is added to
|
||||
// make it possible to select the code path in end2end and performance tests.
|
||||
bool selectViewInGeometryShader = false;
|
||||
};
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
|
@ -1,476 +0,0 @@
|
|||
# Copyright (c) 2012 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.
|
||||
|
||||
{
|
||||
'variables':
|
||||
{
|
||||
'angle_code': 1,
|
||||
'angle_gen_path': '<(SHARED_INTERMEDIATE_DIR)/angle',
|
||||
'angle_id_script_base': 'commit_id.py',
|
||||
'angle_id_script': '<(angle_gen_path)/<(angle_id_script_base)',
|
||||
'angle_id_header_base': 'commit.h',
|
||||
'angle_id_header': '<(angle_gen_path)/id/<(angle_id_header_base)',
|
||||
'angle_use_commit_id%': '<!(python <(angle_id_script_base) check ..)',
|
||||
'angle_enable_d3d9%': 0,
|
||||
'angle_enable_d3d11%': 0,
|
||||
'angle_enable_gl%': 0,
|
||||
'angle_enable_vulkan%': 0,
|
||||
'angle_enable_essl%': 1, # Enable this for all configs by default
|
||||
'angle_enable_glsl%': 1, # Enable this for all configs by default
|
||||
'angle_enable_hlsl%': 0,
|
||||
'angle_link_glx%': 0,
|
||||
'angle_gl_library_type%': 'shared_library',
|
||||
'dcheck_always_on%': 0,
|
||||
'conditions':
|
||||
[
|
||||
['OS=="win"',
|
||||
{
|
||||
'angle_enable_gl%': 1,
|
||||
'angle_enable_d3d9%': 1,
|
||||
'angle_enable_d3d11%': 1,
|
||||
'angle_enable_hlsl%': 1,
|
||||
'angle_enable_vulkan%': 1,
|
||||
}],
|
||||
['OS=="linux" and use_x11==1 and chromeos==0',
|
||||
{
|
||||
'angle_enable_gl%': 1,
|
||||
'angle_enable_vulkan%': 1,
|
||||
}],
|
||||
['OS=="mac"',
|
||||
{
|
||||
'angle_enable_gl%': 1,
|
||||
}],
|
||||
['use_ozone==1',
|
||||
{
|
||||
'angle_enable_gl%': 1,
|
||||
}],
|
||||
],
|
||||
'angle_enable_null%': 1, # Available on all platforms
|
||||
},
|
||||
'includes':
|
||||
[
|
||||
'compiler.gypi',
|
||||
'libGLESv2.gypi',
|
||||
'libEGL.gypi',
|
||||
'vulkan_support/vulkan.gypi',
|
||||
],
|
||||
|
||||
'targets':
|
||||
[
|
||||
{
|
||||
'target_name': 'angle_common',
|
||||
'type': 'static_library',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_common_sources)',
|
||||
],
|
||||
'include_dirs':
|
||||
[
|
||||
'.',
|
||||
'../include',
|
||||
'common/third_party/base',
|
||||
],
|
||||
'dependencies':
|
||||
[
|
||||
'commit_id',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'include_dirs':
|
||||
[
|
||||
'<(angle_path)/include',
|
||||
'<(angle_path)/src',
|
||||
'<(angle_path)/src/common/third_party/base',
|
||||
],
|
||||
'conditions':
|
||||
[
|
||||
['dcheck_always_on==1',
|
||||
{
|
||||
'configurations':
|
||||
{
|
||||
'Release_Base':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_RELEASE_ASSERTS',
|
||||
],
|
||||
},
|
||||
},
|
||||
}],
|
||||
['OS=="win"',
|
||||
{
|
||||
'configurations':
|
||||
{
|
||||
'Debug_Base':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_DEBUG_ANNOTATIONS'
|
||||
],
|
||||
},
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
'conditions':
|
||||
[
|
||||
['dcheck_always_on==1',
|
||||
{
|
||||
'configurations':
|
||||
{
|
||||
'Release_Base':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_RELEASE_ASSERTS',
|
||||
],
|
||||
},
|
||||
},
|
||||
}],
|
||||
['OS=="win"',
|
||||
{
|
||||
'configurations':
|
||||
{
|
||||
'Debug_Base':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_DEBUG_ANNOTATIONS'
|
||||
],
|
||||
},
|
||||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_common_win_sources)',
|
||||
],
|
||||
}],
|
||||
['OS=="mac"',
|
||||
{
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_common_mac_sources)',
|
||||
],
|
||||
'link_settings':
|
||||
{
|
||||
'libraries':
|
||||
[
|
||||
'$(SDKROOT)/System/Library/Frameworks/IOKit.framework',
|
||||
'$(SDKROOT)/System/Library/Frameworks/CoreFoundation.framework',
|
||||
],
|
||||
},
|
||||
}],
|
||||
['OS=="linux"',
|
||||
{
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_common_linux_sources)',
|
||||
],
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
'target_name': 'angle_image_util',
|
||||
'type': 'static_library',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_image_util_sources)',
|
||||
],
|
||||
'include_dirs':
|
||||
[
|
||||
'.',
|
||||
'../include',
|
||||
],
|
||||
'dependencies':
|
||||
[
|
||||
'angle_common',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'include_dirs':
|
||||
[
|
||||
'<(angle_path)/include',
|
||||
'<(angle_path)/src',
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
'target_name': 'angle_gpu_info_util',
|
||||
'type': 'static_library',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_gpu_info_util_sources)',
|
||||
],
|
||||
'include_dirs':
|
||||
[
|
||||
'.',
|
||||
'../include',
|
||||
],
|
||||
'dependencies':
|
||||
[
|
||||
'angle_common',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'include_dirs':
|
||||
[
|
||||
'<(angle_path)/include',
|
||||
'<(angle_path)/src',
|
||||
],
|
||||
},
|
||||
'conditions':
|
||||
[
|
||||
['OS=="win"',
|
||||
{
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_gpu_info_util_win_sources)',
|
||||
],
|
||||
}],
|
||||
['OS=="win" and angle_build_winrt==0',
|
||||
{
|
||||
'link_settings':
|
||||
{
|
||||
'msvs_settings':
|
||||
{
|
||||
'VCLinkerTool':
|
||||
{
|
||||
'AdditionalDependencies':
|
||||
[
|
||||
'setupapi.lib'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
'defines':
|
||||
[
|
||||
'GPU_INFO_USE_SETUPAPI',
|
||||
],
|
||||
},
|
||||
{
|
||||
'link_settings':
|
||||
{
|
||||
'msvs_settings':
|
||||
{
|
||||
'VCLinkerTool':
|
||||
{
|
||||
'AdditionalDependencies':
|
||||
[
|
||||
'dxgi.lib'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
'defines':
|
||||
[
|
||||
'GPU_INFO_USE_DXGI',
|
||||
],
|
||||
}],
|
||||
['OS=="linux"',
|
||||
{
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_gpu_info_util_linux_sources)',
|
||||
],
|
||||
}],
|
||||
['OS=="linux" and use_x11==1',
|
||||
{
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_gpu_info_util_x11_sources)',
|
||||
],
|
||||
'defines':
|
||||
[
|
||||
'GPU_INFO_USE_X11',
|
||||
],
|
||||
'dependencies':
|
||||
[
|
||||
'<(angle_path)/src/third_party/libXNVCtrl/libXNVCtrl.gyp:libXNVCtrl',
|
||||
],
|
||||
'link_settings':
|
||||
{
|
||||
'ldflags':
|
||||
[
|
||||
'<!@(<(pkg-config) --libs-only-L --libs-only-other x11 xi xext)',
|
||||
],
|
||||
'libraries':
|
||||
[
|
||||
'<!@(<(pkg-config) --libs-only-l x11 xi xext) -ldl',
|
||||
],
|
||||
},
|
||||
}],
|
||||
['OS=="linux" and use_libpci==1',
|
||||
{
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_gpu_info_util_libpci_sources)',
|
||||
],
|
||||
'defines':
|
||||
[
|
||||
'GPU_INFO_USE_LIBPCI',
|
||||
],
|
||||
'link_settings':
|
||||
{
|
||||
'ldflags':
|
||||
[
|
||||
'<!@(<(pkg-config) --libs-only-L --libs-only-other libpci)',
|
||||
],
|
||||
'libraries':
|
||||
[
|
||||
'<!@(<(pkg-config) --libs-only-l libpci)',
|
||||
],
|
||||
},
|
||||
}],
|
||||
['OS=="mac"',
|
||||
{
|
||||
'sources':
|
||||
[
|
||||
'<@(libangle_gpu_info_util_mac_sources)',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
'target_name': 'copy_scripts',
|
||||
'type': 'none',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'hard_dependency': 1,
|
||||
'copies':
|
||||
[
|
||||
{
|
||||
'destination': '<(angle_gen_path)',
|
||||
'files': [ 'copy_compiler_dll.bat', '<(angle_id_script_base)' ],
|
||||
},
|
||||
],
|
||||
'conditions':
|
||||
[
|
||||
['angle_build_winrt==1',
|
||||
{
|
||||
'type' : 'shared_library',
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
'conditions':
|
||||
[
|
||||
['angle_use_commit_id!=0',
|
||||
{
|
||||
'targets':
|
||||
[
|
||||
{
|
||||
'target_name': 'commit_id',
|
||||
'type': 'none',
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'dependencies': [ 'copy_scripts', ],
|
||||
'hard_dependency': 1,
|
||||
'actions':
|
||||
[
|
||||
{
|
||||
'action_name': 'Generate ANGLE Commit ID Header',
|
||||
'message': 'Generating ANGLE Commit ID',
|
||||
# reference the git index as an input, so we rebuild on changes to the index
|
||||
'inputs': [ '<(angle_id_script)', '<(angle_path)/.git/index' ],
|
||||
'outputs': [ '<(angle_id_header)' ],
|
||||
'msvs_cygwin_shell': 0,
|
||||
'action':
|
||||
[
|
||||
'python', '<(angle_id_script)', 'gen', '<(angle_path)', '<(angle_id_header)'
|
||||
],
|
||||
},
|
||||
],
|
||||
'all_dependent_settings':
|
||||
{
|
||||
'include_dirs':
|
||||
[
|
||||
'<(angle_gen_path)',
|
||||
],
|
||||
},
|
||||
'conditions':
|
||||
[
|
||||
['angle_build_winrt==1',
|
||||
{
|
||||
'type' : 'shared_library',
|
||||
}],
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
{ # angle_use_commit_id==0
|
||||
'targets':
|
||||
[
|
||||
{
|
||||
'target_name': 'commit_id',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'copies':
|
||||
[
|
||||
{
|
||||
'destination': '<(angle_gen_path)/id',
|
||||
'files': [ '<(angle_id_header_base)' ]
|
||||
}
|
||||
],
|
||||
'all_dependent_settings':
|
||||
{
|
||||
'include_dirs':
|
||||
[
|
||||
'<(angle_gen_path)',
|
||||
],
|
||||
},
|
||||
'conditions':
|
||||
[
|
||||
['angle_build_winrt==1',
|
||||
{
|
||||
'type' : 'shared_library',
|
||||
}],
|
||||
],
|
||||
}
|
||||
]
|
||||
}],
|
||||
['OS=="win"',
|
||||
{
|
||||
'targets':
|
||||
[
|
||||
{
|
||||
'target_name': 'copy_compiler_dll',
|
||||
'type': 'none',
|
||||
'dependencies': [ 'copy_scripts', ],
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'conditions':
|
||||
[
|
||||
['angle_build_winrt==0',
|
||||
{
|
||||
'actions':
|
||||
[
|
||||
{
|
||||
'action_name': 'copy_dll',
|
||||
'message': 'Copying D3D Compiler DLL...',
|
||||
'msvs_cygwin_shell': 0,
|
||||
'inputs': [ 'copy_compiler_dll.bat' ],
|
||||
'outputs': [ '<(PRODUCT_DIR)/d3dcompiler_47.dll' ],
|
||||
'action':
|
||||
[
|
||||
"<(angle_gen_path)/copy_compiler_dll.bat",
|
||||
"$(PlatformName)",
|
||||
"<(windows_sdk_path)",
|
||||
"<(PRODUCT_DIR)"
|
||||
],
|
||||
},
|
||||
], #actions
|
||||
}],
|
||||
['angle_build_winrt==1',
|
||||
{
|
||||
'type' : 'shared_library',
|
||||
}],
|
||||
]
|
||||
},
|
||||
], # targets
|
||||
}],
|
||||
] # conditions
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
// commit.h:
|
||||
// This is a default commit hash header, when git is not available.
|
||||
//
|
||||
|
||||
#define ANGLE_COMMIT_HASH "unknown hash"
|
||||
#define ANGLE_COMMIT_HASH_SIZE 12
|
||||
#define ANGLE_COMMIT_DATE "unknown date"
|
||||
|
||||
#define ANGLE_DISABLE_PROGRAM_BINARY_LOAD
|
|
@ -1,42 +0,0 @@
|
|||
import subprocess as sp
|
||||
import sys
|
||||
import os
|
||||
|
||||
usage = """\
|
||||
Usage: commit_id.py check <angle_dir> - check if git is present
|
||||
commit_id.py gen <angle_dir> <file_to_write> - generate commit.h"""
|
||||
|
||||
def grab_output(command, cwd):
|
||||
return sp.Popen(command, stdout=sp.PIPE, shell=True, cwd=cwd).communicate()[0].strip()
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
sys.exit(usage)
|
||||
|
||||
operation = sys.argv[1]
|
||||
cwd = sys.argv[2]
|
||||
|
||||
if operation == 'check':
|
||||
index_path = os.path.join(cwd, '.git', 'index')
|
||||
if os.path.exists(index_path):
|
||||
print("1")
|
||||
else:
|
||||
print("0")
|
||||
sys.exit(0)
|
||||
|
||||
output_file = sys.argv[3]
|
||||
commit_id_size = 12
|
||||
|
||||
try:
|
||||
commit_id = grab_output('git rev-parse --short=%d HEAD' % commit_id_size, cwd)
|
||||
commit_date = grab_output('git show -s --format=%ci HEAD', cwd)
|
||||
except:
|
||||
commit_id = 'invalid-hash'
|
||||
commit_date = 'invalid-date'
|
||||
|
||||
hfile = open(output_file, 'w')
|
||||
|
||||
hfile.write('#define ANGLE_COMMIT_HASH "%s"\n' % commit_id)
|
||||
hfile.write('#define ANGLE_COMMIT_HASH_SIZE %d\n' % commit_id_size)
|
||||
hfile.write('#define ANGLE_COMMIT_DATE "%s"\n' % commit_date)
|
||||
|
||||
hfile.close()
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2016 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.
|
||||
//
|
||||
|
||||
// Color.h : Defines the Color type used throughout the ANGLE libraries
|
||||
|
||||
#ifndef COMMON_COLOR_H_
|
||||
#define COMMON_COLOR_H_
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct Color
|
||||
{
|
||||
T red;
|
||||
T green;
|
||||
T blue;
|
||||
T alpha;
|
||||
|
||||
Color();
|
||||
Color(T r, T g, T b, T a);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool operator==(const Color<T> &a, const Color<T> &b);
|
||||
|
||||
template <typename T>
|
||||
bool operator!=(const Color<T> &a, const Color<T> &b);
|
||||
|
||||
typedef Color<float> ColorF;
|
||||
typedef Color<int> ColorI;
|
||||
typedef Color<unsigned int> ColorUI;
|
||||
|
||||
} // namespace angle
|
||||
|
||||
// TODO: Move this fully into the angle namespace
|
||||
namespace gl
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
using Color = angle::Color<T>;
|
||||
using ColorF = angle::ColorF;
|
||||
using ColorI = angle::ColorI;
|
||||
using ColorUI = angle::ColorUI;
|
||||
|
||||
} // namespace gl
|
||||
|
||||
#include "Color.inl"
|
||||
|
||||
#endif // COMMON_COLOR_H_
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2016 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.
|
||||
//
|
||||
|
||||
// Color.inl : Inline definitions of some functions from Color.h
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
Color<T>::Color() : Color(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Color<T>::Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator==(const Color<T> &a, const Color<T> &b)
|
||||
{
|
||||
return a.red == b.red &&
|
||||
a.green == b.green &&
|
||||
a.blue == b.blue &&
|
||||
a.alpha == b.alpha;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator!=(const Color<T> &a, const Color<T> &b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
} // namespace angle
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,80 +0,0 @@
|
|||
# Copyright (c) 2012 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.
|
||||
#
|
||||
|
||||
# This script generates a function that converts 16-bit precision floating
|
||||
# point numbers to 32-bit.
|
||||
# It is based on ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf.
|
||||
|
||||
#include "common/mathutil.h"
|
||||
|
||||
def convertMantissa(i):
|
||||
if i == 0:
|
||||
return 0
|
||||
elif i < 1024:
|
||||
m = i << 13
|
||||
e = 0
|
||||
while not (m & 0x00800000):
|
||||
e -= 0x00800000
|
||||
m = m << 1
|
||||
m &= ~0x00800000
|
||||
e += 0x38800000
|
||||
return m | e
|
||||
else:
|
||||
return 0x38000000 + ((i - 1024) << 13)
|
||||
|
||||
def convertExponent(i):
|
||||
if i == 0:
|
||||
return 0
|
||||
elif i in range(1, 31):
|
||||
return i << 23
|
||||
elif i == 31:
|
||||
return 0x47800000
|
||||
elif i == 32:
|
||||
return 0x80000000
|
||||
elif i in range(33, 63):
|
||||
return 0x80000000 + ((i - 32) << 23)
|
||||
else:
|
||||
return 0xC7800000
|
||||
|
||||
def convertOffset(i):
|
||||
if i == 0 or i == 32:
|
||||
return 0
|
||||
else:
|
||||
return 1024
|
||||
|
||||
print """//
|
||||
// Copyright (c) 2012 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.
|
||||
//
|
||||
|
||||
// This file is automatically generated.
|
||||
|
||||
namespace gl
|
||||
{
|
||||
"""
|
||||
|
||||
print "const static unsigned g_mantissa[2048] = {"
|
||||
for i in range(0, 2048):
|
||||
print " %#010x," % convertMantissa(i)
|
||||
print "};\n"
|
||||
|
||||
print "const static unsigned g_exponent[64] = {"
|
||||
for i in range(0, 64):
|
||||
print " %#010x," % convertExponent(i)
|
||||
print "};\n"
|
||||
|
||||
print "const static unsigned g_offset[64] = {"
|
||||
for i in range(0, 64):
|
||||
print " %#010x," % convertOffset(i)
|
||||
print "};\n"
|
||||
|
||||
print """float float16ToFloat32(unsigned short h)
|
||||
{
|
||||
unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10];
|
||||
return bitCast<float>(i32);
|
||||
}
|
||||
}
|
||||
"""
|
|
@ -1,155 +0,0 @@
|
|||
//
|
||||
// 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 "common/MemoryBuffer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
// MemoryBuffer implementation.
|
||||
MemoryBuffer::MemoryBuffer() : mSize(0), mData(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBuffer::~MemoryBuffer()
|
||||
{
|
||||
free(mData);
|
||||
mData = nullptr;
|
||||
}
|
||||
|
||||
bool MemoryBuffer::resize(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
free(mData);
|
||||
mData = nullptr;
|
||||
mSize = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (size == mSize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Only reallocate if the size has changed.
|
||||
uint8_t *newMemory = reinterpret_cast<uint8_t *>(malloc(sizeof(uint8_t) * size));
|
||||
if (newMemory == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mData)
|
||||
{
|
||||
// Copy the intersection of the old data and the new data
|
||||
std::copy(mData, mData + std::min(mSize, size), newMemory);
|
||||
free(mData);
|
||||
}
|
||||
|
||||
mData = newMemory;
|
||||
mSize = size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemoryBuffer::fill(uint8_t datum)
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
std::fill(mData, mData + mSize, datum);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) : MemoryBuffer()
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
MemoryBuffer &MemoryBuffer::operator=(MemoryBuffer &&other)
|
||||
{
|
||||
std::swap(mSize, other.mSize);
|
||||
std::swap(mData, other.mData);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ScratchBuffer implementation.
|
||||
|
||||
ScratchBuffer::ScratchBuffer(uint32_t lifetime) : mLifetime(lifetime), mResetCounter(lifetime)
|
||||
{
|
||||
}
|
||||
|
||||
ScratchBuffer::~ScratchBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
bool ScratchBuffer::get(size_t requestedSize, MemoryBuffer **memoryBufferOut)
|
||||
{
|
||||
return getImpl(requestedSize, memoryBufferOut, Optional<uint8_t>::Invalid());
|
||||
}
|
||||
|
||||
bool ScratchBuffer::getInitialized(size_t requestedSize,
|
||||
MemoryBuffer **memoryBufferOut,
|
||||
uint8_t initValue)
|
||||
{
|
||||
return getImpl(requestedSize, memoryBufferOut, Optional<uint8_t>(initValue));
|
||||
}
|
||||
|
||||
bool ScratchBuffer::getImpl(size_t requestedSize,
|
||||
MemoryBuffer **memoryBufferOut,
|
||||
Optional<uint8_t> initValue)
|
||||
{
|
||||
if (mScratchMemory.size() == requestedSize)
|
||||
{
|
||||
mResetCounter = mLifetime;
|
||||
*memoryBufferOut = &mScratchMemory;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mScratchMemory.size() > requestedSize)
|
||||
{
|
||||
tick();
|
||||
}
|
||||
|
||||
if (mResetCounter == 0 || mScratchMemory.size() < requestedSize)
|
||||
{
|
||||
mScratchMemory.resize(0);
|
||||
if (!mScratchMemory.resize(requestedSize))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mResetCounter = mLifetime;
|
||||
if (initValue.valid())
|
||||
{
|
||||
mScratchMemory.fill(initValue.value());
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(mScratchMemory.size() >= requestedSize);
|
||||
|
||||
*memoryBufferOut = &mScratchMemory;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScratchBuffer::tick()
|
||||
{
|
||||
if (mResetCounter > 0)
|
||||
{
|
||||
--mResetCounter;
|
||||
}
|
||||
}
|
||||
|
||||
void ScratchBuffer::clear()
|
||||
{
|
||||
mResetCounter = mLifetime;
|
||||
mScratchMemory.resize(0);
|
||||
}
|
||||
|
||||
} // namespace angle
|
|
@ -1,77 +0,0 @@
|
|||
//
|
||||
// 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 COMMON_MEMORYBUFFER_H_
|
||||
#define COMMON_MEMORYBUFFER_H_
|
||||
|
||||
#include "common/Optional.h"
|
||||
#include "common/angleutils.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
class MemoryBuffer final : NonCopyable
|
||||
{
|
||||
public:
|
||||
MemoryBuffer();
|
||||
~MemoryBuffer();
|
||||
|
||||
MemoryBuffer(MemoryBuffer &&other);
|
||||
MemoryBuffer &operator=(MemoryBuffer &&other);
|
||||
|
||||
bool resize(size_t size);
|
||||
size_t size() const { return mSize; }
|
||||
bool empty() const { return mSize == 0; }
|
||||
|
||||
const uint8_t *data() const { return mData; }
|
||||
uint8_t *data()
|
||||
{
|
||||
ASSERT(mData);
|
||||
return mData;
|
||||
}
|
||||
|
||||
void fill(uint8_t datum);
|
||||
|
||||
private:
|
||||
size_t mSize;
|
||||
uint8_t *mData;
|
||||
};
|
||||
|
||||
class ScratchBuffer final : NonCopyable
|
||||
{
|
||||
public:
|
||||
// If we request a scratch buffer requesting a smaller size this many times, release and
|
||||
// recreate the scratch buffer. This ensures we don't have a degenerate case where we are stuck
|
||||
// hogging memory.
|
||||
ScratchBuffer(uint32_t lifetime);
|
||||
~ScratchBuffer();
|
||||
|
||||
// Returns true with a memory buffer of the requested size, or false on failure.
|
||||
bool get(size_t requestedSize, MemoryBuffer **memoryBufferOut);
|
||||
|
||||
// Same as get, but ensures new values are initialized to a fixed constant.
|
||||
bool getInitialized(size_t requestedSize, MemoryBuffer **memoryBufferOut, uint8_t initValue);
|
||||
|
||||
// Ticks the release counter for the scratch buffer. Also done implicitly in get().
|
||||
void tick();
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
bool getImpl(size_t requestedSize, MemoryBuffer **memoryBufferOut, Optional<uint8_t> initValue);
|
||||
|
||||
const uint32_t mLifetime;
|
||||
uint32_t mResetCounter;
|
||||
MemoryBuffer mScratchMemory;
|
||||
};
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // COMMON_MEMORYBUFFER_H_
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2015 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.
|
||||
//
|
||||
// Optional.h:
|
||||
// Represents a type that may be invalid, similar to std::optional.
|
||||
//
|
||||
|
||||
#ifndef COMMON_OPTIONAL_H_
|
||||
#define COMMON_OPTIONAL_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
template <class T>
|
||||
struct Optional
|
||||
{
|
||||
Optional() : mValid(false), mValue(T()) {}
|
||||
|
||||
Optional(const T &valueIn) : mValid(true), mValue(valueIn) {}
|
||||
|
||||
Optional(const Optional &other) : mValid(other.mValid), mValue(other.mValue) {}
|
||||
|
||||
Optional &operator=(const Optional &other)
|
||||
{
|
||||
this->mValid = other.mValid;
|
||||
this->mValue = other.mValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Optional &operator=(const T &value)
|
||||
{
|
||||
mValue = value;
|
||||
mValid = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Optional &operator=(T &&value)
|
||||
{
|
||||
mValue = std::move(value);
|
||||
mValid = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset() { mValid = false; }
|
||||
|
||||
static Optional Invalid() { return Optional(); }
|
||||
|
||||
bool valid() const { return mValid; }
|
||||
const T &value() const { return mValue; }
|
||||
|
||||
bool operator==(const Optional &other) const
|
||||
{
|
||||
return ((mValid == other.mValid) && (!mValid || (mValue == other.mValue)));
|
||||
}
|
||||
|
||||
bool operator!=(const Optional &other) const { return !(*this == other); }
|
||||
|
||||
bool operator==(const T &value) const { return mValid && (mValue == value); }
|
||||
|
||||
bool operator!=(const T &value) const { return !(*this == value); }
|
||||
|
||||
private:
|
||||
bool mValid;
|
||||
T mValue;
|
||||
};
|
||||
|
||||
#endif // COMMON_OPTIONAL_H_
|
|
@ -1,47 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2015 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.
|
||||
//
|
||||
// Unit tests for ANGLE's Optional helper class.
|
||||
//
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "common/Optional.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST(OptionalTest, BasicInvalid)
|
||||
{
|
||||
Optional<int> testInvalid;
|
||||
ASSERT_FALSE(testInvalid.valid());
|
||||
ASSERT_EQ(Optional<int>::Invalid(), testInvalid);
|
||||
}
|
||||
|
||||
TEST(OptionalTest, BasicValid)
|
||||
{
|
||||
Optional<int> testValid(3);
|
||||
ASSERT_TRUE(testValid.valid());
|
||||
ASSERT_EQ(3, testValid.value());
|
||||
ASSERT_NE(Optional<int>::Invalid(), testValid);
|
||||
}
|
||||
|
||||
TEST(OptionalTest, Copies)
|
||||
{
|
||||
Optional<int> testValid(3);
|
||||
Optional<int> testInvalid;
|
||||
|
||||
Optional<int> testCopy = testInvalid;
|
||||
ASSERT_FALSE(testCopy.valid());
|
||||
ASSERT_EQ(testInvalid, testCopy);
|
||||
|
||||
testCopy = testValid;
|
||||
ASSERT_TRUE(testCopy.valid());
|
||||
ASSERT_EQ(3, testCopy.value());
|
||||
ASSERT_EQ(testValid, testCopy);
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -1,44 +0,0 @@
|
|||
//
|
||||
// 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 "common/angleutils.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
const uintptr_t DirtyPointer = std::numeric_limits<uintptr_t>::max();
|
||||
}
|
||||
|
||||
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
|
||||
{
|
||||
// The state of the va_list passed to vsnprintf is undefined after the call, do a copy in case
|
||||
// we need to grow the buffer.
|
||||
va_list varargCopy;
|
||||
va_copy(varargCopy, vararg);
|
||||
|
||||
// Attempt to just print to the current buffer
|
||||
int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, varargCopy);
|
||||
va_end(varargCopy);
|
||||
|
||||
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(nullptr, 0, fmt, vararg);
|
||||
outBuffer.resize(len + 1);
|
||||
|
||||
// Print again
|
||||
va_copy(varargCopy, vararg);
|
||||
len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, varargCopy);
|
||||
va_end(varargCopy);
|
||||
}
|
||||
ASSERT(len >= 0);
|
||||
return static_cast<size_t>(len);
|
||||
}
|
|
@ -1,263 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-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.
|
||||
//
|
||||
|
||||
// angleutils.h: Common ANGLE utilities.
|
||||
|
||||
#ifndef COMMON_ANGLEUTILS_H_
|
||||
#define COMMON_ANGLEUTILS_H_
|
||||
|
||||
#include "common/platform.h"
|
||||
|
||||
#include <climits>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
// A helper class to disallow copy and assignment operators
|
||||
namespace angle
|
||||
{
|
||||
|
||||
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
|
||||
using Microsoft::WRL::ComPtr;
|
||||
#endif // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
|
||||
|
||||
class NonCopyable
|
||||
{
|
||||
protected:
|
||||
NonCopyable() = default;
|
||||
~NonCopyable() = default;
|
||||
|
||||
private:
|
||||
NonCopyable(const NonCopyable&) = delete;
|
||||
void operator=(const NonCopyable&) = delete;
|
||||
};
|
||||
|
||||
extern const uintptr_t DirtyPointer;
|
||||
|
||||
} // namespace angle
|
||||
|
||||
template <typename T, size_t N>
|
||||
constexpr inline size_t ArraySize(T (&)[N])
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class WrappedArray final : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
template <size_t N>
|
||||
constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr WrappedArray() : mArray(nullptr), mSize(0) {}
|
||||
constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {}
|
||||
|
||||
WrappedArray(WrappedArray &&other) : WrappedArray()
|
||||
{
|
||||
std::swap(mArray, other.mArray);
|
||||
std::swap(mSize, other.mSize);
|
||||
}
|
||||
|
||||
~WrappedArray() {}
|
||||
|
||||
constexpr const T *get() const { return mArray; }
|
||||
constexpr size_t size() const { return mSize; }
|
||||
|
||||
private:
|
||||
const T *mArray;
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
template <typename T, unsigned int N>
|
||||
void SafeRelease(T (&resourceBlock)[N])
|
||||
{
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
{
|
||||
SafeRelease(resourceBlock[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SafeRelease(T& resource)
|
||||
{
|
||||
if (resource)
|
||||
{
|
||||
resource->Release();
|
||||
resource = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SafeDelete(T *&resource)
|
||||
{
|
||||
delete resource;
|
||||
resource = nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SafeDeleteContainer(T& resource)
|
||||
{
|
||||
for (auto &element : resource)
|
||||
{
|
||||
SafeDelete(element);
|
||||
}
|
||||
resource.clear();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SafeDeleteArray(T*& resource)
|
||||
{
|
||||
delete[] resource;
|
||||
resource = nullptr;
|
||||
}
|
||||
|
||||
// Provide a less-than function for comparing structs
|
||||
// Note: struct memory must be initialized to zero, because of packing gaps
|
||||
template <typename T>
|
||||
inline bool StructLessThan(const T &a, const T &b)
|
||||
{
|
||||
return (memcmp(&a, &b, sizeof(T)) < 0);
|
||||
}
|
||||
|
||||
// Provide a less-than function for comparing structs
|
||||
// Note: struct memory must be initialized to zero, because of packing gaps
|
||||
template <typename T>
|
||||
inline bool StructEquals(const T &a, const T &b)
|
||||
{
|
||||
return (memcmp(&a, &b, sizeof(T)) == 0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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;
|
||||
std::set<std::string>::iterator it = strings.find(str);
|
||||
if (it != strings.end())
|
||||
{
|
||||
return it->c_str();
|
||||
}
|
||||
|
||||
return strings.insert(str).first->c_str();
|
||||
}
|
||||
|
||||
inline std::string ArrayString(unsigned int i)
|
||||
{
|
||||
// We assume UINT_MAX and GL_INVALID_INDEX are equal
|
||||
// See DynamicHLSL.cpp
|
||||
if (i == UINT_MAX)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream strstr;
|
||||
|
||||
strstr << "[";
|
||||
strstr << i;
|
||||
strstr << "]";
|
||||
|
||||
return strstr.str();
|
||||
}
|
||||
|
||||
inline std::string Str(int i)
|
||||
{
|
||||
std::stringstream strstr;
|
||||
strstr << 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, ...);
|
||||
|
||||
template <typename T>
|
||||
std::string ToString(const T &value)
|
||||
{
|
||||
std::ostringstream o;
|
||||
o << value;
|
||||
return o.str();
|
||||
}
|
||||
|
||||
// snprintf is not defined with MSVC prior to to msvc14
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#define GL_BGRX8_ANGLEX 0x6ABA
|
||||
#define GL_BGR565_ANGLEX 0x6ABB
|
||||
#define GL_BGRA4_ANGLEX 0x6ABC
|
||||
#define GL_BGR5_A1_ANGLEX 0x6ABD
|
||||
#define GL_INT_64_ANGLEX 0x6ABE
|
||||
|
||||
// Hidden enum for the NULL D3D device type.
|
||||
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
|
||||
|
||||
// TODO(jmadill): Clean this up at some point.
|
||||
#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x9999
|
||||
|
||||
#define ANGLE_TRY_CHECKED_MATH(result) \
|
||||
if (!result.IsValid()) \
|
||||
{ \
|
||||
return gl::InternalError() << "Integer overflow."; \
|
||||
}
|
||||
|
||||
// The below inlining code lifted from V8.
|
||||
#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
|
||||
#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
|
||||
#define ANGLE_HAS___FORCEINLINE 0
|
||||
#elif defined(_MSC_VER)
|
||||
#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
|
||||
#define ANGLE_HAS___FORCEINLINE 1
|
||||
#else
|
||||
#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
|
||||
#define ANGLE_HAS___FORCEINLINE 0
|
||||
#endif
|
||||
|
||||
#if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE
|
||||
#define ANGLE_INLINE inline __attribute__((always_inline))
|
||||
#elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE
|
||||
#define ANGLE_INLINE __forceinline
|
||||
#else
|
||||
#define ANGLE_INLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef ANGLE_STRINGIFY
|
||||
#define ANGLE_STRINGIFY(x) #x
|
||||
#endif
|
||||
|
||||
#ifndef ANGLE_MACRO_STRINGIFY
|
||||
#define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
|
||||
#endif
|
||||
|
||||
// Detect support for C++17 [[nodiscard]]
|
||||
#if !defined(__has_cpp_attribute)
|
||||
#define __has_cpp_attribute(name) 0
|
||||
#endif // !defined(__has_cpp_attribute)
|
||||
|
||||
#if __has_cpp_attribute(nodiscard)
|
||||
#define ANGLE_NO_DISCARD [[nodiscard]]
|
||||
#else
|
||||
#define ANGLE_NO_DISCARD
|
||||
#endif // __has_cpp_attribute(nodiscard)
|
||||
|
||||
#endif // COMMON_ANGLEUTILS_H_
|
|
@ -1,498 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// bitset_utils:
|
||||
// Bitset-related helper classes, such as a fast iterator to scan for set bits.
|
||||
//
|
||||
|
||||
#ifndef COMMON_BITSETITERATOR_H_
|
||||
#define COMMON_BITSETITERATOR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/mathutil.h"
|
||||
#include "common/platform.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
class BitSetT final
|
||||
{
|
||||
public:
|
||||
class Reference final
|
||||
{
|
||||
public:
|
||||
~Reference() {}
|
||||
Reference &operator=(bool x)
|
||||
{
|
||||
mParent->set(mBit, x);
|
||||
return *this;
|
||||
}
|
||||
explicit operator bool() const { return mParent->test(mBit); }
|
||||
|
||||
private:
|
||||
friend class BitSetT;
|
||||
|
||||
Reference(BitSetT *parent, std::size_t bit) : mParent(parent), mBit(bit) {}
|
||||
|
||||
BitSetT *mParent;
|
||||
std::size_t mBit;
|
||||
};
|
||||
|
||||
class Iterator final
|
||||
{
|
||||
public:
|
||||
Iterator(const BitSetT &bits);
|
||||
Iterator &operator++();
|
||||
|
||||
bool operator==(const Iterator &other) const;
|
||||
bool operator!=(const Iterator &other) const;
|
||||
std::size_t operator*() const;
|
||||
|
||||
private:
|
||||
std::size_t getNextBit();
|
||||
|
||||
BitSetT mBitsCopy;
|
||||
std::size_t mCurrentBit;
|
||||
};
|
||||
|
||||
BitSetT();
|
||||
BitSetT(BitsT value);
|
||||
~BitSetT();
|
||||
|
||||
BitSetT(const BitSetT &other);
|
||||
BitSetT &operator=(const BitSetT &other);
|
||||
|
||||
bool operator==(const BitSetT &other) const;
|
||||
bool operator!=(const BitSetT &other) const;
|
||||
|
||||
constexpr bool operator[](std::size_t pos) const;
|
||||
Reference operator[](std::size_t pos) { return Reference(this, pos); }
|
||||
|
||||
bool test(std::size_t pos) const;
|
||||
|
||||
bool all() const;
|
||||
bool any() const;
|
||||
bool none() const;
|
||||
std::size_t count() const;
|
||||
|
||||
constexpr std::size_t size() const { return N; }
|
||||
|
||||
BitSetT &operator&=(const BitSetT &other);
|
||||
BitSetT &operator|=(const BitSetT &other);
|
||||
BitSetT &operator^=(const BitSetT &other);
|
||||
BitSetT operator~() const;
|
||||
|
||||
BitSetT operator<<(std::size_t pos) const;
|
||||
BitSetT &operator<<=(std::size_t pos);
|
||||
BitSetT operator>>(std::size_t pos) const;
|
||||
BitSetT &operator>>=(std::size_t pos);
|
||||
|
||||
BitSetT &set();
|
||||
BitSetT &set(std::size_t pos, bool value = true);
|
||||
|
||||
BitSetT &reset();
|
||||
BitSetT &reset(std::size_t pos);
|
||||
|
||||
BitSetT &flip();
|
||||
BitSetT &flip(std::size_t pos);
|
||||
|
||||
unsigned long to_ulong() const { return static_cast<unsigned long>(mBits); }
|
||||
BitsT bits() const { return mBits; }
|
||||
|
||||
Iterator begin() const { return Iterator(*this); }
|
||||
Iterator end() const { return Iterator(BitSetT()); }
|
||||
|
||||
private:
|
||||
constexpr static BitsT Bit(std::size_t x) { return (static_cast<BitsT>(1) << x); }
|
||||
constexpr static BitsT Mask(std::size_t x) { return ((Bit(x - 1) - 1) << 1) + 1; }
|
||||
|
||||
BitsT mBits;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
class IterableBitSet : public std::bitset<N>
|
||||
{
|
||||
public:
|
||||
IterableBitSet() {}
|
||||
IterableBitSet(const std::bitset<N> &implicitBitSet) : std::bitset<N>(implicitBitSet) {}
|
||||
|
||||
class Iterator final
|
||||
{
|
||||
public:
|
||||
Iterator(const std::bitset<N> &bits);
|
||||
Iterator &operator++();
|
||||
|
||||
bool operator==(const Iterator &other) const;
|
||||
bool operator!=(const Iterator &other) const;
|
||||
unsigned long operator*() const { return mCurrentBit; }
|
||||
|
||||
private:
|
||||
unsigned long getNextBit();
|
||||
|
||||
static constexpr size_t BitsPerWord = sizeof(uint32_t) * 8;
|
||||
std::bitset<N> mBits;
|
||||
unsigned long mCurrentBit;
|
||||
unsigned long mOffset;
|
||||
};
|
||||
|
||||
Iterator begin() const { return Iterator(*this); }
|
||||
Iterator end() const { return Iterator(std::bitset<N>(0)); }
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
IterableBitSet<N>::Iterator::Iterator(const std::bitset<N> &bitset)
|
||||
: mBits(bitset), mCurrentBit(0), mOffset(0)
|
||||
{
|
||||
if (mBits.any())
|
||||
{
|
||||
mCurrentBit = getNextBit();
|
||||
}
|
||||
else
|
||||
{
|
||||
mOffset = static_cast<unsigned long>(rx::roundUp(N, BitsPerWord));
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
typename IterableBitSet<N>::Iterator &IterableBitSet<N>::Iterator::operator++()
|
||||
{
|
||||
ASSERT(mBits.any());
|
||||
mBits.set(mCurrentBit - mOffset, 0);
|
||||
mCurrentBit = getNextBit();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
bool IterableBitSet<N>::Iterator::operator==(const Iterator &other) const
|
||||
{
|
||||
return mOffset == other.mOffset && mBits == other.mBits;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
bool IterableBitSet<N>::Iterator::operator!=(const Iterator &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
unsigned long IterableBitSet<N>::Iterator::getNextBit()
|
||||
{
|
||||
// TODO(jmadill): Use 64-bit scan when possible.
|
||||
static constexpr std::bitset<N> wordMask(std::numeric_limits<uint32_t>::max());
|
||||
|
||||
while (mOffset < N)
|
||||
{
|
||||
uint32_t wordBits = static_cast<uint32_t>((mBits & wordMask).to_ulong());
|
||||
if (wordBits != 0)
|
||||
{
|
||||
return gl::ScanForward(wordBits) + mOffset;
|
||||
}
|
||||
|
||||
mBits >>= BitsPerWord;
|
||||
mOffset += BitsPerWord;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT>::BitSetT() : mBits(0)
|
||||
{
|
||||
static_assert(N > 0, "Bitset type cannot support zero bits.");
|
||||
static_assert(N <= sizeof(BitsT) * 8, "Bitset type cannot support a size this large.");
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT>::BitSetT(BitsT value) : mBits(value & Mask(N))
|
||||
{
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT>::~BitSetT()
|
||||
{
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT>::BitSetT(const BitSetT &other) : mBits(other.mBits)
|
||||
{
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator=(const BitSetT &other)
|
||||
{
|
||||
mBits = other.mBits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::operator==(const BitSetT &other) const
|
||||
{
|
||||
return mBits == other.mBits;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::operator!=(const BitSetT &other) const
|
||||
{
|
||||
return mBits != other.mBits;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
constexpr bool BitSetT<N, BitsT>::operator[](std::size_t pos) const
|
||||
{
|
||||
return test(pos);
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::test(std::size_t pos) const
|
||||
{
|
||||
return (mBits & Bit(pos)) != 0;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::all() const
|
||||
{
|
||||
ASSERT(mBits == (mBits & Mask(N)));
|
||||
return mBits == Mask(N);
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::any() const
|
||||
{
|
||||
ASSERT(mBits == (mBits & Mask(N)));
|
||||
return (mBits != 0);
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::none() const
|
||||
{
|
||||
ASSERT(mBits == (mBits & Mask(N)));
|
||||
return (mBits == 0);
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
std::size_t BitSetT<N, BitsT>::count() const
|
||||
{
|
||||
return gl::BitCount(mBits);
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator&=(const BitSetT &other)
|
||||
{
|
||||
mBits &= other.mBits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator|=(const BitSetT &other)
|
||||
{
|
||||
mBits |= other.mBits;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator^=(const BitSetT &other)
|
||||
{
|
||||
mBits = (mBits ^ other.mBits) & Mask(N);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> BitSetT<N, BitsT>::operator~() const
|
||||
{
|
||||
return BitSetT<N, BitsT>(~mBits & Mask(N));
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> BitSetT<N, BitsT>::operator<<(std::size_t pos) const
|
||||
{
|
||||
return BitSetT<N, BitsT>((mBits << pos) & Mask(N));
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator<<=(std::size_t pos)
|
||||
{
|
||||
mBits = (mBits << pos & Mask(N));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> BitSetT<N, BitsT>::operator>>(std::size_t pos) const
|
||||
{
|
||||
return BitSetT<N, BitsT>(mBits >> pos);
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::operator>>=(std::size_t pos)
|
||||
{
|
||||
mBits = ((mBits >> pos) & Mask(N));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::set()
|
||||
{
|
||||
mBits = Mask(N);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::set(std::size_t pos, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
mBits |= Bit(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
reset(pos);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::reset()
|
||||
{
|
||||
mBits = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::reset(std::size_t pos)
|
||||
{
|
||||
mBits &= ~Bit(pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::flip()
|
||||
{
|
||||
mBits ^= Mask(N);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT> &BitSetT<N, BitsT>::flip(std::size_t pos)
|
||||
{
|
||||
mBits ^= Bit(pos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
BitSetT<N, BitsT>::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0)
|
||||
{
|
||||
if (bits.any())
|
||||
{
|
||||
mCurrentBit = getNextBit();
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
typename BitSetT<N, BitsT>::Iterator &BitSetT<N, BitsT>::Iterator::operator++()
|
||||
{
|
||||
ASSERT(mBitsCopy.any());
|
||||
mBitsCopy.reset(mCurrentBit);
|
||||
mCurrentBit = getNextBit();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::Iterator::operator==(const Iterator &other) const
|
||||
{
|
||||
return mBitsCopy == other.mBitsCopy;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
bool BitSetT<N, BitsT>::Iterator::operator!=(const Iterator &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
std::size_t BitSetT<N, BitsT>::Iterator::operator*() const
|
||||
{
|
||||
return mCurrentBit;
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
std::size_t BitSetT<N, BitsT>::Iterator::getNextBit()
|
||||
{
|
||||
if (mBitsCopy.none())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return gl::ScanForward(mBitsCopy.mBits);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
using BitSet32 = BitSetT<N, uint32_t>;
|
||||
|
||||
// ScanForward for 64-bits requires a 64-bit implementation.
|
||||
#if defined(ANGLE_X64_CPU)
|
||||
template <size_t N>
|
||||
using BitSet64 = BitSetT<N, uint64_t>;
|
||||
#endif // defined(ANGLE_X64_CPU)
|
||||
|
||||
namespace priv
|
||||
{
|
||||
|
||||
template <size_t N, typename T>
|
||||
using EnableIfBitsFit = typename std::enable_if<N <= sizeof(T) * 8>::type;
|
||||
|
||||
template <size_t N, typename Enable = void>
|
||||
struct GetBitSet
|
||||
{
|
||||
using Type = IterableBitSet<N>;
|
||||
};
|
||||
|
||||
// Prefer 64-bit bitsets on 64-bit CPUs. They seem faster than 32-bit.
|
||||
#if defined(ANGLE_X64_CPU)
|
||||
template <size_t N>
|
||||
struct GetBitSet<N, EnableIfBitsFit<N, uint64_t>>
|
||||
{
|
||||
using Type = BitSet64<N>;
|
||||
};
|
||||
#else
|
||||
template <size_t N>
|
||||
struct GetBitSet<N, EnableIfBitsFit<N, uint32_t>>
|
||||
{
|
||||
using Type = BitSet32<N>;
|
||||
};
|
||||
#endif // defined(ANGLE_X64_CPU)
|
||||
|
||||
} // namespace priv
|
||||
|
||||
template <size_t N>
|
||||
using BitSet = typename priv::GetBitSet<N>::Type;
|
||||
|
||||
} // angle
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
inline angle::BitSetT<N, BitsT> operator&(const angle::BitSetT<N, BitsT> &lhs,
|
||||
const angle::BitSetT<N, BitsT> &rhs)
|
||||
{
|
||||
return angle::BitSetT<N, BitsT>(lhs.bits() & rhs.bits());
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
inline angle::BitSetT<N, BitsT> operator|(const angle::BitSetT<N, BitsT> &lhs,
|
||||
const angle::BitSetT<N, BitsT> &rhs)
|
||||
{
|
||||
return angle::BitSetT<N, BitsT>(lhs.bits() | rhs.bits());
|
||||
}
|
||||
|
||||
template <size_t N, typename BitsT>
|
||||
inline angle::BitSetT<N, BitsT> operator^(const angle::BitSetT<N, BitsT> &lhs,
|
||||
const angle::BitSetT<N, BitsT> &rhs)
|
||||
{
|
||||
return angle::BitSetT<N, BitsT>(lhs.bits() ^ rhs.bits());
|
||||
}
|
||||
|
||||
#endif // COMMON_BITSETITERATOR_H_
|
|
@ -1,112 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// bitset_utils_unittest:
|
||||
// Tests bitset helpers and custom classes.
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "common/bitset_utils.h"
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace
|
||||
{
|
||||
class BitSetIteratorTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
BitSet<40> mStateBits;
|
||||
};
|
||||
|
||||
// Simple iterator test.
|
||||
TEST_F(BitSetIteratorTest, Iterator)
|
||||
{
|
||||
std::set<size_t> originalValues;
|
||||
originalValues.insert(2);
|
||||
originalValues.insert(6);
|
||||
originalValues.insert(8);
|
||||
originalValues.insert(35);
|
||||
|
||||
for (size_t value : originalValues)
|
||||
{
|
||||
mStateBits.set(value);
|
||||
}
|
||||
|
||||
std::set<size_t> readValues;
|
||||
for (size_t bit : mStateBits)
|
||||
{
|
||||
EXPECT_EQ(1u, originalValues.count(bit));
|
||||
EXPECT_EQ(0u, readValues.count(bit));
|
||||
readValues.insert(bit);
|
||||
}
|
||||
|
||||
EXPECT_EQ(originalValues.size(), readValues.size());
|
||||
}
|
||||
|
||||
// Test an empty iterator.
|
||||
TEST_F(BitSetIteratorTest, EmptySet)
|
||||
{
|
||||
// We don't use the FAIL gtest macro here since it returns immediately,
|
||||
// causing an unreachable code warning in MSVS
|
||||
bool sawBit = false;
|
||||
for (size_t bit : mStateBits)
|
||||
{
|
||||
sawBit = true;
|
||||
UNUSED_VARIABLE(bit);
|
||||
}
|
||||
EXPECT_FALSE(sawBit);
|
||||
}
|
||||
|
||||
// Test iterating a result of combining two bitsets.
|
||||
TEST_F(BitSetIteratorTest, NonLValueBitset)
|
||||
{
|
||||
BitSet<40> otherBits;
|
||||
|
||||
mStateBits.set(1);
|
||||
mStateBits.set(2);
|
||||
mStateBits.set(3);
|
||||
mStateBits.set(4);
|
||||
|
||||
otherBits.set(0);
|
||||
otherBits.set(1);
|
||||
otherBits.set(3);
|
||||
otherBits.set(5);
|
||||
|
||||
std::set<size_t> seenBits;
|
||||
|
||||
angle::BitSet<40> maskedBits = (mStateBits & otherBits);
|
||||
for (size_t bit : maskedBits)
|
||||
{
|
||||
EXPECT_EQ(0u, seenBits.count(bit));
|
||||
seenBits.insert(bit);
|
||||
EXPECT_TRUE(mStateBits[bit]);
|
||||
EXPECT_TRUE(otherBits[bit]);
|
||||
}
|
||||
|
||||
EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());
|
||||
}
|
||||
|
||||
// Test bit assignments.
|
||||
TEST_F(BitSetIteratorTest, BitAssignment)
|
||||
{
|
||||
std::set<size_t> originalValues;
|
||||
originalValues.insert(2);
|
||||
originalValues.insert(6);
|
||||
originalValues.insert(8);
|
||||
originalValues.insert(35);
|
||||
|
||||
for (size_t value : originalValues)
|
||||
{
|
||||
(mStateBits[value] = false) = true;
|
||||
}
|
||||
|
||||
for (size_t value : originalValues)
|
||||
{
|
||||
EXPECT_TRUE(mStateBits.test(value));
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
|
@ -1,220 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 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.
|
||||
//
|
||||
|
||||
// debug.cpp: Debugging utilities.
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "common/Optional.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
DebugAnnotator *g_debugAnnotator = nullptr;
|
||||
|
||||
constexpr std::array<const char *, LOG_NUM_SEVERITIES> g_logSeverityNames = {
|
||||
{"EVENT", "WARN", "ERR"}};
|
||||
|
||||
constexpr const char *LogSeverityName(int severity)
|
||||
{
|
||||
return (severity >= 0 && severity < LOG_NUM_SEVERITIES) ? g_logSeverityNames[severity]
|
||||
: "UNKNOWN";
|
||||
}
|
||||
|
||||
bool ShouldCreateLogMessage(LogSeverity severity)
|
||||
{
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
return true;
|
||||
#elif defined(ANGLE_ENABLE_ASSERTS)
|
||||
return severity == LOG_ERR;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace priv
|
||||
{
|
||||
|
||||
bool ShouldCreatePlatformLogMessage(LogSeverity severity)
|
||||
{
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
return true;
|
||||
#else
|
||||
return severity != LOG_EVENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
bool DebugAnnotationsActive()
|
||||
{
|
||||
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DebugAnnotationsInitialized()
|
||||
{
|
||||
return g_debugAnnotator != nullptr;
|
||||
}
|
||||
|
||||
void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
|
||||
{
|
||||
UninitializeDebugAnnotations();
|
||||
g_debugAnnotator = debugAnnotator;
|
||||
}
|
||||
|
||||
void UninitializeDebugAnnotations()
|
||||
{
|
||||
// Pointer is not managed.
|
||||
g_debugAnnotator = nullptr;
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::ScopedPerfEventHelper(const char *format, ...)
|
||||
{
|
||||
#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
if (!DebugAnnotationsActive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_DEBUG_TRACE
|
||||
|
||||
va_list vararg;
|
||||
va_start(vararg, format);
|
||||
std::vector<char> buffer(512);
|
||||
size_t len = FormatStringIntoVector(format, vararg, buffer);
|
||||
ANGLE_LOG(EVENT) << std::string(&buffer[0], len);
|
||||
va_end(vararg);
|
||||
}
|
||||
|
||||
ScopedPerfEventHelper::~ScopedPerfEventHelper()
|
||||
{
|
||||
if (DebugAnnotationsActive())
|
||||
{
|
||||
g_debugAnnotator->endEvent();
|
||||
}
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(const char *function, int line, LogSeverity severity)
|
||||
: mFunction(function), mLine(line), mSeverity(severity)
|
||||
{
|
||||
// EVENT() does not require additional function(line) info.
|
||||
if (mSeverity != LOG_EVENT)
|
||||
{
|
||||
mStream << mFunction << "(" << mLine << "): ";
|
||||
}
|
||||
}
|
||||
|
||||
LogMessage::~LogMessage()
|
||||
{
|
||||
if (DebugAnnotationsInitialized() && (mSeverity == LOG_ERR || mSeverity == LOG_WARN))
|
||||
{
|
||||
g_debugAnnotator->logMessage(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace(getSeverity(), getMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Trace(LogSeverity severity, const char *message)
|
||||
{
|
||||
if (!ShouldCreateLogMessage(severity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str(message);
|
||||
|
||||
if (DebugAnnotationsActive())
|
||||
{
|
||||
std::wstring formattedWideMessage(str.begin(), str.end());
|
||||
|
||||
switch (severity)
|
||||
{
|
||||
case LOG_EVENT:
|
||||
g_debugAnnotator->beginEvent(formattedWideMessage.c_str());
|
||||
break;
|
||||
default:
|
||||
g_debugAnnotator->setMarker(formattedWideMessage.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (severity == LOG_ERR)
|
||||
{
|
||||
// Note: we use fprintf because <iostream> includes static initializers.
|
||||
fprintf(stderr, "%s: %s\n", LogSeverityName(severity), str.c_str());
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS) && \
|
||||
(defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) || !defined(NDEBUG))
|
||||
#if !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
|
||||
if (severity == LOG_ERR)
|
||||
#endif // !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
|
||||
{
|
||||
OutputDebugStringA(str.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
#if defined(NDEBUG)
|
||||
if (severity == LOG_EVENT || severity == LOG_WARN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif // defined(NDEBUG)
|
||||
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
|
||||
if (file)
|
||||
{
|
||||
file << LogSeverityName(severity) << ": " << str << std::endl;
|
||||
file.flush();
|
||||
}
|
||||
#endif // defined(ANGLE_ENABLE_DEBUG_TRACE)
|
||||
}
|
||||
|
||||
LogSeverity LogMessage::getSeverity() const
|
||||
{
|
||||
return mSeverity;
|
||||
}
|
||||
|
||||
std::string LogMessage::getMessage() const
|
||||
{
|
||||
return mStream.str();
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS)
|
||||
std::ostream &operator<<(std::ostream &os, const FmtHR &fmt)
|
||||
{
|
||||
os << "HRESULT: ";
|
||||
return FmtHexInt(os, fmt.mHR);
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const FmtErr &fmt)
|
||||
{
|
||||
os << "error: ";
|
||||
return FmtHexInt(os, fmt.mErr);
|
||||
}
|
||||
|
||||
#endif // defined(ANGLE_PLATFORM_WINDOWS)
|
||||
|
||||
} // namespace gl
|
|
@ -1,286 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2010 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.
|
||||
//
|
||||
|
||||
// debug.h: Debugging utilities.
|
||||
|
||||
#ifndef COMMON_DEBUG_H_
|
||||
#define COMMON_DEBUG_H_
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ios>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
|
||||
#if !defined(TRACE_OUTPUT_FILE)
|
||||
#define TRACE_OUTPUT_FILE "angle_debug.txt"
|
||||
#endif
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
// Pairs a D3D begin event with an end event.
|
||||
class ScopedPerfEventHelper : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
ScopedPerfEventHelper(const char* format, ...);
|
||||
~ScopedPerfEventHelper();
|
||||
};
|
||||
|
||||
using LogSeverity = int;
|
||||
// Note: the log severities are used to index into the array of names,
|
||||
// see g_logSeverityNames.
|
||||
constexpr LogSeverity LOG_EVENT = 0;
|
||||
constexpr LogSeverity LOG_WARN = 1;
|
||||
constexpr LogSeverity LOG_ERR = 2;
|
||||
constexpr LogSeverity LOG_NUM_SEVERITIES = 3;
|
||||
|
||||
void Trace(LogSeverity severity, const char *message);
|
||||
|
||||
// This class more or less represents a particular log message. You
|
||||
// create an instance of LogMessage and then stream stuff to it.
|
||||
// When you finish streaming to it, ~LogMessage is called and the
|
||||
// full message gets streamed to the appropriate destination.
|
||||
//
|
||||
// You shouldn't actually use LogMessage's constructor to log things,
|
||||
// though. You should use the ERR() and WARN() macros.
|
||||
class LogMessage : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
// Used for ANGLE_LOG(severity).
|
||||
LogMessage(const char *function, int line, LogSeverity severity);
|
||||
~LogMessage();
|
||||
std::ostream &stream() { return mStream; }
|
||||
|
||||
LogSeverity getSeverity() const;
|
||||
std::string getMessage() const;
|
||||
|
||||
private:
|
||||
const char *mFunction;
|
||||
const int mLine;
|
||||
const LogSeverity mSeverity;
|
||||
|
||||
std::ostringstream mStream;
|
||||
};
|
||||
|
||||
// Wraps the D3D9/D3D11 debug annotation functions.
|
||||
// Also handles redirecting logging destination.
|
||||
class DebugAnnotator : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
DebugAnnotator(){};
|
||||
virtual ~DebugAnnotator() { };
|
||||
virtual void beginEvent(const wchar_t *eventName) = 0;
|
||||
virtual void endEvent() = 0;
|
||||
virtual void setMarker(const wchar_t *markerName) = 0;
|
||||
virtual bool getStatus() = 0;
|
||||
// Log Message Handler that gets passed every log message,
|
||||
// when debug annotations are initialized,
|
||||
// replacing default handling by LogMessage.
|
||||
virtual void logMessage(const LogMessage &msg) const = 0;
|
||||
};
|
||||
|
||||
void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator);
|
||||
void UninitializeDebugAnnotations();
|
||||
bool DebugAnnotationsActive();
|
||||
bool DebugAnnotationsInitialized();
|
||||
|
||||
namespace priv
|
||||
{
|
||||
// This class is used to explicitly ignore values in the conditional logging macros. This avoids
|
||||
// compiler warnings like "value computed is not used" and "statement has no effect".
|
||||
class LogMessageVoidify
|
||||
{
|
||||
public:
|
||||
LogMessageVoidify() {}
|
||||
// This has to be an operator with a precedence lower than << but higher than ?:
|
||||
void operator&(std::ostream &) {}
|
||||
};
|
||||
|
||||
// Used by ANGLE_LOG_IS_ON to lazy-evaluate stream arguments.
|
||||
bool ShouldCreatePlatformLogMessage(LogSeverity severity);
|
||||
|
||||
template <int N, typename T>
|
||||
std::ostream &FmtHex(std::ostream &os, T value)
|
||||
{
|
||||
os << "0x";
|
||||
|
||||
std::ios_base::fmtflags oldFlags = os.flags();
|
||||
std::streamsize oldWidth = os.width();
|
||||
std::ostream::char_type oldFill = os.fill();
|
||||
|
||||
os << std::hex << std::uppercase << std::setw(N) << std::setfill('0') << value;
|
||||
|
||||
os.flags(oldFlags);
|
||||
os.width(oldWidth);
|
||||
os.fill(oldFill);
|
||||
|
||||
return os;
|
||||
}
|
||||
} // namespace priv
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS)
|
||||
class FmtHR
|
||||
{
|
||||
public:
|
||||
explicit FmtHR(HRESULT hresult) : mHR(hresult) {}
|
||||
private:
|
||||
HRESULT mHR;
|
||||
friend std::ostream &operator<<(std::ostream &os, const FmtHR &fmt);
|
||||
};
|
||||
|
||||
class FmtErr
|
||||
{
|
||||
public:
|
||||
explicit FmtErr(DWORD err) : mErr(err) {}
|
||||
|
||||
private:
|
||||
DWORD mErr;
|
||||
friend std::ostream &operator<<(std::ostream &os, const FmtErr &fmt);
|
||||
};
|
||||
#endif // defined(ANGLE_PLATFORM_WINDOWS)
|
||||
|
||||
template <typename T>
|
||||
std::ostream &FmtHexShort(std::ostream &os, T value)
|
||||
{
|
||||
return priv::FmtHex<4>(os, value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::ostream &FmtHexInt(std::ostream &os, T value)
|
||||
{
|
||||
return priv::FmtHex<8>(os, value);
|
||||
}
|
||||
|
||||
// A few definitions of macros that don't generate much code. These are used
|
||||
// by ANGLE_LOG(). Since these are used all over our code, it's
|
||||
// better to have compact code for these operations.
|
||||
#define COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ...) \
|
||||
::gl::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_EVENT, ##__VA_ARGS__)
|
||||
#define COMPACT_ANGLE_LOG_EX_WARN(ClassName, ...) \
|
||||
::gl::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_WARN, ##__VA_ARGS__)
|
||||
#define COMPACT_ANGLE_LOG_EX_ERR(ClassName, ...) \
|
||||
::gl::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_ERR, ##__VA_ARGS__)
|
||||
|
||||
#define COMPACT_ANGLE_LOG_EVENT COMPACT_ANGLE_LOG_EX_EVENT(LogMessage)
|
||||
#define COMPACT_ANGLE_LOG_WARN COMPACT_ANGLE_LOG_EX_WARN(LogMessage)
|
||||
#define COMPACT_ANGLE_LOG_ERR COMPACT_ANGLE_LOG_EX_ERR(LogMessage)
|
||||
|
||||
#define ANGLE_LOG_IS_ON(severity) (::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_##severity))
|
||||
|
||||
// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold.
|
||||
// Condition is evaluated once and only once.
|
||||
#define ANGLE_LAZY_STREAM(stream, condition) \
|
||||
!(condition) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify() & (stream)
|
||||
|
||||
// We use the preprocessor's merging operator, "##", so that, e.g.,
|
||||
// ANGLE_LOG(EVENT) becomes the token COMPACT_ANGLE_LOG_EVENT. There's some funny
|
||||
// subtle difference between ostream member streaming functions (e.g.,
|
||||
// ostream::operator<<(int) and ostream non-member streaming functions
|
||||
// (e.g., ::operator<<(ostream&, string&): it turns out that it's
|
||||
// impossible to stream something like a string directly to an unnamed
|
||||
// ostream. We employ a neat hack by calling the stream() member
|
||||
// function of LogMessage which seems to avoid the problem.
|
||||
#define ANGLE_LOG_STREAM(severity) COMPACT_ANGLE_LOG_##severity.stream()
|
||||
|
||||
#define ANGLE_LOG(severity) ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(severity), ANGLE_LOG_IS_ON(severity))
|
||||
|
||||
} // namespace gl
|
||||
|
||||
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
|
||||
#define ANGLE_TRACE_ENABLED
|
||||
#endif
|
||||
|
||||
#define ANGLE_EMPTY_STATEMENT for (;;) break
|
||||
#if !defined(NDEBUG) || defined(ANGLE_ENABLE_RELEASE_ASSERTS)
|
||||
#define ANGLE_ENABLE_ASSERTS
|
||||
#endif
|
||||
|
||||
#define WARN() ANGLE_LOG(WARN)
|
||||
#define ERR() ANGLE_LOG(ERR)
|
||||
|
||||
// A macro to log a performance event around a scope.
|
||||
#if defined(ANGLE_TRACE_ENABLED)
|
||||
#if defined(_MSC_VER)
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
|
||||
#else
|
||||
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper("%s" message "\n", __FUNCTION__, ##__VA_ARGS__);
|
||||
#endif // _MSC_VER
|
||||
#else
|
||||
#define EVENT(message, ...) (void(0))
|
||||
#endif
|
||||
|
||||
#if defined(COMPILER_GCC) || defined(__clang__)
|
||||
#define ANGLE_CRASH() __builtin_trap()
|
||||
#else
|
||||
#define ANGLE_CRASH() ((void)(*(volatile char *)0 = 0))
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define ANGLE_ASSERT_IMPL(expression) assert(expression)
|
||||
#else
|
||||
// TODO(jmadill): Detect if debugger is attached and break.
|
||||
#define ANGLE_ASSERT_IMPL(expression) ANGLE_CRASH()
|
||||
#endif // !defined(NDEBUG)
|
||||
|
||||
// A macro asserting a condition and outputting failures to the debug log
|
||||
#if defined(ANGLE_ENABLE_ASSERTS)
|
||||
#define ASSERT(expression) \
|
||||
(expression ? static_cast<void>(0) : ((ERR() << "\t! Assert failed in " << __FUNCTION__ << "(" \
|
||||
<< __LINE__ << "): " << #expression), \
|
||||
ANGLE_ASSERT_IMPL(expression)))
|
||||
#else
|
||||
// These are just dummy values.
|
||||
#define COMPACT_ANGLE_LOG_EX_ASSERT(ClassName, ...) \
|
||||
COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ##__VA_ARGS__)
|
||||
#define COMPACT_ANGLE_LOG_ASSERT COMPACT_ANGLE_LOG_EVENT
|
||||
namespace gl
|
||||
{
|
||||
constexpr LogSeverity LOG_ASSERT = LOG_EVENT;
|
||||
} // namespace gl
|
||||
|
||||
#define ASSERT(condition) \
|
||||
ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(ASSERT), false ? !(condition) : false) \
|
||||
<< "Check failed: " #condition ". "
|
||||
#endif // defined(ANGLE_ENABLE_ASSERTS)
|
||||
|
||||
#define UNUSED_VARIABLE(variable) ((void)variable)
|
||||
|
||||
// A macro to indicate unimplemented functionality
|
||||
#ifndef NOASSERT_UNIMPLEMENTED
|
||||
#define NOASSERT_UNIMPLEMENTED 1
|
||||
#endif
|
||||
|
||||
#if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
|
||||
#define UNIMPLEMENTED() \
|
||||
{ \
|
||||
ERR() << "\t! Unimplemented: " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \
|
||||
<< ")"; \
|
||||
ASSERT(NOASSERT_UNIMPLEMENTED); \
|
||||
} \
|
||||
ANGLE_EMPTY_STATEMENT
|
||||
|
||||
// A macro for code which is not expected to be reached under valid assumptions
|
||||
#define UNREACHABLE() \
|
||||
((ERR() << "\t! Unreachable reached: " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \
|
||||
<< ")"), \
|
||||
ASSERT(false))
|
||||
#else
|
||||
#define UNIMPLEMENTED() \
|
||||
{ \
|
||||
ASSERT(NOASSERT_UNIMPLEMENTED); \
|
||||
} \
|
||||
ANGLE_EMPTY_STATEMENT
|
||||
|
||||
// A macro for code which is not expected to be reached under valid assumptions
|
||||
#define UNREACHABLE() ASSERT(false)
|
||||
#endif // defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
|
||||
|
||||
#endif // COMMON_DEBUG_H_
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (c) 2012 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 "common/event_tracer.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
const unsigned char *GetTraceCategoryEnabledFlag(const char *name)
|
||||
{
|
||||
auto *platform = ANGLEPlatformCurrent();
|
||||
ASSERT(platform);
|
||||
|
||||
const unsigned char *categoryEnabledFlag =
|
||||
platform->getTraceCategoryEnabledFlag(platform, name);
|
||||
if (categoryEnabledFlag != nullptr)
|
||||
{
|
||||
return categoryEnabledFlag;
|
||||
}
|
||||
|
||||
static unsigned char disabled = 0;
|
||||
return &disabled;
|
||||
}
|
||||
|
||||
angle::TraceEventHandle AddTraceEvent(char phase,
|
||||
const unsigned char *categoryGroupEnabled,
|
||||
const char *name,
|
||||
unsigned long long id,
|
||||
int numArgs,
|
||||
const char **argNames,
|
||||
const unsigned char *argTypes,
|
||||
const unsigned long long *argValues,
|
||||
unsigned char flags)
|
||||
{
|
||||
auto *platform = ANGLEPlatformCurrent();
|
||||
ASSERT(platform);
|
||||
|
||||
double timestamp = platform->monotonicallyIncreasingTime(platform);
|
||||
|
||||
if (timestamp != 0)
|
||||
{
|
||||
angle::TraceEventHandle handle =
|
||||
platform->addTraceEvent(platform, phase, categoryGroupEnabled, name, id, timestamp,
|
||||
numArgs, argNames, argTypes, argValues, flags);
|
||||
ASSERT(handle != 0);
|
||||
return handle;
|
||||
}
|
||||
|
||||
return static_cast<angle::TraceEventHandle>(0);
|
||||
}
|
||||
|
||||
} // namespace angle
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) 2012 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 COMMON_EVENT_TRACER_H_
|
||||
#define COMMON_EVENT_TRACER_H_
|
||||
|
||||
#include "common/platform.h"
|
||||
#include "platform/Platform.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
const unsigned char *GetTraceCategoryEnabledFlag(const char* name);
|
||||
angle::TraceEventHandle AddTraceEvent(char phase,
|
||||
const unsigned char *categoryGroupEnabled,
|
||||
const char *name,
|
||||
unsigned long long id,
|
||||
int numArgs,
|
||||
const char **argNames,
|
||||
const unsigned char *argTypes,
|
||||
const unsigned long long *argValues,
|
||||
unsigned char flags);
|
||||
}
|
||||
|
||||
#endif // COMMON_EVENT_TRACER_H_
|
|
@ -1,257 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright 2017 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.
|
||||
#
|
||||
# gen_uniform_type_table.py:
|
||||
# Code generation for OpenGL uniform type info tables.
|
||||
|
||||
from datetime import date
|
||||
|
||||
import sys
|
||||
|
||||
all_uniform_types = [
|
||||
"GL_NONE",
|
||||
"GL_BOOL",
|
||||
"GL_BOOL_VEC2",
|
||||
"GL_BOOL_VEC3",
|
||||
"GL_BOOL_VEC4",
|
||||
"GL_FLOAT",
|
||||
"GL_FLOAT_MAT2",
|
||||
"GL_FLOAT_MAT2x3",
|
||||
"GL_FLOAT_MAT2x4",
|
||||
"GL_FLOAT_MAT3",
|
||||
"GL_FLOAT_MAT3x2",
|
||||
"GL_FLOAT_MAT3x4",
|
||||
"GL_FLOAT_MAT4",
|
||||
"GL_FLOAT_MAT4x2",
|
||||
"GL_FLOAT_MAT4x3",
|
||||
"GL_FLOAT_VEC2",
|
||||
"GL_FLOAT_VEC3",
|
||||
"GL_FLOAT_VEC4",
|
||||
"GL_IMAGE_2D",
|
||||
"GL_IMAGE_2D_ARRAY",
|
||||
"GL_IMAGE_3D",
|
||||
"GL_IMAGE_CUBE",
|
||||
"GL_INT",
|
||||
"GL_INT_IMAGE_2D",
|
||||
"GL_INT_IMAGE_2D_ARRAY",
|
||||
"GL_INT_IMAGE_3D",
|
||||
"GL_INT_IMAGE_CUBE",
|
||||
"GL_INT_SAMPLER_2D",
|
||||
"GL_INT_SAMPLER_2D_ARRAY",
|
||||
"GL_INT_SAMPLER_2D_MULTISAMPLE",
|
||||
"GL_INT_SAMPLER_3D",
|
||||
"GL_INT_SAMPLER_CUBE",
|
||||
"GL_INT_VEC2",
|
||||
"GL_INT_VEC3",
|
||||
"GL_INT_VEC4",
|
||||
"GL_SAMPLER_2D",
|
||||
"GL_SAMPLER_2D_ARRAY",
|
||||
"GL_SAMPLER_2D_ARRAY_SHADOW",
|
||||
"GL_SAMPLER_2D_MULTISAMPLE",
|
||||
"GL_SAMPLER_2D_RECT_ANGLE",
|
||||
"GL_SAMPLER_2D_SHADOW",
|
||||
"GL_SAMPLER_3D",
|
||||
"GL_SAMPLER_CUBE",
|
||||
"GL_SAMPLER_CUBE_SHADOW",
|
||||
"GL_SAMPLER_EXTERNAL_OES",
|
||||
"GL_UNSIGNED_INT",
|
||||
"GL_UNSIGNED_INT_ATOMIC_COUNTER",
|
||||
"GL_UNSIGNED_INT_IMAGE_2D",
|
||||
"GL_UNSIGNED_INT_IMAGE_2D_ARRAY",
|
||||
"GL_UNSIGNED_INT_IMAGE_3D",
|
||||
"GL_UNSIGNED_INT_IMAGE_CUBE",
|
||||
"GL_UNSIGNED_INT_SAMPLER_2D",
|
||||
"GL_UNSIGNED_INT_SAMPLER_2D_ARRAY",
|
||||
"GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE",
|
||||
"GL_UNSIGNED_INT_SAMPLER_3D",
|
||||
"GL_UNSIGNED_INT_SAMPLER_CUBE",
|
||||
"GL_UNSIGNED_INT_VEC2",
|
||||
"GL_UNSIGNED_INT_VEC3",
|
||||
"GL_UNSIGNED_INT_VEC4"
|
||||
]
|
||||
|
||||
# Uniform texture types.
|
||||
texture_types = {
|
||||
"2D": "2D",
|
||||
"CUBE": "CUBE_MAP",
|
||||
"2D_ARRAY": "2D_ARRAY",
|
||||
"3D": "3D",
|
||||
"MULTISAMPLE": "MULTISAMPLE",
|
||||
"RECT": "RECTANGLE",
|
||||
"EXTERNAL_OES": "EXTERNAL_OES"
|
||||
}
|
||||
|
||||
template_cpp = """// GENERATED FILE - DO NOT EDIT.
|
||||
// Generated by {script_name}.
|
||||
//
|
||||
// Copyright {copyright_year} 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.
|
||||
//
|
||||
// Uniform type info table:
|
||||
// Metadata about a particular uniform format, indexed by GL type.
|
||||
|
||||
#include <array>
|
||||
#include "common/utilities.h"
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace gl
|
||||
{{
|
||||
|
||||
namespace
|
||||
{{
|
||||
constexpr std::array<UniformTypeInfo, {total_count}> kInfoTable =
|
||||
{{{{
|
||||
{uniform_type_info_data}
|
||||
}}}};
|
||||
|
||||
size_t GetTypeInfoIndex(GLenum uniformType)
|
||||
{{
|
||||
switch (uniformType)
|
||||
{{
|
||||
{uniform_type_index_cases}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}}
|
||||
}}
|
||||
}} // anonymous namespace
|
||||
|
||||
const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType)
|
||||
{{
|
||||
ASSERT(kInfoTable[GetTypeInfoIndex(uniformType)].type == uniformType);
|
||||
return kInfoTable[GetTypeInfoIndex(uniformType)];
|
||||
}}
|
||||
|
||||
}} // namespace gl
|
||||
"""
|
||||
|
||||
type_info_data_template = """{{{type}, {component_type}, {texture_type}, {transposed_type}, {bool_type}, {rows}, {columns}, {components}, {component_size}, {internal_size}, {external_size}, {is_sampler}, {is_matrix}, {is_image} }}"""
|
||||
type_index_case_template = """case {enum_value}: return {index_value};"""
|
||||
|
||||
def cpp_bool(value):
|
||||
return "true" if value else "false"
|
||||
|
||||
def get_component_type(uniform_type):
|
||||
if uniform_type.find("GL_BOOL") == 0:
|
||||
return "GL_BOOL"
|
||||
elif uniform_type.find("GL_FLOAT") == 0:
|
||||
return "GL_FLOAT"
|
||||
elif uniform_type.find("GL_INT") == 0:
|
||||
return "GL_INT"
|
||||
elif uniform_type.find("GL_UNSIGNED_INT") == 0:
|
||||
return "GL_UNSIGNED_INT"
|
||||
elif uniform_type == "GL_NONE":
|
||||
return "GL_NONE"
|
||||
else:
|
||||
return "GL_INT"
|
||||
|
||||
def get_texture_type(uniform_type):
|
||||
for sampler_type, tex_type in texture_types.items():
|
||||
if sampler_type in uniform_type:
|
||||
return "GL_TEXTURE_" + tex_type
|
||||
return "GL_NONE"
|
||||
|
||||
def get_transposed_type(uniform_type):
|
||||
if "_MAT" in uniform_type:
|
||||
if "x" in uniform_type:
|
||||
return "GL_FLOAT_MAT" + uniform_type[-1] + "x" + uniform_type[uniform_type.find("_MAT")+4]
|
||||
else:
|
||||
return uniform_type
|
||||
else:
|
||||
return "GL_NONE"
|
||||
|
||||
def get_bool_type(uniform_type):
|
||||
if uniform_type == "GL_INT" or uniform_type == "GL_UNSIGNED_INT" or uniform_type == "GL_FLOAT":
|
||||
return "GL_BOOL"
|
||||
elif "_VEC" in uniform_type:
|
||||
return "GL_BOOL_VEC" + uniform_type[-1]
|
||||
else:
|
||||
return "GL_NONE"
|
||||
|
||||
def get_rows(uniform_type):
|
||||
if uniform_type == "GL_NONE":
|
||||
return "0"
|
||||
elif "_MAT" in uniform_type:
|
||||
return uniform_type[-1]
|
||||
else:
|
||||
return "1"
|
||||
|
||||
def get_columns(uniform_type):
|
||||
if uniform_type == "GL_NONE":
|
||||
return "0"
|
||||
elif "_VEC" in uniform_type:
|
||||
return uniform_type[-1]
|
||||
elif "_MAT" in uniform_type:
|
||||
return uniform_type[uniform_type.find("_MAT") + 4]
|
||||
else:
|
||||
return "1"
|
||||
|
||||
def get_components(uniform_type):
|
||||
return str(int(get_rows(uniform_type)) * int(get_columns(uniform_type)))
|
||||
|
||||
def get_component_size(uniform_type):
|
||||
component_type = get_component_type(uniform_type)
|
||||
if (component_type) == "GL_BOOL":
|
||||
return "sizeof(GLint)"
|
||||
elif (component_type) == "GL_FLOAT":
|
||||
return "sizeof(GLfloat)"
|
||||
elif (component_type) == "GL_INT":
|
||||
return "sizeof(GLint)"
|
||||
elif (component_type) == "GL_UNSIGNED_INT":
|
||||
return "sizeof(GLuint)"
|
||||
elif (component_type) == "GL_NONE":
|
||||
return "0"
|
||||
else:
|
||||
raise "Invalid component type: " + component_type
|
||||
|
||||
def get_internal_size(uniform_type):
|
||||
return get_component_size(uniform_type) + " * " + str(int(get_rows(uniform_type)) * 4)
|
||||
|
||||
def get_external_size(uniform_type):
|
||||
return get_component_size(uniform_type) + " * " + get_components(uniform_type)
|
||||
|
||||
def get_is_sampler(uniform_type):
|
||||
return cpp_bool("_SAMPLER_" in uniform_type)
|
||||
|
||||
def get_is_matrix(uniform_type):
|
||||
return cpp_bool("_MAT" in uniform_type)
|
||||
|
||||
def get_is_image(uniform_type):
|
||||
return cpp_bool("_IMAGE_" in uniform_type)
|
||||
|
||||
def gen_type_info(uniform_type):
|
||||
return type_info_data_template.format(
|
||||
type = uniform_type,
|
||||
component_type = get_component_type(uniform_type),
|
||||
texture_type = get_texture_type(uniform_type),
|
||||
transposed_type = get_transposed_type(uniform_type),
|
||||
bool_type = get_bool_type(uniform_type),
|
||||
rows = get_rows(uniform_type),
|
||||
columns = get_columns(uniform_type),
|
||||
components = get_components(uniform_type),
|
||||
component_size = get_component_size(uniform_type),
|
||||
internal_size = get_internal_size(uniform_type),
|
||||
external_size = get_external_size(uniform_type),
|
||||
is_sampler = get_is_sampler(uniform_type),
|
||||
is_matrix = get_is_matrix(uniform_type),
|
||||
is_image = get_is_image(uniform_type))
|
||||
|
||||
def gen_type_index_case(index, uniform_type):
|
||||
return "case " + uniform_type + ": return " + str(index) + ";"
|
||||
|
||||
uniform_type_info_data = ",\n".join([gen_type_info(uniform_type) for uniform_type in all_uniform_types])
|
||||
uniform_type_index_cases = "\n".join([gen_type_index_case(index, uniform_type) for index, uniform_type in enumerate(all_uniform_types)])
|
||||
|
||||
with open('uniform_type_info_autogen.cpp', 'wt') as out_file:
|
||||
output_cpp = template_cpp.format(
|
||||
script_name = sys.argv[0],
|
||||
copyright_year = date.today().year,
|
||||
total_count = len(all_uniform_types),
|
||||
uniform_type_info_data = uniform_type_info_data,
|
||||
uniform_type_index_cases = uniform_type_index_cases)
|
||||
out_file.write(output_cpp)
|
||||
out_file.close()
|
|
@ -1,73 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013 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.
|
||||
//
|
||||
|
||||
// mathutil.cpp: Math and bit manipulation functions.
|
||||
|
||||
#include "common/mathutil.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct RGB9E5Data
|
||||
{
|
||||
unsigned int R : 9;
|
||||
unsigned int G : 9;
|
||||
unsigned int B : 9;
|
||||
unsigned int E : 5;
|
||||
};
|
||||
|
||||
// B is the exponent bias (15)
|
||||
constexpr int g_sharedexp_bias = 15;
|
||||
|
||||
// N is the number of mantissa bits per component (9)
|
||||
constexpr int g_sharedexp_mantissabits = 9;
|
||||
|
||||
// Emax is the maximum allowed biased exponent value (31)
|
||||
constexpr int g_sharedexp_maxexponent = 31;
|
||||
|
||||
constexpr float g_sharedexp_max =
|
||||
((static_cast<float>(1 << g_sharedexp_mantissabits) - 1) /
|
||||
static_cast<float>(1 << g_sharedexp_mantissabits)) *
|
||||
static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias));
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
unsigned int convertRGBFloatsTo999E5(float red, float green, float blue)
|
||||
{
|
||||
const float red_c = std::max<float>(0, std::min(g_sharedexp_max, red));
|
||||
const float green_c = std::max<float>(0, std::min(g_sharedexp_max, green));
|
||||
const float blue_c = std::max<float>(0, std::min(g_sharedexp_max, blue));
|
||||
|
||||
const float max_c = std::max<float>(std::max<float>(red_c, green_c), blue_c);
|
||||
const float exp_p = std::max<float>(-g_sharedexp_bias - 1, floor(log(max_c))) + 1 + g_sharedexp_bias;
|
||||
const int max_s = static_cast<int>(floor((max_c / (pow(2.0f, exp_p - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f));
|
||||
const int exp_s = static_cast<int>((max_s < pow(2.0f, g_sharedexp_mantissabits)) ? exp_p : exp_p + 1);
|
||||
|
||||
RGB9E5Data output;
|
||||
output.R = static_cast<unsigned int>(floor((red_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f));
|
||||
output.G = static_cast<unsigned int>(floor((green_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f));
|
||||
output.B = static_cast<unsigned int>(floor((blue_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f));
|
||||
output.E = exp_s;
|
||||
|
||||
return bitCast<unsigned int>(output);
|
||||
}
|
||||
|
||||
void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue)
|
||||
{
|
||||
const RGB9E5Data *inputData = reinterpret_cast<const RGB9E5Data*>(&input);
|
||||
|
||||
*red = inputData->R * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits);
|
||||
*green = inputData->G * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits);
|
||||
*blue = inputData->B * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits);
|
||||
}
|
||||
|
||||
} // namespace gl
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,368 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// mathutil_unittest:
|
||||
// Unit tests for the utils defined in mathutil.h
|
||||
//
|
||||
|
||||
#include "mathutil.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace gl;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions.
|
||||
// For floats f1 and f2, unpackSnorm2x16(packSnorm2x16(f1, f2)) should be same as f1 and f2.
|
||||
TEST(MathUtilTest, packAndUnpackSnorm2x16)
|
||||
{
|
||||
const float input[8][2] =
|
||||
{
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f },
|
||||
{ 0.875f, 0.75f },
|
||||
{ 0.00392f, -0.99215f },
|
||||
{ -0.000675f, 0.004954f },
|
||||
{ -0.6937f, -0.02146f }
|
||||
};
|
||||
const float floatFaultTolerance = 0.0001f;
|
||||
float outputVal1, outputVal2;
|
||||
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
unpackSnorm2x16(packSnorm2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(input[i][0], outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(input[i][1], outputVal2, floatFaultTolerance);
|
||||
}
|
||||
}
|
||||
|
||||
// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions with infinity values,
|
||||
// result should be clamped to [-1, 1].
|
||||
TEST(MathUtilTest, packAndUnpackSnorm2x16Infinity)
|
||||
{
|
||||
const float floatFaultTolerance = 0.0001f;
|
||||
float outputVal1, outputVal2;
|
||||
|
||||
unpackSnorm2x16(packSnorm2x16(std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity()), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(1.0f, outputVal2, floatFaultTolerance);
|
||||
|
||||
unpackSnorm2x16(packSnorm2x16(std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity()), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(-1.0f, outputVal2, floatFaultTolerance);
|
||||
|
||||
unpackSnorm2x16(packSnorm2x16(-std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity()), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(-1.0f, outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(-1.0f, outputVal2, floatFaultTolerance);
|
||||
}
|
||||
|
||||
// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions.
|
||||
// For floats f1 and f2, unpackUnorm2x16(packUnorm2x16(f1, f2)) should be same as f1 and f2.
|
||||
TEST(MathUtilTest, packAndUnpackUnorm2x16)
|
||||
{
|
||||
const float input[8][2] =
|
||||
{
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f },
|
||||
{ 0.875f, 0.75f },
|
||||
{ 0.00392f, -0.99215f },
|
||||
{ -0.000675f, 0.004954f },
|
||||
{ -0.6937f, -0.02146f }
|
||||
};
|
||||
const float floatFaultTolerance = 0.0001f;
|
||||
float outputVal1, outputVal2;
|
||||
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
unpackUnorm2x16(packUnorm2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2);
|
||||
float expected = input[i][0] < 0.0f ? 0.0f : input[i][0];
|
||||
EXPECT_NEAR(expected, outputVal1, floatFaultTolerance);
|
||||
expected = input[i][1] < 0.0f ? 0.0f : input[i][1];
|
||||
EXPECT_NEAR(expected, outputVal2, floatFaultTolerance);
|
||||
}
|
||||
}
|
||||
|
||||
// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions with infinity values,
|
||||
// result should be clamped to [0, 1].
|
||||
TEST(MathUtilTest, packAndUnpackUnorm2x16Infinity)
|
||||
{
|
||||
const float floatFaultTolerance = 0.0001f;
|
||||
float outputVal1, outputVal2;
|
||||
|
||||
unpackUnorm2x16(packUnorm2x16(std::numeric_limits<float>::infinity(),
|
||||
std::numeric_limits<float>::infinity()), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(1.0f, outputVal2, floatFaultTolerance);
|
||||
|
||||
unpackUnorm2x16(packUnorm2x16(std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity()), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(0.0f, outputVal2, floatFaultTolerance);
|
||||
|
||||
unpackUnorm2x16(packUnorm2x16(-std::numeric_limits<float>::infinity(),
|
||||
-std::numeric_limits<float>::infinity()), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(0.0f, outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(0.0f, outputVal2, floatFaultTolerance);
|
||||
}
|
||||
|
||||
// Test the correctness of packHalf2x16 and unpackHalf2x16 functions.
|
||||
// For floats f1 and f2, unpackHalf2x16(packHalf2x16(f1, f2)) should be same as f1 and f2.
|
||||
TEST(MathUtilTest, packAndUnpackHalf2x16)
|
||||
{
|
||||
const float input[8][2] =
|
||||
{
|
||||
{ 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f },
|
||||
{ 0.875f, 0.75f },
|
||||
{ 0.00392f, -0.99215f },
|
||||
{ -0.000675f, 0.004954f },
|
||||
{ -0.6937f, -0.02146f },
|
||||
};
|
||||
const float floatFaultTolerance = 0.0005f;
|
||||
float outputVal1, outputVal2;
|
||||
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
unpackHalf2x16(packHalf2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2);
|
||||
EXPECT_NEAR(input[i][0], outputVal1, floatFaultTolerance);
|
||||
EXPECT_NEAR(input[i][1], outputVal2, floatFaultTolerance);
|
||||
}
|
||||
}
|
||||
|
||||
// Test the correctness of packUnorm4x8 and unpackUnorm4x8 functions.
|
||||
// For floats f1 to f4, unpackUnorm4x8(packUnorm4x8(f1, f2, f3, f4)) should be same as f1 to f4.
|
||||
TEST(MathUtilTest, packAndUnpackUnorm4x8)
|
||||
{
|
||||
const float input[5][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
{1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{-1.0f, 1.0f, -1.0f, 1.0f},
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f},
|
||||
{64.0f / 255.0f, 128.0f / 255.0f, 32.0f / 255.0f, 16.0f / 255.0f}};
|
||||
|
||||
const float floatFaultTolerance = 0.005f;
|
||||
float outputVals[4];
|
||||
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
UnpackUnorm4x8(PackUnorm4x8(input[i][0], input[i][1], input[i][2], input[i][3]),
|
||||
outputVals);
|
||||
for (size_t j = 0; j < 4; j++)
|
||||
{
|
||||
float expected = input[i][j] < 0.0f ? 0.0f : input[i][j];
|
||||
EXPECT_NEAR(expected, outputVals[j], floatFaultTolerance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test the correctness of packSnorm4x8 and unpackSnorm4x8 functions.
|
||||
// For floats f1 to f4, unpackSnorm4x8(packSnorm4x8(f1, f2, f3, f4)) should be same as f1 to f4.
|
||||
TEST(MathUtilTest, packAndUnpackSnorm4x8)
|
||||
{
|
||||
const float input[5][4] = {{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
{1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{-1.0f, 1.0f, -1.0f, 1.0f},
|
||||
{-1.0f, -1.0f, -1.0f, -1.0f},
|
||||
{64.0f / 127.0f, -8.0f / 127.0f, 32.0f / 127.0f, 16.0f / 127.0f}};
|
||||
|
||||
const float floatFaultTolerance = 0.01f;
|
||||
float outputVals[4];
|
||||
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
UnpackSnorm4x8(PackSnorm4x8(input[i][0], input[i][1], input[i][2], input[i][3]),
|
||||
outputVals);
|
||||
for (size_t j = 0; j < 4; j++)
|
||||
{
|
||||
float expected = input[i][j];
|
||||
EXPECT_NEAR(expected, outputVals[j], floatFaultTolerance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test the correctness of gl::isNaN function.
|
||||
TEST(MathUtilTest, isNaN)
|
||||
{
|
||||
EXPECT_TRUE(isNaN(bitCast<float>(0xffu << 23 | 1u)));
|
||||
EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 1u)));
|
||||
EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 0x400000u)));
|
||||
EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 0x7fffffu)));
|
||||
EXPECT_FALSE(isNaN(0.0f));
|
||||
EXPECT_FALSE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23)));
|
||||
EXPECT_FALSE(isNaN(bitCast<float>(0xffu << 23)));
|
||||
}
|
||||
|
||||
// Test the correctness of gl::isInf function.
|
||||
TEST(MathUtilTest, isInf)
|
||||
{
|
||||
EXPECT_TRUE(isInf(bitCast<float>(0xffu << 23)));
|
||||
EXPECT_TRUE(isInf(bitCast<float>(1u << 31 | 0xffu << 23)));
|
||||
EXPECT_FALSE(isInf(0.0f));
|
||||
EXPECT_FALSE(isInf(bitCast<float>(0xffu << 23 | 1u)));
|
||||
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 1u)));
|
||||
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x400000u)));
|
||||
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x7fffffu)));
|
||||
EXPECT_FALSE(isInf(bitCast<float>(0xfeu << 23 | 0x7fffffu)));
|
||||
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xfeu << 23 | 0x7fffffu)));
|
||||
}
|
||||
|
||||
TEST(MathUtilTest, CountLeadingZeros)
|
||||
{
|
||||
for (unsigned int i = 0; i < 32u; ++i)
|
||||
{
|
||||
uint32_t iLeadingZeros = 1u << (31u - i);
|
||||
EXPECT_EQ(i, CountLeadingZeros(iLeadingZeros));
|
||||
}
|
||||
EXPECT_EQ(32u, CountLeadingZeros(0));
|
||||
}
|
||||
|
||||
// Some basic tests. Tests that rounding up zero produces zero.
|
||||
TEST(MathUtilTest, BasicRoundUp)
|
||||
{
|
||||
EXPECT_EQ(0u, rx::roundUp(0u, 4u));
|
||||
EXPECT_EQ(4u, rx::roundUp(1u, 4u));
|
||||
EXPECT_EQ(4u, rx::roundUp(4u, 4u));
|
||||
}
|
||||
|
||||
// Test that rounding up zero produces zero for checked ints.
|
||||
TEST(MathUtilTest, CheckedRoundUpZero)
|
||||
{
|
||||
auto checkedValue = rx::CheckedRoundUp(0u, 4u);
|
||||
ASSERT_TRUE(checkedValue.IsValid());
|
||||
ASSERT_EQ(0u, checkedValue.ValueOrDie());
|
||||
}
|
||||
|
||||
// Test out-of-bounds with CheckedRoundUp
|
||||
TEST(MathUtilTest, CheckedRoundUpInvalid)
|
||||
{
|
||||
// The answer to this query is out of bounds.
|
||||
auto limit = std::numeric_limits<unsigned int>::max();
|
||||
auto checkedValue = rx::CheckedRoundUp(limit, limit - 1);
|
||||
ASSERT_FALSE(checkedValue.IsValid());
|
||||
|
||||
// Our implementation can't handle this query, despite the parameters being in range.
|
||||
auto checkedLimit = rx::CheckedRoundUp(limit - 1, limit);
|
||||
ASSERT_FALSE(checkedLimit.IsValid());
|
||||
}
|
||||
|
||||
// Test BitfieldReverse which reverses the order of the bits in an integer.
|
||||
TEST(MathUtilTest, BitfieldReverse)
|
||||
{
|
||||
EXPECT_EQ(0u, gl::BitfieldReverse(0u));
|
||||
EXPECT_EQ(0x80000000u, gl::BitfieldReverse(1u));
|
||||
EXPECT_EQ(0x1u, gl::BitfieldReverse(0x80000000u));
|
||||
uint32_t bits = (1u << 4u) | (1u << 7u);
|
||||
uint32_t reversed = (1u << (31u - 4u)) | (1u << (31u - 7u));
|
||||
EXPECT_EQ(reversed, gl::BitfieldReverse(bits));
|
||||
}
|
||||
|
||||
// Test BitCount, which counts 1 bits in an integer.
|
||||
TEST(MathUtilTest, BitCount)
|
||||
{
|
||||
EXPECT_EQ(0, gl::BitCount(0u));
|
||||
EXPECT_EQ(32, gl::BitCount(0xFFFFFFFFu));
|
||||
EXPECT_EQ(10, gl::BitCount(0x17103121u));
|
||||
|
||||
#if defined(ANGLE_X64_CPU)
|
||||
EXPECT_EQ(0, gl::BitCount(0ull));
|
||||
EXPECT_EQ(32, gl::BitCount(0xFFFFFFFFull));
|
||||
EXPECT_EQ(10, gl::BitCount(0x17103121ull));
|
||||
#endif // defined(ANGLE_X64_CPU)
|
||||
}
|
||||
|
||||
// Test ScanForward, which scans for the least significant 1 bit from a non-zero integer.
|
||||
TEST(MathUtilTest, ScanForward)
|
||||
{
|
||||
EXPECT_EQ(0ul, gl::ScanForward(1u));
|
||||
EXPECT_EQ(16ul, gl::ScanForward(0x80010000u));
|
||||
EXPECT_EQ(31ul, gl::ScanForward(0x80000000u));
|
||||
|
||||
#if defined(ANGLE_X64_CPU)
|
||||
EXPECT_EQ(0ul, gl::ScanForward(1ull));
|
||||
EXPECT_EQ(16ul, gl::ScanForward(0x80010000ull));
|
||||
EXPECT_EQ(31ul, gl::ScanForward(0x80000000ull));
|
||||
#endif // defined(ANGLE_X64_CPU)
|
||||
}
|
||||
|
||||
// Test ScanReverse, which scans for the most significant 1 bit from a non-zero integer.
|
||||
TEST(MathUtilTest, ScanReverse)
|
||||
{
|
||||
EXPECT_EQ(0ul, gl::ScanReverse(1ul));
|
||||
EXPECT_EQ(16ul, gl::ScanReverse(0x00010030ul));
|
||||
EXPECT_EQ(31ul, gl::ScanReverse(0x80000000ul));
|
||||
}
|
||||
|
||||
// Test FindLSB, which finds the least significant 1 bit.
|
||||
TEST(MathUtilTest, FindLSB)
|
||||
{
|
||||
EXPECT_EQ(-1, gl::FindLSB(0u));
|
||||
EXPECT_EQ(0, gl::FindLSB(1u));
|
||||
EXPECT_EQ(16, gl::FindLSB(0x80010000u));
|
||||
EXPECT_EQ(31, gl::FindLSB(0x80000000u));
|
||||
}
|
||||
|
||||
// Test FindMSB, which finds the most significant 1 bit.
|
||||
TEST(MathUtilTest, FindMSB)
|
||||
{
|
||||
EXPECT_EQ(-1, gl::FindMSB(0u));
|
||||
EXPECT_EQ(0, gl::FindMSB(1u));
|
||||
EXPECT_EQ(16, gl::FindMSB(0x00010030u));
|
||||
EXPECT_EQ(31, gl::FindMSB(0x80000000u));
|
||||
}
|
||||
|
||||
// Test Ldexp, which combines mantissa and exponent into a floating-point number.
|
||||
TEST(MathUtilTest, Ldexp)
|
||||
{
|
||||
EXPECT_EQ(2.5f, Ldexp(0.625f, 2));
|
||||
EXPECT_EQ(-5.0f, Ldexp(-0.625f, 3));
|
||||
EXPECT_EQ(std::numeric_limits<float>::infinity(), Ldexp(0.625f, 129));
|
||||
EXPECT_EQ(0.0f, Ldexp(1.0f, -129));
|
||||
}
|
||||
|
||||
// Test that Range::extend works as expected.
|
||||
TEST(MathUtilTest, RangeExtend)
|
||||
{
|
||||
RangeI range(0, 0);
|
||||
|
||||
range.extend(5);
|
||||
EXPECT_EQ(0, range.low());
|
||||
EXPECT_EQ(6, range.high());
|
||||
EXPECT_EQ(6, range.length());
|
||||
|
||||
range.extend(-1);
|
||||
EXPECT_EQ(-1, range.low());
|
||||
EXPECT_EQ(6, range.high());
|
||||
EXPECT_EQ(7, range.length());
|
||||
|
||||
range.extend(10);
|
||||
EXPECT_EQ(-1, range.low());
|
||||
EXPECT_EQ(11, range.high());
|
||||
EXPECT_EQ(12, range.length());
|
||||
}
|
||||
|
||||
// Test that Range iteration works as expected.
|
||||
TEST(MathUtilTest, RangeIteration)
|
||||
{
|
||||
RangeI range(0, 10);
|
||||
int expected = 0;
|
||||
for (int value : range)
|
||||
{
|
||||
EXPECT_EQ(expected, value);
|
||||
expected++;
|
||||
}
|
||||
EXPECT_EQ(range.length(), expected);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
|
@ -1,386 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// Matrix:
|
||||
// Utility class implementing various matrix operations.
|
||||
// Supports matrices with minimum 2 and maximum 4 number of rows/columns.
|
||||
//
|
||||
// TODO: Check if we can merge Matrix.h in sample_util with this and replace it with this implementation.
|
||||
// TODO: Rename this file to Matrix.h once we remove Matrix.h in sample_util.
|
||||
|
||||
#ifndef COMMON_MATRIX_UTILS_H_
|
||||
#define COMMON_MATRIX_UTILS_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/mathutil.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
class Matrix
|
||||
{
|
||||
public:
|
||||
Matrix(const std::vector<T> &elements, const unsigned int &numRows, const unsigned int &numCols)
|
||||
: mElements(elements),
|
||||
mRows(numRows),
|
||||
mCols(numCols)
|
||||
{
|
||||
ASSERT(rows() >= 1 && rows() <= 4);
|
||||
ASSERT(columns() >= 1 && columns() <= 4);
|
||||
}
|
||||
|
||||
Matrix(const std::vector<T> &elements, const unsigned int &size)
|
||||
: mElements(elements),
|
||||
mRows(size),
|
||||
mCols(size)
|
||||
{
|
||||
ASSERT(rows() >= 1 && rows() <= 4);
|
||||
ASSERT(columns() >= 1 && columns() <= 4);
|
||||
}
|
||||
|
||||
Matrix(const T *elements, const unsigned int &size)
|
||||
: mRows(size),
|
||||
mCols(size)
|
||||
{
|
||||
ASSERT(rows() >= 1 && rows() <= 4);
|
||||
ASSERT(columns() >= 1 && columns() <= 4);
|
||||
for (size_t i = 0; i < size * size; i++)
|
||||
mElements.push_back(elements[i]);
|
||||
}
|
||||
|
||||
const T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex) const
|
||||
{
|
||||
return mElements[rowIndex * columns() + columnIndex];
|
||||
}
|
||||
|
||||
T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex)
|
||||
{
|
||||
return mElements[rowIndex * columns() + columnIndex];
|
||||
}
|
||||
|
||||
const T &at(const unsigned int &rowIndex, const unsigned int &columnIndex) const
|
||||
{
|
||||
return operator()(rowIndex, columnIndex);
|
||||
}
|
||||
|
||||
Matrix<T> operator*(const Matrix<T> &m)
|
||||
{
|
||||
ASSERT(columns() == m.rows());
|
||||
|
||||
unsigned int resultRows = rows();
|
||||
unsigned int resultCols = m.columns();
|
||||
Matrix<T> result(std::vector<T>(resultRows * resultCols), resultRows, resultCols);
|
||||
for (unsigned int i = 0; i < resultRows; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < resultCols; j++)
|
||||
{
|
||||
T tmp = 0.0f;
|
||||
for (unsigned int k = 0; k < columns(); k++)
|
||||
tmp += at(i, k) * m(k, j);
|
||||
result(i, j) = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int size() const
|
||||
{
|
||||
ASSERT(rows() == columns());
|
||||
return rows();
|
||||
}
|
||||
|
||||
unsigned int rows() const { return mRows; }
|
||||
|
||||
unsigned int columns() const { return mCols; }
|
||||
|
||||
std::vector<T> elements() const { return mElements; }
|
||||
|
||||
Matrix<T> compMult(const Matrix<T> &mat1) const
|
||||
{
|
||||
Matrix result(std::vector<T>(mElements.size()), size());
|
||||
for (unsigned int i = 0; i < columns(); i++)
|
||||
for (unsigned int j = 0; j < rows(); j++)
|
||||
result(i, j) = at(i, j) * mat1(i, j);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix<T> outerProduct(const Matrix<T> &mat1) const
|
||||
{
|
||||
unsigned int cols = mat1.columns();
|
||||
Matrix result(std::vector<T>(rows() * cols), rows(), cols);
|
||||
for (unsigned int i = 0; i < rows(); i++)
|
||||
for (unsigned int j = 0; j < cols; j++)
|
||||
result(i, j) = at(i, 0) * mat1(0, j);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Matrix<T> transpose() const
|
||||
{
|
||||
Matrix result(std::vector<T>(mElements.size()), columns(), rows());
|
||||
for (unsigned int i = 0; i < columns(); i++)
|
||||
for (unsigned int j = 0; j < rows(); j++)
|
||||
result(i, j) = at(j, i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
T determinant() const
|
||||
{
|
||||
ASSERT(rows() == columns());
|
||||
|
||||
switch (size())
|
||||
{
|
||||
case 2:
|
||||
return at(0, 0) * at(1, 1) - at(0, 1) * at(1, 0);
|
||||
|
||||
case 3:
|
||||
return at(0, 0) * at(1, 1) * at(2, 2) +
|
||||
at(0, 1) * at(1, 2) * at(2, 0) +
|
||||
at(0, 2) * at(1, 0) * at(2, 1) -
|
||||
at(0, 2) * at(1, 1) * at(2, 0) -
|
||||
at(0, 1) * at(1, 0) * at(2, 2) -
|
||||
at(0, 0) * at(1, 2) * at(2, 1);
|
||||
|
||||
case 4:
|
||||
{
|
||||
const float minorMatrices[4][3 * 3] =
|
||||
{
|
||||
{
|
||||
at(1, 1), at(2, 1), at(3, 1),
|
||||
at(1, 2), at(2, 2), at(3, 2),
|
||||
at(1, 3), at(2, 3), at(3, 3),
|
||||
},
|
||||
{
|
||||
at(1, 0), at(2, 0), at(3, 0),
|
||||
at(1, 2), at(2, 2), at(3, 2),
|
||||
at(1, 3), at(2, 3), at(3, 3),
|
||||
},
|
||||
{
|
||||
at(1, 0), at(2, 0), at(3, 0),
|
||||
at(1, 1), at(2, 1), at(3, 1),
|
||||
at(1, 3), at(2, 3), at(3, 3),
|
||||
},
|
||||
{
|
||||
at(1, 0), at(2, 0), at(3, 0),
|
||||
at(1, 1), at(2, 1), at(3, 1),
|
||||
at(1, 2), at(2, 2), at(3, 2),
|
||||
}
|
||||
};
|
||||
return at(0, 0) * Matrix<T>(minorMatrices[0], 3).determinant() -
|
||||
at(0, 1) * Matrix<T>(minorMatrices[1], 3).determinant() +
|
||||
at(0, 2) * Matrix<T>(minorMatrices[2], 3).determinant() -
|
||||
at(0, 3) * Matrix<T>(minorMatrices[3], 3).determinant();
|
||||
}
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
return T();
|
||||
}
|
||||
|
||||
Matrix<T> inverse() const
|
||||
{
|
||||
ASSERT(rows() == columns());
|
||||
|
||||
Matrix<T> cof(std::vector<T>(mElements.size()), rows(), columns());
|
||||
switch (size())
|
||||
{
|
||||
case 2:
|
||||
cof(0, 0) = at(1, 1);
|
||||
cof(0, 1) = -at(1, 0);
|
||||
cof(1, 0) = -at(0, 1);
|
||||
cof(1, 1) = at(0, 0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
cof(0, 0) = at(1, 1) * at(2, 2) -
|
||||
at(2, 1) * at(1, 2);
|
||||
cof(0, 1) = -(at(1, 0) * at(2, 2) -
|
||||
at(2, 0) * at(1, 2));
|
||||
cof(0, 2) = at(1, 0) * at(2, 1) -
|
||||
at(2, 0) * at(1, 1);
|
||||
cof(1, 0) = -(at(0, 1) * at(2, 2) -
|
||||
at(2, 1) * at(0, 2));
|
||||
cof(1, 1) = at(0, 0) * at(2, 2) -
|
||||
at(2, 0) * at(0, 2);
|
||||
cof(1, 2) = -(at(0, 0) * at(2, 1) -
|
||||
at(2, 0) * at(0, 1));
|
||||
cof(2, 0) = at(0, 1) * at(1, 2) -
|
||||
at(1, 1) * at(0, 2);
|
||||
cof(2, 1) = -(at(0, 0) * at(1, 2) -
|
||||
at(1, 0) * at(0, 2));
|
||||
cof(2, 2) = at(0, 0) * at(1, 1) -
|
||||
at(1, 0) * at(0, 1);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cof(0, 0) = at(1, 1) * at(2, 2) * at(3, 3) +
|
||||
at(2, 1) * at(3, 2) * at(1, 3) +
|
||||
at(3, 1) * at(1, 2) * at(2, 3) -
|
||||
at(1, 1) * at(3, 2) * at(2, 3) -
|
||||
at(2, 1) * at(1, 2) * at(3, 3) -
|
||||
at(3, 1) * at(2, 2) * at(1, 3);
|
||||
cof(0, 1) = -(at(1, 0) * at(2, 2) * at(3, 3) +
|
||||
at(2, 0) * at(3, 2) * at(1, 3) +
|
||||
at(3, 0) * at(1, 2) * at(2, 3) -
|
||||
at(1, 0) * at(3, 2) * at(2, 3) -
|
||||
at(2, 0) * at(1, 2) * at(3, 3) -
|
||||
at(3, 0) * at(2, 2) * at(1, 3));
|
||||
cof(0, 2) = at(1, 0) * at(2, 1) * at(3, 3) +
|
||||
at(2, 0) * at(3, 1) * at(1, 3) +
|
||||
at(3, 0) * at(1, 1) * at(2, 3) -
|
||||
at(1, 0) * at(3, 1) * at(2, 3) -
|
||||
at(2, 0) * at(1, 1) * at(3, 3) -
|
||||
at(3, 0) * at(2, 1) * at(1, 3);
|
||||
cof(0, 3) = -(at(1, 0) * at(2, 1) * at(3, 2) +
|
||||
at(2, 0) * at(3, 1) * at(1, 2) +
|
||||
at(3, 0) * at(1, 1) * at(2, 2) -
|
||||
at(1, 0) * at(3, 1) * at(2, 2) -
|
||||
at(2, 0) * at(1, 1) * at(3, 2) -
|
||||
at(3, 0) * at(2, 1) * at(1, 2));
|
||||
cof(1, 0) = -(at(0, 1) * at(2, 2) * at(3, 3) +
|
||||
at(2, 1) * at(3, 2) * at(0, 3) +
|
||||
at(3, 1) * at(0, 2) * at(2, 3) -
|
||||
at(0, 1) * at(3, 2) * at(2, 3) -
|
||||
at(2, 1) * at(0, 2) * at(3, 3) -
|
||||
at(3, 1) * at(2, 2) * at(0, 3));
|
||||
cof(1, 1) = at(0, 0) * at(2, 2) * at(3, 3) +
|
||||
at(2, 0) * at(3, 2) * at(0, 3) +
|
||||
at(3, 0) * at(0, 2) * at(2, 3) -
|
||||
at(0, 0) * at(3, 2) * at(2, 3) -
|
||||
at(2, 0) * at(0, 2) * at(3, 3) -
|
||||
at(3, 0) * at(2, 2) * at(0, 3);
|
||||
cof(1, 2) = -(at(0, 0) * at(2, 1) * at(3, 3) +
|
||||
at(2, 0) * at(3, 1) * at(0, 3) +
|
||||
at(3, 0) * at(0, 1) * at(2, 3) -
|
||||
at(0, 0) * at(3, 1) * at(2, 3) -
|
||||
at(2, 0) * at(0, 1) * at(3, 3) -
|
||||
at(3, 0) * at(2, 1) * at(0, 3));
|
||||
cof(1, 3) = at(0, 0) * at(2, 1) * at(3, 2) +
|
||||
at(2, 0) * at(3, 1) * at(0, 2) +
|
||||
at(3, 0) * at(0, 1) * at(2, 2) -
|
||||
at(0, 0) * at(3, 1) * at(2, 2) -
|
||||
at(2, 0) * at(0, 1) * at(3, 2) -
|
||||
at(3, 0) * at(2, 1) * at(0, 2);
|
||||
cof(2, 0) = at(0, 1) * at(1, 2) * at(3, 3) +
|
||||
at(1, 1) * at(3, 2) * at(0, 3) +
|
||||
at(3, 1) * at(0, 2) * at(1, 3) -
|
||||
at(0, 1) * at(3, 2) * at(1, 3) -
|
||||
at(1, 1) * at(0, 2) * at(3, 3) -
|
||||
at(3, 1) * at(1, 2) * at(0, 3);
|
||||
cof(2, 1) = -(at(0, 0) * at(1, 2) * at(3, 3) +
|
||||
at(1, 0) * at(3, 2) * at(0, 3) +
|
||||
at(3, 0) * at(0, 2) * at(1, 3) -
|
||||
at(0, 0) * at(3, 2) * at(1, 3) -
|
||||
at(1, 0) * at(0, 2) * at(3, 3) -
|
||||
at(3, 0) * at(1, 2) * at(0, 3));
|
||||
cof(2, 2) = at(0, 0) * at(1, 1) * at(3, 3) +
|
||||
at(1, 0) * at(3, 1) * at(0, 3) +
|
||||
at(3, 0) * at(0, 1) * at(1, 3) -
|
||||
at(0, 0) * at(3, 1) * at(1, 3) -
|
||||
at(1, 0) * at(0, 1) * at(3, 3) -
|
||||
at(3, 0) * at(1, 1) * at(0, 3);
|
||||
cof(2, 3) = -(at(0, 0) * at(1, 1) * at(3, 2) +
|
||||
at(1, 0) * at(3, 1) * at(0, 2) +
|
||||
at(3, 0) * at(0, 1) * at(1, 2) -
|
||||
at(0, 0) * at(3, 1) * at(1, 2) -
|
||||
at(1, 0) * at(0, 1) * at(3, 2) -
|
||||
at(3, 0) * at(1, 1) * at(0, 2));
|
||||
cof(3, 0) = -(at(0, 1) * at(1, 2) * at(2, 3) +
|
||||
at(1, 1) * at(2, 2) * at(0, 3) +
|
||||
at(2, 1) * at(0, 2) * at(1, 3) -
|
||||
at(0, 1) * at(2, 2) * at(1, 3) -
|
||||
at(1, 1) * at(0, 2) * at(2, 3) -
|
||||
at(2, 1) * at(1, 2) * at(0, 3));
|
||||
cof(3, 1) = at(0, 0) * at(1, 2) * at(2, 3) +
|
||||
at(1, 0) * at(2, 2) * at(0, 3) +
|
||||
at(2, 0) * at(0, 2) * at(1, 3) -
|
||||
at(0, 0) * at(2, 2) * at(1, 3) -
|
||||
at(1, 0) * at(0, 2) * at(2, 3) -
|
||||
at(2, 0) * at(1, 2) * at(0, 3);
|
||||
cof(3, 2) = -(at(0, 0) * at(1, 1) * at(2, 3) +
|
||||
at(1, 0) * at(2, 1) * at(0, 3) +
|
||||
at(2, 0) * at(0, 1) * at(1, 3) -
|
||||
at(0, 0) * at(2, 1) * at(1, 3) -
|
||||
at(1, 0) * at(0, 1) * at(2, 3) -
|
||||
at(2, 0) * at(1, 1) * at(0, 3));
|
||||
cof(3, 3) = at(0, 0) * at(1, 1) * at(2, 2) +
|
||||
at(1, 0) * at(2, 1) * at(0, 2) +
|
||||
at(2, 0) * at(0, 1) * at(1, 2) -
|
||||
at(0, 0) * at(2, 1) * at(1, 2) -
|
||||
at(1, 0) * at(0, 1) * at(2, 2) -
|
||||
at(2, 0) * at(1, 1) * at(0, 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
// The inverse of A is the transpose of the cofactor matrix times the reciprocal of the determinant of A.
|
||||
Matrix<T> adjugateMatrix(cof.transpose());
|
||||
T det = determinant();
|
||||
Matrix<T> result(std::vector<T>(mElements.size()), rows(), columns());
|
||||
for (unsigned int i = 0; i < rows(); i++)
|
||||
for (unsigned int j = 0; j < columns(); j++)
|
||||
result(i, j) = det ? adjugateMatrix(i, j) / det : T();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void setToIdentity()
|
||||
{
|
||||
ASSERT(rows() == columns());
|
||||
|
||||
const auto one = T(1);
|
||||
const auto zero = T(0);
|
||||
|
||||
for (auto &e : mElements)
|
||||
e = zero;
|
||||
|
||||
for (unsigned int i = 0; i < rows(); ++i)
|
||||
{
|
||||
const auto pos = i * columns() + (i % columns());
|
||||
mElements[pos] = one;
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned int Size>
|
||||
static void setToIdentity(T(&matrix)[Size])
|
||||
{
|
||||
static_assert(gl::iSquareRoot<Size>() != 0, "Matrix is not square.");
|
||||
|
||||
const auto cols = gl::iSquareRoot<Size>();
|
||||
const auto one = T(1);
|
||||
const auto zero = T(0);
|
||||
|
||||
for (auto &e : matrix)
|
||||
e = zero;
|
||||
|
||||
for (unsigned int i = 0; i < cols; ++i)
|
||||
{
|
||||
const auto pos = i * cols + (i % cols);
|
||||
matrix[pos] = one;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> mElements;
|
||||
unsigned int mRows;
|
||||
unsigned int mCols;
|
||||
};
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // COMMON_MATRIX_UTILS_H_
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// matrix_utils_unittests:
|
||||
// Unit tests for the matrix utils.
|
||||
//
|
||||
|
||||
#include "matrix_utils.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const unsigned int minDimensions = 2;
|
||||
const unsigned int maxDimensions = 4;
|
||||
|
||||
TEST(MatrixUtilsTest, MatrixConstructorTest)
|
||||
{
|
||||
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
|
||||
{
|
||||
for (unsigned int j = minDimensions; j <= maxDimensions; j++)
|
||||
{
|
||||
unsigned int numElements = i * j;
|
||||
Matrix<float> m(std::vector<float>(numElements, 1.0f), i, j);
|
||||
EXPECT_EQ(m.rows(), i);
|
||||
EXPECT_EQ(m.columns(), j);
|
||||
EXPECT_EQ(m.elements(), std::vector<float>(numElements, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
|
||||
{
|
||||
unsigned int numElements = i * i;
|
||||
Matrix<float> m(std::vector<float>(numElements, 1.0f), i);
|
||||
EXPECT_EQ(m.size(), i);
|
||||
EXPECT_EQ(m.columns(), m.columns());
|
||||
EXPECT_EQ(m.elements(), std::vector<float>(numElements, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MatrixUtilsTest, MatrixCompMultTest)
|
||||
{
|
||||
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
|
||||
{
|
||||
unsigned int numElements = i * i;
|
||||
Matrix<float> m1(std::vector<float>(numElements, 2.0f), i);
|
||||
Matrix<float> actualResult = m1.compMult(m1);
|
||||
std::vector<float> actualResultElements = actualResult.elements();
|
||||
std::vector<float> expectedResultElements(numElements, 4.0f);
|
||||
EXPECT_EQ(expectedResultElements, actualResultElements);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MatrixUtilsTest, MatrixOuterProductTest)
|
||||
{
|
||||
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
|
||||
{
|
||||
for (unsigned int j = minDimensions; j <= maxDimensions; j++)
|
||||
{
|
||||
unsigned int numElements = i * j;
|
||||
Matrix<float> m1(std::vector<float>(numElements, 2.0f), i, 1);
|
||||
Matrix<float> m2(std::vector<float>(numElements, 2.0f), 1, j);
|
||||
Matrix<float> actualResult = m1.outerProduct(m2);
|
||||
EXPECT_EQ(actualResult.rows(), i);
|
||||
EXPECT_EQ(actualResult.columns(), j);
|
||||
std::vector<float> actualResultElements = actualResult.elements();
|
||||
std::vector<float> expectedResultElements(numElements, 4.0f);
|
||||
EXPECT_EQ(expectedResultElements, actualResultElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MatrixUtilsTest, MatrixTransposeTest)
|
||||
{
|
||||
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
|
||||
{
|
||||
for (unsigned int j = minDimensions; j <= maxDimensions; j++)
|
||||
{
|
||||
unsigned int numElements = i * j;
|
||||
Matrix<float> m1(std::vector<float>(numElements, 2.0f), i, j);
|
||||
Matrix<float> expectedResult = Matrix<float>(std::vector<float>(numElements, 2.0f), j, i);
|
||||
Matrix<float> actualResult = m1.transpose();
|
||||
EXPECT_EQ(expectedResult.elements(), actualResult.elements());
|
||||
EXPECT_EQ(actualResult.rows(), expectedResult.rows());
|
||||
EXPECT_EQ(actualResult.columns(), expectedResult.columns());
|
||||
// transpose(transpose(A)) = A
|
||||
Matrix<float> m2 = actualResult.transpose();
|
||||
EXPECT_EQ(m1.elements(), m2.elements());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MatrixUtilsTest, MatrixDeterminantTest)
|
||||
{
|
||||
for (unsigned int i = minDimensions; i <= maxDimensions; i++)
|
||||
{
|
||||
unsigned int numElements = i * i;
|
||||
Matrix<float> m(std::vector<float>(numElements, 2.0f), i);
|
||||
EXPECT_EQ(m.determinant(), 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MatrixUtilsTest, 2x2MatrixInverseTest)
|
||||
{
|
||||
float inputElements[] =
|
||||
{
|
||||
2.0f, 5.0f,
|
||||
3.0f, 7.0f
|
||||
};
|
||||
unsigned int numElements = 4;
|
||||
std::vector<float> input(inputElements, inputElements + numElements);
|
||||
Matrix<float> inputMatrix(input, 2);
|
||||
float identityElements[] =
|
||||
{
|
||||
1.0f, 0.0f,
|
||||
0.0f, 1.0f
|
||||
};
|
||||
std::vector<float> identityMatrix(identityElements, identityElements + numElements);
|
||||
// A * inverse(A) = I, where I is identity matrix.
|
||||
Matrix<float> result = inputMatrix * inputMatrix.inverse();
|
||||
EXPECT_EQ(identityMatrix, result.elements());
|
||||
}
|
||||
|
||||
TEST(MatrixUtilsTest, 3x3MatrixInverseTest)
|
||||
{
|
||||
float inputElements[] =
|
||||
{
|
||||
11.0f, 23.0f, 37.0f,
|
||||
13.0f, 29.0f, 41.0f,
|
||||
19.0f, 31.0f, 43.0f
|
||||
};
|
||||
unsigned int numElements = 9;
|
||||
std::vector<float> input(inputElements, inputElements + numElements);
|
||||
Matrix<float> inputMatrix(input, 3);
|
||||
float identityElements[] =
|
||||
{
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f
|
||||
};
|
||||
std::vector<float> identityMatrix(identityElements, identityElements + numElements);
|
||||
// A * inverse(A) = I, where I is identity matrix.
|
||||
Matrix<float> result = inputMatrix * inputMatrix.inverse();
|
||||
std::vector<float> resultElements = result.elements();
|
||||
const float floatFaultTolarance = 0.000001f;
|
||||
for (size_t i = 0; i < numElements; i++)
|
||||
EXPECT_NEAR(resultElements[i], identityMatrix[i], floatFaultTolarance);
|
||||
}
|
||||
|
||||
TEST(MatrixUtilsTest, 4x4MatrixInverseTest)
|
||||
{
|
||||
float inputElements[] =
|
||||
{
|
||||
29.0f, 43.0f, 61.0f, 79.0f,
|
||||
31.0f, 47.0f, 67.0f, 83.0f,
|
||||
37.0f, 53.0f, 71.0f, 89.0f,
|
||||
41.0f, 59.0f, 73.0f, 97.0f
|
||||
};
|
||||
unsigned int numElements = 16;
|
||||
std::vector<float> input(inputElements, inputElements + numElements);
|
||||
Matrix<float> inputMatrix(input, 4);
|
||||
float identityElements[] =
|
||||
{
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
std::vector<float> identityMatrix(identityElements, identityElements + numElements);
|
||||
// A * inverse(A) = I, where I is identity matrix.
|
||||
Matrix<float> result = inputMatrix * inputMatrix.inverse();
|
||||
std::vector<float> resultElements = result.elements();
|
||||
const float floatFaultTolarance = 0.00001f;
|
||||
for (unsigned int i = 0; i < numElements; i++)
|
||||
EXPECT_NEAR(resultElements[i], identityMatrix[i], floatFaultTolarance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// platform.h: Operating system specific includes and defines.
|
||||
|
||||
#ifndef COMMON_PLATFORM_H_
|
||||
#define COMMON_PLATFORM_H_
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define ANGLE_PLATFORM_WINDOWS 1
|
||||
#elif defined(__APPLE__)
|
||||
# define ANGLE_PLATFORM_APPLE 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#elif defined(ANDROID)
|
||||
# define ANGLE_PLATFORM_ANDROID 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#elif defined(__linux__) || defined(EMSCRIPTEN)
|
||||
# define ANGLE_PLATFORM_LINUX 1
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#elif defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__) || \
|
||||
defined(__DragonFly__) || \
|
||||
defined(__sun) || \
|
||||
defined(__GLIBC__) || \
|
||||
defined(__GNU__) || \
|
||||
defined(__QNX__) || \
|
||||
defined(__Fuchsia__) || \
|
||||
defined(__HAIKU__)
|
||||
# define ANGLE_PLATFORM_POSIX 1
|
||||
#else
|
||||
# error Unsupported platform.
|
||||
#endif
|
||||
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
# ifndef STRICT
|
||||
# define STRICT 1
|
||||
# endif
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# endif
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX 1
|
||||
# endif
|
||||
|
||||
# include <windows.h>
|
||||
# include <intrin.h>
|
||||
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
|
||||
# define ANGLE_ENABLE_WINDOWS_STORE 1
|
||||
# endif
|
||||
|
||||
# if defined(ANGLE_ENABLE_D3D9)
|
||||
# include <d3d9.h>
|
||||
# include <d3dcompiler.h>
|
||||
# endif
|
||||
|
||||
# if defined(ANGLE_ENABLE_D3D11)
|
||||
#include <d3d10_1.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3d11_3.h>
|
||||
#include <d3dcompiler.h>
|
||||
#include <dxgi.h>
|
||||
#include <dxgi1_2.h>
|
||||
# endif
|
||||
|
||||
#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
|
||||
#include <wrl.h>
|
||||
#endif
|
||||
|
||||
# if defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
# include <dxgi1_3.h>
|
||||
# if defined(_DEBUG)
|
||||
# include <DXProgrammableCapture.h>
|
||||
# include <dxgidebug.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# undef near
|
||||
# undef far
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_M_ARM)
|
||||
#include <intrin.h>
|
||||
#define ANGLE_USE_SSE
|
||||
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
|
||||
#include <x86intrin.h>
|
||||
#define ANGLE_USE_SSE
|
||||
#endif
|
||||
|
||||
// The MemoryBarrier function name collides with a macro under Windows
|
||||
// We will undef the macro so that the function name does not get replaced
|
||||
#undef MemoryBarrier
|
||||
|
||||
#endif // COMMON_PLATFORM_H_
|
|
@ -1,190 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// string_utils:
|
||||
// String helper functions.
|
||||
//
|
||||
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "common/platform.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
const char kWhitespaceASCII[] = " \f\n\r\t\v";
|
||||
|
||||
std::vector<std::string> SplitString(const std::string &input,
|
||||
const std::string &delimiters,
|
||||
WhitespaceHandling whitespace,
|
||||
SplitResult resultType)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
if (input.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string::size_type start = 0;
|
||||
while (start != std::string::npos)
|
||||
{
|
||||
auto end = input.find_first_of(delimiters, start);
|
||||
|
||||
std::string piece;
|
||||
if (end == std::string::npos)
|
||||
{
|
||||
piece = input.substr(start);
|
||||
start = std::string::npos;
|
||||
}
|
||||
else
|
||||
{
|
||||
piece = input.substr(start, end - start);
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
if (whitespace == TRIM_WHITESPACE)
|
||||
{
|
||||
piece = TrimString(piece, kWhitespaceASCII);
|
||||
}
|
||||
|
||||
if (resultType == SPLIT_WANT_ALL || !piece.empty())
|
||||
{
|
||||
result.push_back(piece);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SplitStringAlongWhitespace(const std::string &input,
|
||||
std::vector<std::string> *tokensOut)
|
||||
{
|
||||
|
||||
std::istringstream stream(input);
|
||||
std::string line;
|
||||
|
||||
while (std::getline(stream, line))
|
||||
{
|
||||
size_t prev = 0, pos;
|
||||
while ((pos = line.find_first_of(kWhitespaceASCII, prev)) != std::string::npos)
|
||||
{
|
||||
if (pos > prev)
|
||||
tokensOut->push_back(line.substr(prev, pos - prev));
|
||||
prev = pos + 1;
|
||||
}
|
||||
if (prev < line.length())
|
||||
tokensOut->push_back(line.substr(prev, std::string::npos));
|
||||
}
|
||||
}
|
||||
|
||||
std::string TrimString(const std::string &input, const std::string &trimChars)
|
||||
{
|
||||
auto begin = input.find_first_not_of(trimChars);
|
||||
if (begin == std::string::npos)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string::size_type end = input.find_last_not_of(trimChars);
|
||||
if (end == std::string::npos)
|
||||
{
|
||||
return input.substr(begin);
|
||||
}
|
||||
|
||||
return input.substr(begin, end - begin + 1);
|
||||
}
|
||||
|
||||
bool HexStringToUInt(const std::string &input, unsigned int *uintOut)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
|
||||
if (input.size() >= 2 && input[0] == '0' && input[1] == 'x')
|
||||
{
|
||||
offset = 2u;
|
||||
}
|
||||
|
||||
// Simple validity check
|
||||
if (input.find_first_not_of("0123456789ABCDEFabcdef", offset) != std::string::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream inStream(input);
|
||||
inStream >> std::hex >> *uintOut;
|
||||
return !inStream.fail();
|
||||
}
|
||||
|
||||
bool ReadFileToString(const std::string &path, std::string *stringOut)
|
||||
{
|
||||
std::ifstream inFile(path.c_str());
|
||||
if (inFile.fail())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inFile.seekg(0, std::ios::end);
|
||||
stringOut->reserve(static_cast<std::string::size_type>(inFile.tellg()));
|
||||
inFile.seekg(0, std::ios::beg);
|
||||
|
||||
stringOut->assign(std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>());
|
||||
return !inFile.fail();
|
||||
}
|
||||
|
||||
Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString)
|
||||
{
|
||||
std::vector<wchar_t> wcstring(length + 1);
|
||||
#if !defined(ANGLE_PLATFORM_WINDOWS)
|
||||
size_t written = mbstowcs(wcstring.data(), cString, length + 1);
|
||||
if (written == 0)
|
||||
{
|
||||
return Optional<std::vector<wchar_t>>::Invalid();
|
||||
}
|
||||
#else
|
||||
size_t convertedChars = 0;
|
||||
errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, cString, _TRUNCATE);
|
||||
if (err != 0)
|
||||
{
|
||||
return Optional<std::vector<wchar_t>>::Invalid();
|
||||
}
|
||||
#endif
|
||||
return Optional<std::vector<wchar_t>>(wcstring);
|
||||
}
|
||||
|
||||
bool BeginsWith(const std::string &str, const char *prefix)
|
||||
{
|
||||
return strncmp(str.c_str(), prefix, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
bool BeginsWith(const char *str, const char *prefix)
|
||||
{
|
||||
return strncmp(str, prefix, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
bool EndsWith(const std::string &str, const char *suffix)
|
||||
{
|
||||
const auto len = strlen(suffix);
|
||||
if (len > str.size())
|
||||
return false;
|
||||
|
||||
const char *end = str.c_str() + str.size() - len;
|
||||
|
||||
return memcmp(end, suffix, len) == 0;
|
||||
}
|
||||
|
||||
void ToLower(std::string *str)
|
||||
{
|
||||
for (auto &ch : *str)
|
||||
{
|
||||
ch = static_cast<char>(::tolower(ch));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace angle
|
|
@ -1,70 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// string_utils:
|
||||
// String helper functions.
|
||||
//
|
||||
|
||||
#ifndef LIBANGLE_STRING_UTILS_H_
|
||||
#define LIBANGLE_STRING_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/Optional.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
extern const char kWhitespaceASCII[];
|
||||
|
||||
enum WhitespaceHandling
|
||||
{
|
||||
KEEP_WHITESPACE,
|
||||
TRIM_WHITESPACE,
|
||||
};
|
||||
|
||||
enum SplitResult
|
||||
{
|
||||
SPLIT_WANT_ALL,
|
||||
SPLIT_WANT_NONEMPTY,
|
||||
};
|
||||
|
||||
std::vector<std::string> SplitString(const std::string &input,
|
||||
const std::string &delimiters,
|
||||
WhitespaceHandling whitespace,
|
||||
SplitResult resultType);
|
||||
|
||||
void SplitStringAlongWhitespace(const std::string &input,
|
||||
std::vector<std::string> *tokensOut);
|
||||
|
||||
std::string TrimString(const std::string &input, const std::string &trimChars);
|
||||
|
||||
bool HexStringToUInt(const std::string &input, unsigned int *uintOut);
|
||||
|
||||
bool ReadFileToString(const std::string &path, std::string *stringOut);
|
||||
|
||||
Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString);
|
||||
|
||||
// Check if the string str begins with the given prefix.
|
||||
// Prefix may not be NULL and needs to be NULL terminated.
|
||||
// The comparison is case sensitive.
|
||||
bool BeginsWith(const std::string &str, const char *prefix);
|
||||
|
||||
// Check if the string str begins with the given prefix.
|
||||
// str and prefix may not be NULL and need to be NULL terminated.
|
||||
// The comparison is case sensitive.
|
||||
bool BeginsWith(const char *str, const char *prefix);
|
||||
|
||||
// Check if the string str ends with the given suffix.
|
||||
// Suffix may not be NUL and needs to be NULL terminated.
|
||||
// The comparison is case sensitive.
|
||||
bool EndsWith(const std::string& str, const char* suffix);
|
||||
|
||||
// Convert to lower-case.
|
||||
void ToLower(std::string *str);
|
||||
}
|
||||
|
||||
#endif // LIBANGLE_STRING_UTILS_H_
|
|
@ -1,163 +0,0 @@
|
|||
//
|
||||
// Copyright 2015 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.
|
||||
//
|
||||
// string_utils_unittests:
|
||||
// Unit tests for the string utils.
|
||||
//
|
||||
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Basic SplitString tests
|
||||
TEST(StringUtilsTest, SplitString_Basics)
|
||||
{
|
||||
std::vector<std::string> r;
|
||||
|
||||
r = SplitString(std::string(), ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL);
|
||||
EXPECT_TRUE(r.empty());
|
||||
|
||||
// Empty separator list
|
||||
r = SplitString("hello, world", "", KEEP_WHITESPACE, SPLIT_WANT_ALL);
|
||||
ASSERT_EQ(1u, r.size());
|
||||
EXPECT_EQ("hello, world", r[0]);
|
||||
|
||||
// Should split on any of the separators.
|
||||
r = SplitString("::,,;;", ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL);
|
||||
ASSERT_EQ(7u, r.size());
|
||||
for (auto str : r)
|
||||
ASSERT_TRUE(str.empty());
|
||||
|
||||
r = SplitString("red, green; blue:", ",:;", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
|
||||
ASSERT_EQ(3u, r.size());
|
||||
EXPECT_EQ("red", r[0]);
|
||||
EXPECT_EQ("green", r[1]);
|
||||
EXPECT_EQ("blue", r[2]);
|
||||
|
||||
// Want to split a string along whitespace sequences.
|
||||
r = SplitString(" red green \tblue\n", " \t\n", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
|
||||
ASSERT_EQ(3u, r.size());
|
||||
EXPECT_EQ("red", r[0]);
|
||||
EXPECT_EQ("green", r[1]);
|
||||
EXPECT_EQ("blue", r[2]);
|
||||
|
||||
// Weird case of splitting on spaces but not trimming.
|
||||
r = SplitString(" red ", " ", TRIM_WHITESPACE, SPLIT_WANT_ALL);
|
||||
ASSERT_EQ(3u, r.size());
|
||||
EXPECT_EQ("", r[0]); // Before the first space.
|
||||
EXPECT_EQ("red", r[1]);
|
||||
EXPECT_EQ("", r[2]); // After the last space.
|
||||
}
|
||||
|
||||
// Check different whitespace and result types for SplitString
|
||||
TEST(StringUtilsTest, SplitString_WhitespaceAndResultType)
|
||||
{
|
||||
std::vector<std::string> r;
|
||||
|
||||
// Empty input handling.
|
||||
r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_ALL);
|
||||
EXPECT_TRUE(r.empty());
|
||||
r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
|
||||
EXPECT_TRUE(r.empty());
|
||||
|
||||
// Input string is space and we're trimming.
|
||||
r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
|
||||
ASSERT_EQ(1u, r.size());
|
||||
EXPECT_EQ("", r[0]);
|
||||
r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
|
||||
EXPECT_TRUE(r.empty());
|
||||
|
||||
// Test all 4 combinations of flags on ", ,".
|
||||
r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_ALL);
|
||||
ASSERT_EQ(3u, r.size());
|
||||
EXPECT_EQ("", r[0]);
|
||||
EXPECT_EQ(" ", r[1]);
|
||||
EXPECT_EQ("", r[2]);
|
||||
r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
|
||||
ASSERT_EQ(1u, r.size());
|
||||
ASSERT_EQ(" ", r[0]);
|
||||
r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
|
||||
ASSERT_EQ(3u, r.size());
|
||||
EXPECT_EQ("", r[0]);
|
||||
EXPECT_EQ("", r[1]);
|
||||
EXPECT_EQ("", r[2]);
|
||||
r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
|
||||
ASSERT_TRUE(r.empty());
|
||||
}
|
||||
|
||||
// Tests for TrimString
|
||||
TEST(StringUtilsTest, TrimString)
|
||||
{
|
||||
// Basic tests
|
||||
EXPECT_EQ("a", TrimString("a", kWhitespaceASCII));
|
||||
EXPECT_EQ("a", TrimString(" a", kWhitespaceASCII));
|
||||
EXPECT_EQ("a", TrimString("a ", kWhitespaceASCII));
|
||||
EXPECT_EQ("a", TrimString(" a ", kWhitespaceASCII));
|
||||
|
||||
// Tests with empty strings
|
||||
EXPECT_EQ("", TrimString("", kWhitespaceASCII));
|
||||
EXPECT_EQ("", TrimString(" \n\r\t", kWhitespaceASCII));
|
||||
EXPECT_EQ(" foo ", TrimString(" foo ", ""));
|
||||
|
||||
// Tests it doesn't removes characters in the middle
|
||||
EXPECT_EQ("foo bar", TrimString(" foo bar ", kWhitespaceASCII));
|
||||
|
||||
// Test with non-whitespace trimChars
|
||||
EXPECT_EQ(" ", TrimString("foo bar", "abcdefghijklmnopqrstuvwxyz"));
|
||||
}
|
||||
|
||||
// Basic functionality tests for HexStringToUInt
|
||||
TEST(StringUtilsTest, HexStringToUIntBasic)
|
||||
{
|
||||
unsigned int uintValue;
|
||||
|
||||
std::string emptyString;
|
||||
ASSERT_FALSE(HexStringToUInt(emptyString, &uintValue));
|
||||
|
||||
std::string testStringA("0xBADF00D");
|
||||
ASSERT_TRUE(HexStringToUInt(testStringA, &uintValue));
|
||||
EXPECT_EQ(0xBADF00Du, uintValue);
|
||||
|
||||
std::string testStringB("0xBADFOOD");
|
||||
EXPECT_FALSE(HexStringToUInt(testStringB, &uintValue));
|
||||
|
||||
std::string testStringC("BADF00D");
|
||||
EXPECT_TRUE(HexStringToUInt(testStringC, &uintValue));
|
||||
EXPECT_EQ(0xBADF00Du, uintValue);
|
||||
|
||||
std::string testStringD("0x BADF00D");
|
||||
EXPECT_FALSE(HexStringToUInt(testStringD, &uintValue));
|
||||
}
|
||||
|
||||
// Note: ReadFileToString is harder to test
|
||||
|
||||
|
||||
TEST(StringUtilsTest, BeginsEndsWith)
|
||||
{
|
||||
ASSERT_FALSE(BeginsWith("foo", "bar"));
|
||||
ASSERT_FALSE(BeginsWith("", "foo"));
|
||||
ASSERT_FALSE(BeginsWith("foo", "foobar"));
|
||||
|
||||
ASSERT_TRUE(BeginsWith("foobar", "foo"));
|
||||
ASSERT_TRUE(BeginsWith("foobar", ""));
|
||||
ASSERT_TRUE(BeginsWith("foo", "foo"));
|
||||
ASSERT_TRUE(BeginsWith("", ""));
|
||||
|
||||
ASSERT_FALSE(EndsWith("foo", "bar"));
|
||||
ASSERT_FALSE(EndsWith("", "bar"));
|
||||
ASSERT_FALSE(EndsWith("foo", "foobar"));
|
||||
|
||||
ASSERT_TRUE(EndsWith("foobar", "bar"));
|
||||
ASSERT_TRUE(EndsWith("foobar", ""));
|
||||
ASSERT_TRUE(EndsWith("bar", "bar"));
|
||||
ASSERT_TRUE(EndsWith("", ""));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// system_utils.h: declaration of OS-specific utility functions
|
||||
|
||||
#ifndef COMMON_SYSTEM_UTILS_H_
|
||||
#define COMMON_SYSTEM_UTILS_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "common/Optional.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
const char *GetExecutablePath();
|
||||
const char *GetExecutableDirectory();
|
||||
const char *GetSharedLibraryExtension();
|
||||
Optional<std::string> GetCWD();
|
||||
bool SetCWD(const char *dirName);
|
||||
bool SetEnvironmentVar(const char *variableName, const char *value);
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // COMMON_SYSTEM_UTILS_H_
|
|
@ -1,89 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2015 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.
|
||||
//
|
||||
|
||||
// system_utils_linux.cpp: Implementation of OS-specific functions for Linux
|
||||
|
||||
#include "system_utils.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string GetExecutablePathImpl()
|
||||
{
|
||||
// We cannot use lstat to get the size of /proc/self/exe as it always returns 0
|
||||
// so we just use a big buffer and hope the path fits in it.
|
||||
char path[4096];
|
||||
|
||||
ssize_t result = readlink("/proc/self/exe", path, sizeof(path) - 1);
|
||||
if (result < 0 || static_cast<size_t>(result) >= sizeof(path) - 1)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
path[result] = '\0';
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string GetExecutableDirectoryImpl()
|
||||
{
|
||||
std::string executablePath = GetExecutablePath();
|
||||
size_t lastPathSepLoc = executablePath.find_last_of("/");
|
||||
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
const char *GetExecutablePath()
|
||||
{
|
||||
// TODO(jmadill): Make global static string thread-safe.
|
||||
const static std::string &exePath = GetExecutablePathImpl();
|
||||
return exePath.c_str();
|
||||
}
|
||||
|
||||
const char *GetExecutableDirectory()
|
||||
{
|
||||
// TODO(jmadill): Make global static string thread-safe.
|
||||
const static std::string &exeDir = GetExecutableDirectoryImpl();
|
||||
return exeDir.c_str();
|
||||
}
|
||||
|
||||
const char *GetSharedLibraryExtension()
|
||||
{
|
||||
return "so";
|
||||
}
|
||||
|
||||
Optional<std::string> GetCWD()
|
||||
{
|
||||
std::array<char, 4096> pathBuf;
|
||||
char *result = getcwd(pathBuf.data(), pathBuf.size());
|
||||
if (result == nullptr)
|
||||
{
|
||||
return Optional<std::string>::Invalid();
|
||||
}
|
||||
return std::string(pathBuf.data());
|
||||
}
|
||||
|
||||
bool SetCWD(const char *dirName)
|
||||
{
|
||||
return (chdir(dirName) == 0);
|
||||
}
|
||||
|
||||
bool SetEnvironmentVar(const char *variableName, const char *value)
|
||||
{
|
||||
return (setenv(variableName, value, 1) == 0);
|
||||
}
|
||||
|
||||
} // namespace angle
|
|
@ -1,94 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2015 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.
|
||||
//
|
||||
|
||||
// system_utils_osx.cpp: Implementation of OS-specific functions for OSX
|
||||
|
||||
#include "system_utils.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <vector>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string GetExecutablePathImpl()
|
||||
{
|
||||
std::string result;
|
||||
|
||||
uint32_t size = 0;
|
||||
_NSGetExecutablePath(nullptr, &size);
|
||||
|
||||
std::vector<char> buffer;
|
||||
buffer.resize(size + 1);
|
||||
|
||||
_NSGetExecutablePath(buffer.data(), &size);
|
||||
buffer[size] = '\0';
|
||||
|
||||
if (!strrchr(buffer.data(), '/'))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return buffer.data();
|
||||
}
|
||||
|
||||
std::string GetExecutableDirectoryImpl()
|
||||
{
|
||||
std::string executablePath = GetExecutablePath();
|
||||
size_t lastPathSepLoc = executablePath.find_last_of("/");
|
||||
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
const char *GetExecutablePath()
|
||||
{
|
||||
// TODO(jmadill): Make global static string thread-safe.
|
||||
const static std::string &exePath = GetExecutablePathImpl();
|
||||
return exePath.c_str();
|
||||
}
|
||||
|
||||
const char *GetExecutableDirectory()
|
||||
{
|
||||
// TODO(jmadill): Make global static string thread-safe.
|
||||
const static std::string &exeDir = GetExecutableDirectoryImpl();
|
||||
return exeDir.c_str();
|
||||
}
|
||||
|
||||
const char *GetSharedLibraryExtension()
|
||||
{
|
||||
return "dylib";
|
||||
}
|
||||
|
||||
Optional<std::string> GetCWD()
|
||||
{
|
||||
std::array<char, 4096> pathBuf;
|
||||
char *result = getcwd(pathBuf.data(), pathBuf.size());
|
||||
if (result == nullptr)
|
||||
{
|
||||
return Optional<std::string>::Invalid();
|
||||
}
|
||||
return std::string(pathBuf.data());
|
||||
}
|
||||
|
||||
bool SetCWD(const char *dirName)
|
||||
{
|
||||
return (chdir(dirName) == 0);
|
||||
}
|
||||
|
||||
bool SetEnvironmentVar(const char *variableName, const char *value)
|
||||
{
|
||||
return (setenv(variableName, value, 1) == 0);
|
||||
}
|
||||
|
||||
} // namespace angle
|
|
@ -1,79 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// system_utils_win.cpp: Implementation of OS-specific functions for Windows
|
||||
|
||||
#include "system_utils.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <windows.h>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string GetExecutablePathImpl()
|
||||
{
|
||||
std::array<char, MAX_PATH> executableFileBuf;
|
||||
DWORD executablePathLen = GetModuleFileNameA(nullptr, executableFileBuf.data(),
|
||||
static_cast<DWORD>(executableFileBuf.size()));
|
||||
return (executablePathLen > 0 ? std::string(executableFileBuf.data()) : "");
|
||||
}
|
||||
|
||||
std::string GetExecutableDirectoryImpl()
|
||||
{
|
||||
std::string executablePath = GetExecutablePath();
|
||||
size_t lastPathSepLoc = executablePath.find_last_of("\\/");
|
||||
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
const char *GetExecutablePath()
|
||||
{
|
||||
// TODO(jmadill): Make global static string thread-safe.
|
||||
const static std::string &exePath = GetExecutablePathImpl();
|
||||
return exePath.c_str();
|
||||
}
|
||||
|
||||
const char *GetExecutableDirectory()
|
||||
{
|
||||
// TODO(jmadill): Make global static string thread-safe.
|
||||
const static std::string &exeDir = GetExecutableDirectoryImpl();
|
||||
return exeDir.c_str();
|
||||
}
|
||||
|
||||
const char *GetSharedLibraryExtension()
|
||||
{
|
||||
return "dll";
|
||||
}
|
||||
|
||||
Optional<std::string> GetCWD()
|
||||
{
|
||||
std::array<char, MAX_PATH> pathBuf;
|
||||
DWORD result = GetCurrentDirectoryA(static_cast<DWORD>(pathBuf.size()), pathBuf.data());
|
||||
if (result == 0)
|
||||
{
|
||||
return Optional<std::string>::Invalid();
|
||||
}
|
||||
return std::string(pathBuf.data());
|
||||
}
|
||||
|
||||
bool SetCWD(const char *dirName)
|
||||
{
|
||||
return (SetCurrentDirectoryA(dirName) == TRUE);
|
||||
}
|
||||
|
||||
bool SetEnvironmentVar(const char *variableName, const char *value)
|
||||
{
|
||||
return (SetEnvironmentVariableA(variableName, value) == TRUE);
|
||||
}
|
||||
|
||||
} // namespace angle
|
|
@ -1,27 +0,0 @@
|
|||
Name: Chromium base:: helper Classes
|
||||
Short Name: base::numerics, base::MRUCachem, base::SHA1
|
||||
Version:
|
||||
URL: https://chromium.googlesource.com/chromium/src/base/+/master
|
||||
SOURCE CODE: Copy the Chromium folder manually into this folder and run git cl format.
|
||||
Date: 24/05/2017
|
||||
Revision: 28b5bbb227d331c01e6ff9b2f8729732135aadc7 (Chromium)
|
||||
Security Critical: no
|
||||
License: Chromium
|
||||
License File: LICENSE in Chromium/src
|
||||
|
||||
Description:
|
||||
base::numerics is a library for doing some simple safe math and conversions.
|
||||
base::MRUCache is a few collections of most-recently-used caching structures.
|
||||
base::SHA1 is a secure hashing algorithm.
|
||||
|
||||
To update the checkout, simply overwrite the folder with Chromium's latest, apply
|
||||
the appropriate namespace, and make sure the paths are correct (anglebase/ instead of
|
||||
base/), and update the header guards and macros.
|
||||
|
||||
Modifications:
|
||||
|
||||
- the file scope is now anglebase/ from base/ to prevent include conflicts.
|
||||
- anglebase/logging.h defines (D)CHECK to be ASSERT to be compatible with ANGLE.
|
||||
- the headers use namespace angle::base instead of base:: to avoid ODR
|
||||
violations when ANGLE code is mixed with Chromium code.
|
||||
- header guards and macros are changed from BASE to ANGLEBASE to prevent conflicts.
|
|
@ -1,13 +0,0 @@
|
|||
//
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
// base_export.h: Compatiblity hacks for importing Chromium's base/SHA1.
|
||||
|
||||
#ifndef ANGLEBASE_BASE_EXPORT_H_
|
||||
#define ANGLEBASE_BASE_EXPORT_H_
|
||||
|
||||
#define ANGLEBASE_EXPORT
|
||||
|
||||
#endif // ANGLEBASE_BASE_EXPORT_H_
|
|
@ -1,275 +0,0 @@
|
|||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// This file contains a template for a Most Recently Used cache that allows
|
||||
// constant-time access to items using a key, but easy identification of the
|
||||
// least-recently-used items for removal. Each key can only be associated with
|
||||
// one payload item at a time.
|
||||
//
|
||||
// The key object will be stored twice, so it should support efficient copying.
|
||||
//
|
||||
// NOTE: While all operations are O(1), this code is written for
|
||||
// legibility rather than optimality. If future profiling identifies this as
|
||||
// a bottleneck, there is room for smaller values of 1 in the O(1). :]
|
||||
|
||||
#ifndef ANGLEBASE_CONTAINERS_MRU_CACHE_H_
|
||||
#define ANGLEBASE_CONTAINERS_MRU_CACHE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include "anglebase/logging.h"
|
||||
#include "anglebase/macros.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
|
||||
// MRUCacheBase ----------------------------------------------------------------
|
||||
|
||||
// This template is used to standardize map type containers that can be used
|
||||
// by MRUCacheBase. This level of indirection is necessary because of the way
|
||||
// that template template params and default template params interact.
|
||||
template <class KeyType, class ValueType, class CompareType>
|
||||
struct MRUCacheStandardMap
|
||||
{
|
||||
typedef std::map<KeyType, ValueType, CompareType> Type;
|
||||
};
|
||||
|
||||
// Base class for the MRU cache specializations defined below.
|
||||
template <class KeyType,
|
||||
class PayloadType,
|
||||
class HashOrCompareType,
|
||||
template <typename, typename, typename> class MapType = MRUCacheStandardMap>
|
||||
class MRUCacheBase
|
||||
{
|
||||
public:
|
||||
// The payload of the list. This maintains a copy of the key so we can
|
||||
// efficiently delete things given an element of the list.
|
||||
typedef std::pair<KeyType, PayloadType> value_type;
|
||||
|
||||
private:
|
||||
typedef std::list<value_type> PayloadList;
|
||||
typedef
|
||||
typename MapType<KeyType, typename PayloadList::iterator, HashOrCompareType>::Type KeyIndex;
|
||||
|
||||
public:
|
||||
typedef typename PayloadList::size_type size_type;
|
||||
|
||||
typedef typename PayloadList::iterator iterator;
|
||||
typedef typename PayloadList::const_iterator const_iterator;
|
||||
typedef typename PayloadList::reverse_iterator reverse_iterator;
|
||||
typedef typename PayloadList::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
enum
|
||||
{
|
||||
NO_AUTO_EVICT = 0
|
||||
};
|
||||
|
||||
// The max_size is the size at which the cache will prune its members to when
|
||||
// a new item is inserted. If the caller wants to manager this itself (for
|
||||
// example, maybe it has special work to do when something is evicted), it
|
||||
// can pass NO_AUTO_EVICT to not restrict the cache size.
|
||||
explicit MRUCacheBase(size_type max_size) : max_size_(max_size) {}
|
||||
|
||||
virtual ~MRUCacheBase() {}
|
||||
|
||||
size_type max_size() const { return max_size_; }
|
||||
|
||||
// Inserts a payload item with the given key. If an existing item has
|
||||
// the same key, it is removed prior to insertion. An iterator indicating the
|
||||
// inserted item will be returned (this will always be the front of the list).
|
||||
//
|
||||
// The payload will be forwarded.
|
||||
template <typename Payload>
|
||||
iterator Put(const KeyType &key, Payload &&payload)
|
||||
{
|
||||
// Remove any existing payload with that key.
|
||||
typename KeyIndex::iterator index_iter = index_.find(key);
|
||||
if (index_iter != index_.end())
|
||||
{
|
||||
// Erase the reference to it. The index reference will be replaced in the
|
||||
// code below.
|
||||
Erase(index_iter->second);
|
||||
}
|
||||
else if (max_size_ != NO_AUTO_EVICT)
|
||||
{
|
||||
// New item is being inserted which might make it larger than the maximum
|
||||
// size: kick the oldest thing out if necessary.
|
||||
ShrinkToSize(max_size_ - 1);
|
||||
}
|
||||
|
||||
ordering_.emplace_front(key, std::forward<Payload>(payload));
|
||||
index_.emplace(key, ordering_.begin());
|
||||
return ordering_.begin();
|
||||
}
|
||||
|
||||
// Retrieves the contents of the given key, or end() if not found. This method
|
||||
// has the side effect of moving the requested item to the front of the
|
||||
// recency list.
|
||||
iterator Get(const KeyType &key)
|
||||
{
|
||||
typename KeyIndex::iterator index_iter = index_.find(key);
|
||||
if (index_iter == index_.end())
|
||||
return end();
|
||||
typename PayloadList::iterator iter = index_iter->second;
|
||||
|
||||
// Move the touched item to the front of the recency ordering.
|
||||
ordering_.splice(ordering_.begin(), ordering_, iter);
|
||||
return ordering_.begin();
|
||||
}
|
||||
|
||||
// Retrieves the payload associated with a given key and returns it via
|
||||
// result without affecting the ordering (unlike Get).
|
||||
iterator Peek(const KeyType &key)
|
||||
{
|
||||
typename KeyIndex::const_iterator index_iter = index_.find(key);
|
||||
if (index_iter == index_.end())
|
||||
return end();
|
||||
return index_iter->second;
|
||||
}
|
||||
|
||||
const_iterator Peek(const KeyType &key) const
|
||||
{
|
||||
typename KeyIndex::const_iterator index_iter = index_.find(key);
|
||||
if (index_iter == index_.end())
|
||||
return end();
|
||||
return index_iter->second;
|
||||
}
|
||||
|
||||
// Exchanges the contents of |this| by the contents of the |other|.
|
||||
void Swap(MRUCacheBase &other)
|
||||
{
|
||||
ordering_.swap(other.ordering_);
|
||||
index_.swap(other.index_);
|
||||
std::swap(max_size_, other.max_size_);
|
||||
}
|
||||
|
||||
// Erases the item referenced by the given iterator. An iterator to the item
|
||||
// following it will be returned. The iterator must be valid.
|
||||
iterator Erase(iterator pos)
|
||||
{
|
||||
index_.erase(pos->first);
|
||||
return ordering_.erase(pos);
|
||||
}
|
||||
|
||||
// MRUCache entries are often processed in reverse order, so we add this
|
||||
// convenience function (not typically defined by STL containers).
|
||||
reverse_iterator Erase(reverse_iterator pos)
|
||||
{
|
||||
// We have to actually give it the incremented iterator to delete, since
|
||||
// the forward iterator that base() returns is actually one past the item
|
||||
// being iterated over.
|
||||
return reverse_iterator(Erase((++pos).base()));
|
||||
}
|
||||
|
||||
// Shrinks the cache so it only holds |new_size| items. If |new_size| is
|
||||
// bigger or equal to the current number of items, this will do nothing.
|
||||
void ShrinkToSize(size_type new_size)
|
||||
{
|
||||
for (size_type i = size(); i > new_size; i--)
|
||||
Erase(rbegin());
|
||||
}
|
||||
|
||||
// Deletes everything from the cache.
|
||||
void Clear()
|
||||
{
|
||||
index_.clear();
|
||||
ordering_.clear();
|
||||
}
|
||||
|
||||
// Returns the number of elements in the cache.
|
||||
size_type size() const
|
||||
{
|
||||
// We don't use ordering_.size() for the return value because
|
||||
// (as a linked list) it can be O(n).
|
||||
DCHECK(index_.size() == ordering_.size());
|
||||
return index_.size();
|
||||
}
|
||||
|
||||
// Allows iteration over the list. Forward iteration starts with the most
|
||||
// recent item and works backwards.
|
||||
//
|
||||
// Note that since these iterators are actually iterators over a list, you
|
||||
// can keep them as you insert or delete things (as long as you don't delete
|
||||
// the one you are pointing to) and they will still be valid.
|
||||
iterator begin() { return ordering_.begin(); }
|
||||
const_iterator begin() const { return ordering_.begin(); }
|
||||
iterator end() { return ordering_.end(); }
|
||||
const_iterator end() const { return ordering_.end(); }
|
||||
|
||||
reverse_iterator rbegin() { return ordering_.rbegin(); }
|
||||
const_reverse_iterator rbegin() const { return ordering_.rbegin(); }
|
||||
reverse_iterator rend() { return ordering_.rend(); }
|
||||
const_reverse_iterator rend() const { return ordering_.rend(); }
|
||||
|
||||
bool empty() const { return ordering_.empty(); }
|
||||
|
||||
private:
|
||||
PayloadList ordering_;
|
||||
KeyIndex index_;
|
||||
|
||||
size_type max_size_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MRUCacheBase);
|
||||
};
|
||||
|
||||
// MRUCache --------------------------------------------------------------------
|
||||
|
||||
// A container that does not do anything to free its data. Use this when storing
|
||||
// value types (as opposed to pointers) in the list.
|
||||
template <class KeyType, class PayloadType, class CompareType = std::less<KeyType>>
|
||||
class MRUCache : public MRUCacheBase<KeyType, PayloadType, CompareType>
|
||||
{
|
||||
private:
|
||||
using ParentType = MRUCacheBase<KeyType, PayloadType, CompareType>;
|
||||
|
||||
public:
|
||||
// See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT.
|
||||
explicit MRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {}
|
||||
virtual ~MRUCache() {}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(MRUCache);
|
||||
};
|
||||
|
||||
// HashingMRUCache ------------------------------------------------------------
|
||||
|
||||
template <class KeyType, class ValueType, class HashType>
|
||||
struct MRUCacheHashMap
|
||||
{
|
||||
typedef std::unordered_map<KeyType, ValueType, HashType> Type;
|
||||
};
|
||||
|
||||
// This class is similar to MRUCache, except that it uses std::unordered_map as
|
||||
// the map type instead of std::map. Note that your KeyType must be hashable to
|
||||
// use this cache or you need to provide a hashing class.
|
||||
template <class KeyType, class PayloadType, class HashType = std::hash<KeyType>>
|
||||
class HashingMRUCache : public MRUCacheBase<KeyType, PayloadType, HashType, MRUCacheHashMap>
|
||||
{
|
||||
private:
|
||||
using ParentType = MRUCacheBase<KeyType, PayloadType, HashType, MRUCacheHashMap>;
|
||||
|
||||
public:
|
||||
// See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT.
|
||||
explicit HashingMRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {}
|
||||
virtual ~HashingMRUCache() {}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(HashingMRUCache);
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLEBASE_CONTAINERS_MRU_CACHE_H_
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// Copyright 2016 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.
|
||||
//
|
||||
// logging.h: Compatiblity hacks for importing Chromium's base/numerics.
|
||||
|
||||
#ifndef ANGLEBASE_LOGGING_H_
|
||||
#define ANGLEBASE_LOGGING_H_
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
#ifndef DCHECK
|
||||
#define DCHECK(X) ASSERT(X)
|
||||
#endif
|
||||
|
||||
#ifndef CHECK
|
||||
#define CHECK(X) ASSERT(X)
|
||||
#endif
|
||||
|
||||
// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect.
|
||||
#ifndef NOTREACHED
|
||||
#define NOTREACHED() UNREACHABLE()
|
||||
#endif
|
||||
|
||||
#endif // ANGLEBASE_LOGGING_H_
|
|
@ -1,17 +0,0 @@
|
|||
//
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
// macros.h: Compatiblity hacks for importing Chromium's MRUCache.
|
||||
|
||||
#ifndef ANGLEBASE_MACROS_H_
|
||||
#define ANGLEBASE_MACROS_H_
|
||||
|
||||
// A macro to disallow the copy constructor and operator= functions.
|
||||
// This should be used in the private: declarations for a class.
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName &) = delete; \
|
||||
void operator=(const TypeName &) = delete
|
||||
|
||||
#endif // ANGLEBASE_MACROS_H_
|
|
@ -1,3 +0,0 @@
|
|||
jschuh@chromium.org
|
||||
tsepez@chromium.org
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
// Copyright 2014 The Chromium 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 ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_H_
|
||||
#define ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "anglebase/logging.h"
|
||||
#include "anglebase/numerics/safe_conversions_impl.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
|
||||
// Convenience function that returns true if the supplied value is in range
|
||||
// for the destination type.
|
||||
template <typename Dst, typename Src>
|
||||
constexpr bool IsValueInRangeForNumericType(Src value)
|
||||
{
|
||||
return internal::DstRangeRelationToSrcRange<Dst>(value) == internal::RANGE_VALID;
|
||||
}
|
||||
|
||||
// Convenience function for determining if a numeric value is negative without
|
||||
// throwing compiler warnings on: unsigned(value) < 0.
|
||||
template <typename T>
|
||||
constexpr typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type IsValueNegative(
|
||||
T value)
|
||||
{
|
||||
static_assert(std::numeric_limits<T>::is_specialized, "Argument must be numeric.");
|
||||
return value < 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type IsValueNegative(T)
|
||||
{
|
||||
static_assert(std::numeric_limits<T>::is_specialized, "Argument must be numeric.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// checked_cast<> is analogous to static_cast<> for numeric types,
|
||||
// except that it CHECKs that the specified numeric conversion will not
|
||||
// overflow or underflow. NaN source will always trigger a CHECK.
|
||||
template <typename Dst, typename Src>
|
||||
inline Dst checked_cast(Src value)
|
||||
{
|
||||
CHECK(IsValueInRangeForNumericType<Dst>(value));
|
||||
return static_cast<Dst>(value);
|
||||
}
|
||||
|
||||
// HandleNaN will cause this class to CHECK(false).
|
||||
struct SaturatedCastNaNBehaviorCheck
|
||||
{
|
||||
template <typename T>
|
||||
static T HandleNaN()
|
||||
{
|
||||
CHECK(false);
|
||||
return T();
|
||||
}
|
||||
};
|
||||
|
||||
// HandleNaN will return 0 in this case.
|
||||
struct SaturatedCastNaNBehaviorReturnZero
|
||||
{
|
||||
template <typename T>
|
||||
static constexpr T HandleNaN()
|
||||
{
|
||||
return T();
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
// This wrapper is used for C++11 constexpr support by avoiding the declaration
|
||||
// of local variables in the saturated_cast template function.
|
||||
template <typename Dst, class NaNHandler, typename Src>
|
||||
constexpr Dst saturated_cast_impl(const Src value, const RangeConstraint constraint)
|
||||
{
|
||||
return constraint == RANGE_VALID
|
||||
? static_cast<Dst>(value)
|
||||
: (constraint == RANGE_UNDERFLOW
|
||||
? std::numeric_limits<Dst>::min()
|
||||
: (constraint == RANGE_OVERFLOW
|
||||
? std::numeric_limits<Dst>::max()
|
||||
: (constraint == RANGE_INVALID
|
||||
? NaNHandler::template HandleNaN<Dst>()
|
||||
: (NOTREACHED(), static_cast<Dst>(value)))));
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
// saturated_cast<> is analogous to static_cast<> for numeric types, except
|
||||
// that the specified numeric conversion will saturate rather than overflow or
|
||||
// underflow. NaN assignment to an integral will defer the behavior to a
|
||||
// specified class. By default, it will return 0.
|
||||
template <typename Dst, class NaNHandler = SaturatedCastNaNBehaviorReturnZero, typename Src>
|
||||
constexpr Dst saturated_cast(Src value)
|
||||
{
|
||||
return std::numeric_limits<Dst>::is_iec559
|
||||
? static_cast<Dst>(value) // Floating point optimization.
|
||||
: internal::saturated_cast_impl<Dst, NaNHandler>(
|
||||
value, internal::DstRangeRelationToSrcRange<Dst>(value));
|
||||
}
|
||||
|
||||
// strict_cast<> is analogous to static_cast<> for numeric types, except that
|
||||
// it will cause a compile failure if the destination type is not large enough
|
||||
// to contain any value in the source type. It performs no runtime checking.
|
||||
template <typename Dst, typename Src>
|
||||
constexpr Dst strict_cast(Src value)
|
||||
{
|
||||
static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
|
||||
static_assert(std::numeric_limits<Dst>::is_specialized, "Result must be numeric.");
|
||||
static_assert((internal::StaticDstRangeRelationToSrcRange<Dst, Src>::value ==
|
||||
internal::NUMERIC_RANGE_CONTAINED),
|
||||
"The numeric conversion is out of range for this type. You "
|
||||
"should probably use one of the following conversion "
|
||||
"mechanisms on the value you want to pass:\n"
|
||||
"- base::checked_cast\n"
|
||||
"- base::saturated_cast\n"
|
||||
"- base::CheckedNumeric");
|
||||
|
||||
return static_cast<Dst>(value);
|
||||
}
|
||||
|
||||
// StrictNumeric implements compile time range checking between numeric types by
|
||||
// wrapping assignment operations in a strict_cast. This class is intended to be
|
||||
// used for function arguments and return types, to ensure the destination type
|
||||
// can always contain the source type. This is essentially the same as enforcing
|
||||
// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied
|
||||
// incrementally at API boundaries, making it easier to convert code so that it
|
||||
// compiles cleanly with truncation warnings enabled.
|
||||
// This template should introduce no runtime overhead, but it also provides no
|
||||
// runtime checking of any of the associated mathematical operations. Use
|
||||
// CheckedNumeric for runtime range checks of the actual value being assigned.
|
||||
template <typename T>
|
||||
class StrictNumeric
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
constexpr StrictNumeric() : value_(0) {}
|
||||
|
||||
// Copy constructor.
|
||||
template <typename Src>
|
||||
constexpr StrictNumeric(const StrictNumeric<Src> &rhs) : value_(strict_cast<T>(rhs.value_))
|
||||
{
|
||||
}
|
||||
|
||||
// This is not an explicit constructor because we implicitly upgrade regular
|
||||
// numerics to StrictNumerics to make them easier to use.
|
||||
template <typename Src>
|
||||
constexpr StrictNumeric(Src value) : value_(strict_cast<T>(value))
|
||||
{
|
||||
}
|
||||
|
||||
// The numeric cast operator basically handles all the magic.
|
||||
template <typename Dst>
|
||||
constexpr operator Dst() const
|
||||
{
|
||||
return strict_cast<Dst>(value_);
|
||||
}
|
||||
|
||||
private:
|
||||
const T value_;
|
||||
};
|
||||
|
||||
// Explicitly make a shorter size_t typedef for convenience.
|
||||
typedef StrictNumeric<size_t> SizeT;
|
||||
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_H_
|
|
@ -1,274 +0,0 @@
|
|||
// Copyright 2014 The Chromium 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 ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
|
||||
#define ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
// The std library doesn't provide a binary max_exponent for integers, however
|
||||
// we can compute one by adding one to the number of non-sign bits. This allows
|
||||
// for accurate range comparisons between floating point and integer types.
|
||||
template <typename NumericType>
|
||||
struct MaxExponent
|
||||
{
|
||||
static_assert(std::is_arithmetic<NumericType>::value, "Argument must be numeric.");
|
||||
static const int value =
|
||||
std::numeric_limits<NumericType>::is_iec559
|
||||
? std::numeric_limits<NumericType>::max_exponent
|
||||
: (sizeof(NumericType) * CHAR_BIT + 1 - std::numeric_limits<NumericType>::is_signed);
|
||||
};
|
||||
|
||||
enum IntegerRepresentation
|
||||
{
|
||||
INTEGER_REPRESENTATION_UNSIGNED,
|
||||
INTEGER_REPRESENTATION_SIGNED
|
||||
};
|
||||
|
||||
// A range for a given nunmeric Src type is contained for a given numeric Dst
|
||||
// type if both numeric_limits<Src>::max() <= numeric_limits<Dst>::max() and
|
||||
// numeric_limits<Src>::min() >= numeric_limits<Dst>::min() are true.
|
||||
// We implement this as template specializations rather than simple static
|
||||
// comparisons to ensure type correctness in our comparisons.
|
||||
enum NumericRangeRepresentation
|
||||
{
|
||||
NUMERIC_RANGE_NOT_CONTAINED,
|
||||
NUMERIC_RANGE_CONTAINED
|
||||
};
|
||||
|
||||
// Helper templates to statically determine if our destination type can contain
|
||||
// maximum and minimum values represented by the source type.
|
||||
|
||||
template <typename Dst,
|
||||
typename Src,
|
||||
IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed
|
||||
? INTEGER_REPRESENTATION_SIGNED
|
||||
: INTEGER_REPRESENTATION_UNSIGNED,
|
||||
IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed
|
||||
? INTEGER_REPRESENTATION_SIGNED
|
||||
: INTEGER_REPRESENTATION_UNSIGNED>
|
||||
struct StaticDstRangeRelationToSrcRange;
|
||||
|
||||
// Same sign: Dst is guaranteed to contain Src only if its range is equal or
|
||||
// larger.
|
||||
template <typename Dst, typename Src, IntegerRepresentation Sign>
|
||||
struct StaticDstRangeRelationToSrcRange<Dst, Src, Sign, Sign>
|
||||
{
|
||||
static const NumericRangeRepresentation value =
|
||||
MaxExponent<Dst>::value >= MaxExponent<Src>::value ? NUMERIC_RANGE_CONTAINED
|
||||
: NUMERIC_RANGE_NOT_CONTAINED;
|
||||
};
|
||||
|
||||
// Unsigned to signed: Dst is guaranteed to contain source only if its range is
|
||||
// larger.
|
||||
template <typename Dst, typename Src>
|
||||
struct StaticDstRangeRelationToSrcRange<Dst,
|
||||
Src,
|
||||
INTEGER_REPRESENTATION_SIGNED,
|
||||
INTEGER_REPRESENTATION_UNSIGNED>
|
||||
{
|
||||
static const NumericRangeRepresentation value =
|
||||
MaxExponent<Dst>::value > MaxExponent<Src>::value ? NUMERIC_RANGE_CONTAINED
|
||||
: NUMERIC_RANGE_NOT_CONTAINED;
|
||||
};
|
||||
|
||||
// Signed to unsigned: Dst cannot be statically determined to contain Src.
|
||||
template <typename Dst, typename Src>
|
||||
struct StaticDstRangeRelationToSrcRange<Dst,
|
||||
Src,
|
||||
INTEGER_REPRESENTATION_UNSIGNED,
|
||||
INTEGER_REPRESENTATION_SIGNED>
|
||||
{
|
||||
static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED;
|
||||
};
|
||||
|
||||
enum RangeConstraint : unsigned char
|
||||
{
|
||||
RANGE_VALID = 0x0, // Value can be represented by the destination type.
|
||||
RANGE_UNDERFLOW = 0x1, // Value would overflow.
|
||||
RANGE_OVERFLOW = 0x2, // Value would underflow.
|
||||
RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN).
|
||||
};
|
||||
|
||||
// Helper function for coercing an int back to a RangeContraint.
|
||||
constexpr RangeConstraint GetRangeConstraint(int integer_range_constraint)
|
||||
{
|
||||
// TODO(jschuh): Once we get full C++14 support we want this
|
||||
// assert(integer_range_constraint >= RANGE_VALID &&
|
||||
// integer_range_constraint <= RANGE_INVALID)
|
||||
return static_cast<RangeConstraint>(integer_range_constraint);
|
||||
}
|
||||
|
||||
// This function creates a RangeConstraint from an upper and lower bound
|
||||
// check by taking advantage of the fact that only NaN can be out of range in
|
||||
// both directions at once.
|
||||
constexpr inline RangeConstraint GetRangeConstraint(bool is_in_upper_bound, bool is_in_lower_bound)
|
||||
{
|
||||
return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) |
|
||||
(is_in_lower_bound ? 0 : RANGE_UNDERFLOW));
|
||||
}
|
||||
|
||||
// The following helper template addresses a corner case in range checks for
|
||||
// conversion from a floating-point type to an integral type of smaller range
|
||||
// but larger precision (e.g. float -> unsigned). The problem is as follows:
|
||||
// 1. Integral maximum is always one less than a power of two, so it must be
|
||||
// truncated to fit the mantissa of the floating point. The direction of
|
||||
// rounding is implementation defined, but by default it's always IEEE
|
||||
// floats, which round to nearest and thus result in a value of larger
|
||||
// magnitude than the integral value.
|
||||
// Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX
|
||||
// // is 4294967295u.
|
||||
// 2. If the floating point value is equal to the promoted integral maximum
|
||||
// value, a range check will erroneously pass.
|
||||
// Example: (4294967296f <= 4294967295u) // This is true due to a precision
|
||||
// // loss in rounding up to float.
|
||||
// 3. When the floating point value is then converted to an integral, the
|
||||
// resulting value is out of range for the target integral type and
|
||||
// thus is implementation defined.
|
||||
// Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0.
|
||||
// To fix this bug we manually truncate the maximum value when the destination
|
||||
// type is an integral of larger precision than the source floating-point type,
|
||||
// such that the resulting maximum is represented exactly as a floating point.
|
||||
template <typename Dst, typename Src>
|
||||
struct NarrowingRange
|
||||
{
|
||||
typedef typename std::numeric_limits<Src> SrcLimits;
|
||||
typedef typename std::numeric_limits<Dst> DstLimits;
|
||||
// The following logic avoids warnings where the max function is
|
||||
// instantiated with invalid values for a bit shift (even though
|
||||
// such a function can never be called).
|
||||
static const int shift = (MaxExponent<Src>::value > MaxExponent<Dst>::value &&
|
||||
SrcLimits::digits < DstLimits::digits &&
|
||||
SrcLimits::is_iec559 &&
|
||||
DstLimits::is_integer)
|
||||
? (DstLimits::digits - SrcLimits::digits)
|
||||
: 0;
|
||||
|
||||
static constexpr Dst max()
|
||||
{
|
||||
// We use UINTMAX_C below to avoid compiler warnings about shifting floating
|
||||
// points. Since it's a compile time calculation, it shouldn't have any
|
||||
// performance impact.
|
||||
return DstLimits::max() - static_cast<Dst>((UINTMAX_C(1) << shift) - 1);
|
||||
}
|
||||
|
||||
static constexpr Dst min()
|
||||
{
|
||||
return std::numeric_limits<Dst>::is_iec559 ? -DstLimits::max() : DstLimits::min();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Dst,
|
||||
typename Src,
|
||||
IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed
|
||||
? INTEGER_REPRESENTATION_SIGNED
|
||||
: INTEGER_REPRESENTATION_UNSIGNED,
|
||||
IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed
|
||||
? INTEGER_REPRESENTATION_SIGNED
|
||||
: INTEGER_REPRESENTATION_UNSIGNED,
|
||||
NumericRangeRepresentation DstRange = StaticDstRangeRelationToSrcRange<Dst, Src>::value>
|
||||
struct DstRangeRelationToSrcRangeImpl;
|
||||
|
||||
// The following templates are for ranges that must be verified at runtime. We
|
||||
// split it into checks based on signedness to avoid confusing casts and
|
||||
// compiler warnings on signed an unsigned comparisons.
|
||||
|
||||
// Dst range is statically determined to contain Src: Nothing to check.
|
||||
template <typename Dst, typename Src, IntegerRepresentation DstSign, IntegerRepresentation SrcSign>
|
||||
struct DstRangeRelationToSrcRangeImpl<Dst, Src, DstSign, SrcSign, NUMERIC_RANGE_CONTAINED>
|
||||
{
|
||||
static constexpr RangeConstraint Check(Src value) { return RANGE_VALID; }
|
||||
};
|
||||
|
||||
// Signed to signed narrowing: Both the upper and lower boundaries may be
|
||||
// exceeded.
|
||||
template <typename Dst, typename Src>
|
||||
struct DstRangeRelationToSrcRangeImpl<Dst,
|
||||
Src,
|
||||
INTEGER_REPRESENTATION_SIGNED,
|
||||
INTEGER_REPRESENTATION_SIGNED,
|
||||
NUMERIC_RANGE_NOT_CONTAINED>
|
||||
{
|
||||
static constexpr RangeConstraint Check(Src value)
|
||||
{
|
||||
return GetRangeConstraint((value <= NarrowingRange<Dst, Src>::max()),
|
||||
(value >= NarrowingRange<Dst, Src>::min()));
|
||||
}
|
||||
};
|
||||
|
||||
// Unsigned to unsigned narrowing: Only the upper boundary can be exceeded.
|
||||
template <typename Dst, typename Src>
|
||||
struct DstRangeRelationToSrcRangeImpl<Dst,
|
||||
Src,
|
||||
INTEGER_REPRESENTATION_UNSIGNED,
|
||||
INTEGER_REPRESENTATION_UNSIGNED,
|
||||
NUMERIC_RANGE_NOT_CONTAINED>
|
||||
{
|
||||
static constexpr RangeConstraint Check(Src value)
|
||||
{
|
||||
return GetRangeConstraint(value <= NarrowingRange<Dst, Src>::max(), true);
|
||||
}
|
||||
};
|
||||
|
||||
// Unsigned to signed: The upper boundary may be exceeded.
|
||||
template <typename Dst, typename Src>
|
||||
struct DstRangeRelationToSrcRangeImpl<Dst,
|
||||
Src,
|
||||
INTEGER_REPRESENTATION_SIGNED,
|
||||
INTEGER_REPRESENTATION_UNSIGNED,
|
||||
NUMERIC_RANGE_NOT_CONTAINED>
|
||||
{
|
||||
static constexpr RangeConstraint Check(Src value)
|
||||
{
|
||||
return sizeof(Dst) > sizeof(Src)
|
||||
? RANGE_VALID
|
||||
: GetRangeConstraint(value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
|
||||
true);
|
||||
}
|
||||
};
|
||||
|
||||
// Signed to unsigned: The upper boundary may be exceeded for a narrower Dst,
|
||||
// and any negative value exceeds the lower boundary.
|
||||
template <typename Dst, typename Src>
|
||||
struct DstRangeRelationToSrcRangeImpl<Dst,
|
||||
Src,
|
||||
INTEGER_REPRESENTATION_UNSIGNED,
|
||||
INTEGER_REPRESENTATION_SIGNED,
|
||||
NUMERIC_RANGE_NOT_CONTAINED>
|
||||
{
|
||||
static constexpr RangeConstraint Check(Src value)
|
||||
{
|
||||
return (MaxExponent<Dst>::value >= MaxExponent<Src>::value)
|
||||
? GetRangeConstraint(true, value >= static_cast<Src>(0))
|
||||
: GetRangeConstraint(value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
|
||||
value >= static_cast<Src>(0));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Dst, typename Src>
|
||||
constexpr RangeConstraint DstRangeRelationToSrcRange(Src value)
|
||||
{
|
||||
static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
|
||||
static_assert(std::numeric_limits<Dst>::is_specialized, "Result must be numeric.");
|
||||
return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
|
|
@ -1,329 +0,0 @@
|
|||
// Copyright 2014 The Chromium 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 ANGLEBASE_NUMERICS_SAFE_MATH_H_
|
||||
#define ANGLEBASE_NUMERICS_SAFE_MATH_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "anglebase/logging.h"
|
||||
#include "anglebase/numerics/safe_math_impl.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
// CheckedNumeric implements all the logic and operators for detecting integer
|
||||
// boundary conditions such as overflow, underflow, and invalid conversions.
|
||||
// The CheckedNumeric type implicitly converts from floating point and integer
|
||||
// data types, and contains overloads for basic arithmetic operations (i.e.: +,
|
||||
// -, *, /, %).
|
||||
//
|
||||
// The following methods convert from CheckedNumeric to standard numeric values:
|
||||
// IsValid() - Returns true if the underlying numeric value is valid (i.e. has
|
||||
// has not wrapped and is not the result of an invalid conversion).
|
||||
// ValueOrDie() - Returns the underlying value. If the state is not valid this
|
||||
// call will crash on a CHECK.
|
||||
// ValueOrDefault() - Returns the current value, or the supplied default if the
|
||||
// state is not valid.
|
||||
// ValueFloating() - Returns the underlying floating point value (valid only
|
||||
// only for floating point CheckedNumeric types).
|
||||
//
|
||||
// Bitwise operations are explicitly not supported, because correct
|
||||
// handling of some cases (e.g. sign manipulation) is ambiguous. Comparison
|
||||
// operations are explicitly not supported because they could result in a crash
|
||||
// on a CHECK condition. You should use patterns like the following for these
|
||||
// operations:
|
||||
// Bitwise operation:
|
||||
// CheckedNumeric<int> checked_int = untrusted_input_value;
|
||||
// int x = checked_int.ValueOrDefault(0) | kFlagValues;
|
||||
// Comparison:
|
||||
// CheckedNumeric<size_t> checked_size = untrusted_input_value;
|
||||
// checked_size += HEADER LENGTH;
|
||||
// if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size)
|
||||
// Do stuff...
|
||||
template <typename T>
|
||||
class CheckedNumeric
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "CheckedNumeric<T>: T must be a numeric type.");
|
||||
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
CheckedNumeric() {}
|
||||
|
||||
// Copy constructor.
|
||||
template <typename Src>
|
||||
CheckedNumeric(const CheckedNumeric<Src> &rhs) : state_(rhs.ValueUnsafe(), rhs.validity())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
CheckedNumeric(Src value, RangeConstraint validity) : state_(value, validity)
|
||||
{
|
||||
}
|
||||
|
||||
// This is not an explicit constructor because we implicitly upgrade regular
|
||||
// numerics to CheckedNumerics to make them easier to use.
|
||||
template <typename Src>
|
||||
CheckedNumeric(Src value) // NOLINT(runtime/explicit)
|
||||
: state_(value)
|
||||
{
|
||||
static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
|
||||
}
|
||||
|
||||
// This is not an explicit constructor because we want a seamless conversion
|
||||
// from StrictNumeric types.
|
||||
template <typename Src>
|
||||
CheckedNumeric(StrictNumeric<Src> value) // NOLINT(runtime/explicit)
|
||||
: state_(static_cast<Src>(value))
|
||||
{
|
||||
}
|
||||
|
||||
// IsValid() is the public API to test if a CheckedNumeric is currently valid.
|
||||
bool IsValid() const { return validity() == RANGE_VALID; }
|
||||
|
||||
// ValueOrDie() The primary accessor for the underlying value. If the current
|
||||
// state is not valid it will CHECK and crash.
|
||||
T ValueOrDie() const
|
||||
{
|
||||
CHECK(IsValid());
|
||||
return state_.value();
|
||||
}
|
||||
|
||||
// ValueOrDefault(T default_value) A convenience method that returns the
|
||||
// current value if the state is valid, and the supplied default_value for
|
||||
// any other state.
|
||||
T ValueOrDefault(T default_value) const { return IsValid() ? state_.value() : default_value; }
|
||||
|
||||
// ValueFloating() - Since floating point values include their validity state,
|
||||
// we provide an easy method for extracting them directly, without a risk of
|
||||
// crashing on a CHECK.
|
||||
T ValueFloating() const
|
||||
{
|
||||
static_assert(std::numeric_limits<T>::is_iec559, "Argument must be float.");
|
||||
return CheckedNumeric<T>::cast(*this).ValueUnsafe();
|
||||
}
|
||||
|
||||
// validity() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now for
|
||||
// tests and to avoid a big matrix of friend operator overloads. But the
|
||||
// values it returns are likely to change in the future.
|
||||
// Returns: current validity state (i.e. valid, overflow, underflow, nan).
|
||||
// TODO(jschuh): crbug.com/332611 Figure out and implement semantics for
|
||||
// saturation/wrapping so we can expose this state consistently and implement
|
||||
// saturated arithmetic.
|
||||
RangeConstraint validity() const { return state_.validity(); }
|
||||
|
||||
// ValueUnsafe() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now
|
||||
// for tests and to avoid a big matrix of friend operator overloads. But the
|
||||
// values it returns are likely to change in the future.
|
||||
// Returns: the raw numeric value, regardless of the current state.
|
||||
// TODO(jschuh): crbug.com/332611 Figure out and implement semantics for
|
||||
// saturation/wrapping so we can expose this state consistently and implement
|
||||
// saturated arithmetic.
|
||||
T ValueUnsafe() const { return state_.value(); }
|
||||
|
||||
// Prototypes for the supported arithmetic operator overloads.
|
||||
template <typename Src>
|
||||
CheckedNumeric &operator+=(Src rhs);
|
||||
template <typename Src>
|
||||
CheckedNumeric &operator-=(Src rhs);
|
||||
template <typename Src>
|
||||
CheckedNumeric &operator*=(Src rhs);
|
||||
template <typename Src>
|
||||
CheckedNumeric &operator/=(Src rhs);
|
||||
template <typename Src>
|
||||
CheckedNumeric &operator%=(Src rhs);
|
||||
|
||||
CheckedNumeric operator-() const
|
||||
{
|
||||
RangeConstraint validity;
|
||||
T value = CheckedNeg(state_.value(), &validity);
|
||||
// Negation is always valid for floating point.
|
||||
if (std::numeric_limits<T>::is_iec559)
|
||||
return CheckedNumeric<T>(value);
|
||||
|
||||
validity = GetRangeConstraint(state_.validity() | validity);
|
||||
return CheckedNumeric<T>(value, validity);
|
||||
}
|
||||
|
||||
CheckedNumeric Abs() const
|
||||
{
|
||||
RangeConstraint validity;
|
||||
T value = CheckedAbs(state_.value(), &validity);
|
||||
// Absolute value is always valid for floating point.
|
||||
if (std::numeric_limits<T>::is_iec559)
|
||||
return CheckedNumeric<T>(value);
|
||||
|
||||
validity = GetRangeConstraint(state_.validity() | validity);
|
||||
return CheckedNumeric<T>(value, validity);
|
||||
}
|
||||
|
||||
// This function is available only for integral types. It returns an unsigned
|
||||
// integer of the same width as the source type, containing the absolute value
|
||||
// of the source, and properly handling signed min.
|
||||
CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const
|
||||
{
|
||||
return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>(
|
||||
CheckedUnsignedAbs(state_.value()), state_.validity());
|
||||
}
|
||||
|
||||
CheckedNumeric &operator++()
|
||||
{
|
||||
*this += 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CheckedNumeric operator++(int)
|
||||
{
|
||||
CheckedNumeric value = *this;
|
||||
*this += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
CheckedNumeric &operator--()
|
||||
{
|
||||
*this -= 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CheckedNumeric operator--(int)
|
||||
{
|
||||
CheckedNumeric value = *this;
|
||||
*this -= 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
// These static methods behave like a convenience cast operator targeting
|
||||
// the desired CheckedNumeric type. As an optimization, a reference is
|
||||
// returned when Src is the same type as T.
|
||||
template <typename Src>
|
||||
static CheckedNumeric<T> cast(
|
||||
Src u,
|
||||
typename std::enable_if<std::numeric_limits<Src>::is_specialized, int>::type = 0)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
static CheckedNumeric<T> cast(
|
||||
const CheckedNumeric<Src> &u,
|
||||
typename std::enable_if<!std::is_same<Src, T>::value, int>::type = 0)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
|
||||
static const CheckedNumeric<T> &cast(const CheckedNumeric<T> &u) { return u; }
|
||||
|
||||
private:
|
||||
template <typename NumericType>
|
||||
struct UnderlyingType
|
||||
{
|
||||
using type = NumericType;
|
||||
};
|
||||
|
||||
template <typename NumericType>
|
||||
struct UnderlyingType<CheckedNumeric<NumericType>>
|
||||
{
|
||||
using type = NumericType;
|
||||
};
|
||||
|
||||
CheckedNumericState<T> state_;
|
||||
};
|
||||
|
||||
// This is the boilerplate for the standard arithmetic operator overloads. A
|
||||
// macro isn't the prettiest solution, but it beats rewriting these five times.
|
||||
// Some details worth noting are:
|
||||
// * We apply the standard arithmetic promotions.
|
||||
// * We skip range checks for floating points.
|
||||
// * We skip range checks for destination integers with sufficient range.
|
||||
// TODO(jschuh): extract these out into templates.
|
||||
#define ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP) \
|
||||
/* Binary arithmetic operator for CheckedNumerics of the same type. */ \
|
||||
template <typename T> \
|
||||
CheckedNumeric<typename ArithmeticPromotion<T>::type> operator OP( \
|
||||
const CheckedNumeric<T> &lhs, const CheckedNumeric<T> &rhs) \
|
||||
{ \
|
||||
typedef typename ArithmeticPromotion<T>::type Promotion; \
|
||||
/* Floating point always takes the fast path */ \
|
||||
if (std::numeric_limits<T>::is_iec559) \
|
||||
return CheckedNumeric<T>(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \
|
||||
if (IsIntegerArithmeticSafe<Promotion, T, T>::value) \
|
||||
return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \
|
||||
GetRangeConstraint(rhs.validity() | lhs.validity())); \
|
||||
RangeConstraint validity = RANGE_VALID; \
|
||||
T result = \
|
||||
static_cast<T>(Checked##NAME(static_cast<Promotion>(lhs.ValueUnsafe()), \
|
||||
static_cast<Promotion>(rhs.ValueUnsafe()), &validity)); \
|
||||
return CheckedNumeric<Promotion>( \
|
||||
result, GetRangeConstraint(validity | lhs.validity() | rhs.validity())); \
|
||||
} \
|
||||
/* Assignment arithmetic operator implementation from CheckedNumeric. */ \
|
||||
template <typename T> \
|
||||
template <typename Src> \
|
||||
CheckedNumeric<T> &CheckedNumeric<T>::operator COMPOUND_OP(Src rhs) \
|
||||
{ \
|
||||
*this = CheckedNumeric<T>::cast(*this) \
|
||||
OP CheckedNumeric<typename UnderlyingType<Src>::type>::cast(rhs); \
|
||||
return *this; \
|
||||
} \
|
||||
/* Binary arithmetic operator for CheckedNumeric of different type. */ \
|
||||
template <typename T, typename Src> \
|
||||
CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \
|
||||
const CheckedNumeric<Src> &lhs, const CheckedNumeric<T> &rhs) \
|
||||
{ \
|
||||
typedef typename ArithmeticPromotion<T, Src>::type Promotion; \
|
||||
if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \
|
||||
return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \
|
||||
GetRangeConstraint(rhs.validity() | lhs.validity())); \
|
||||
return CheckedNumeric<Promotion>::cast(lhs) OP CheckedNumeric<Promotion>::cast(rhs); \
|
||||
} \
|
||||
/* Binary arithmetic operator for left CheckedNumeric and right numeric. */ \
|
||||
template <typename T, typename Src, \
|
||||
typename std::enable_if<std::is_arithmetic<Src>::value>::type * = nullptr> \
|
||||
CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \
|
||||
const CheckedNumeric<T> &lhs, Src rhs) \
|
||||
{ \
|
||||
typedef typename ArithmeticPromotion<T, Src>::type Promotion; \
|
||||
if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \
|
||||
return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs, lhs.validity()); \
|
||||
return CheckedNumeric<Promotion>::cast(lhs) OP CheckedNumeric<Promotion>::cast(rhs); \
|
||||
} \
|
||||
/* Binary arithmetic operator for left numeric and right CheckedNumeric. */ \
|
||||
template <typename T, typename Src, \
|
||||
typename std::enable_if<std::is_arithmetic<Src>::value>::type * = nullptr> \
|
||||
CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \
|
||||
Src lhs, const CheckedNumeric<T> &rhs) \
|
||||
{ \
|
||||
typedef typename ArithmeticPromotion<T, Src>::type Promotion; \
|
||||
if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \
|
||||
return CheckedNumeric<Promotion>(lhs OP rhs.ValueUnsafe(), rhs.validity()); \
|
||||
return CheckedNumeric<Promotion>::cast(lhs) OP CheckedNumeric<Promotion>::cast(rhs); \
|
||||
}
|
||||
|
||||
ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, +=)
|
||||
ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -=)
|
||||
ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *=)
|
||||
ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /=)
|
||||
ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %=)
|
||||
|
||||
#undef ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS
|
||||
|
||||
} // namespace internal
|
||||
|
||||
using internal::CheckedNumeric;
|
||||
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLEBASE_NUMERICS_SAFE_MATH_H_
|
|
@ -1,575 +0,0 @@
|
|||
// Copyright 2014 The Chromium 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 ANGLEBASE_NUMERICS_SAFE_MATH_IMPL_H_
|
||||
#define ANGLEBASE_NUMERICS_SAFE_MATH_IMPL_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "anglebase/numerics/safe_conversions.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
// Everything from here up to the floating point operations is portable C++,
|
||||
// but it may not be fast. This code could be split based on
|
||||
// platform/architecture and replaced with potentially faster implementations.
|
||||
|
||||
// Integer promotion templates used by the portable checked integer arithmetic.
|
||||
template <size_t Size, bool IsSigned>
|
||||
struct IntegerForSizeAndSign;
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<1, true>
|
||||
{
|
||||
typedef int8_t type;
|
||||
};
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<1, false>
|
||||
{
|
||||
typedef uint8_t type;
|
||||
};
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<2, true>
|
||||
{
|
||||
typedef int16_t type;
|
||||
};
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<2, false>
|
||||
{
|
||||
typedef uint16_t type;
|
||||
};
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<4, true>
|
||||
{
|
||||
typedef int32_t type;
|
||||
};
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<4, false>
|
||||
{
|
||||
typedef uint32_t type;
|
||||
};
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<8, true>
|
||||
{
|
||||
typedef int64_t type;
|
||||
};
|
||||
template <>
|
||||
struct IntegerForSizeAndSign<8, false>
|
||||
{
|
||||
typedef uint64_t type;
|
||||
};
|
||||
|
||||
// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to
|
||||
// support 128-bit math, then the ArithmeticPromotion template below will need
|
||||
// to be updated (or more likely replaced with a decltype expression).
|
||||
|
||||
template <typename Integer>
|
||||
struct UnsignedIntegerForSize
|
||||
{
|
||||
typedef
|
||||
typename std::enable_if<std::numeric_limits<Integer>::is_integer,
|
||||
typename IntegerForSizeAndSign<sizeof(Integer), false>::type>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Integer>
|
||||
struct SignedIntegerForSize
|
||||
{
|
||||
typedef
|
||||
typename std::enable_if<std::numeric_limits<Integer>::is_integer,
|
||||
typename IntegerForSizeAndSign<sizeof(Integer), true>::type>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Integer>
|
||||
struct TwiceWiderInteger
|
||||
{
|
||||
typedef typename std::enable_if<
|
||||
std::numeric_limits<Integer>::is_integer,
|
||||
typename IntegerForSizeAndSign<sizeof(Integer) * 2,
|
||||
std::numeric_limits<Integer>::is_signed>::type>::type type;
|
||||
};
|
||||
|
||||
template <typename Integer>
|
||||
struct PositionOfSignBit
|
||||
{
|
||||
static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, size_t>::type
|
||||
value = CHAR_BIT * sizeof(Integer) - 1;
|
||||
};
|
||||
|
||||
// This is used for UnsignedAbs, where we need to support floating-point
|
||||
// template instantiations even though we don't actually support the operations.
|
||||
// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs,
|
||||
// so the float versions will not compile.
|
||||
template <typename Numeric,
|
||||
bool IsInteger = std::numeric_limits<Numeric>::is_integer,
|
||||
bool IsFloat = std::numeric_limits<Numeric>::is_iec559>
|
||||
struct UnsignedOrFloatForSize;
|
||||
|
||||
template <typename Numeric>
|
||||
struct UnsignedOrFloatForSize<Numeric, true, false>
|
||||
{
|
||||
typedef typename UnsignedIntegerForSize<Numeric>::type type;
|
||||
};
|
||||
|
||||
template <typename Numeric>
|
||||
struct UnsignedOrFloatForSize<Numeric, false, true>
|
||||
{
|
||||
typedef Numeric type;
|
||||
};
|
||||
|
||||
// Helper templates for integer manipulations.
|
||||
|
||||
template <typename T>
|
||||
constexpr bool HasSignBit(T x)
|
||||
{
|
||||
// Cast to unsigned since right shift on signed is undefined.
|
||||
return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >>
|
||||
PositionOfSignBit<T>::value);
|
||||
}
|
||||
|
||||
// This wrapper undoes the standard integer promotions.
|
||||
template <typename T>
|
||||
constexpr T BinaryComplement(T x)
|
||||
{
|
||||
return static_cast<T>(~x);
|
||||
}
|
||||
|
||||
// Here are the actual portable checked integer math implementations.
|
||||
// TODO(jschuh): Break this code out from the enable_if pattern and find a clean
|
||||
// way to coalesce things into the CheckedNumericState specializations below.
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type
|
||||
CheckedAdd(T x, T y, RangeConstraint *validity)
|
||||
{
|
||||
// Since the value of x+y is undefined if we have a signed type, we compute
|
||||
// it using the unsigned type of the same size.
|
||||
typedef typename UnsignedIntegerForSize<T>::type UnsignedDst;
|
||||
UnsignedDst ux = static_cast<UnsignedDst>(x);
|
||||
UnsignedDst uy = static_cast<UnsignedDst>(y);
|
||||
UnsignedDst uresult = static_cast<UnsignedDst>(ux + uy);
|
||||
// Addition is valid if the sign of (x + y) is equal to either that of x or
|
||||
// that of y.
|
||||
if (std::numeric_limits<T>::is_signed)
|
||||
{
|
||||
if (HasSignBit(BinaryComplement(static_cast<UnsignedDst>((uresult ^ ux) & (uresult ^ uy)))))
|
||||
{
|
||||
*validity = RANGE_VALID;
|
||||
}
|
||||
else
|
||||
{ // Direction of wrap is inverse of result sign.
|
||||
*validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Unsigned is either valid or overflow.
|
||||
*validity = BinaryComplement(x) >= y ? RANGE_VALID : RANGE_OVERFLOW;
|
||||
}
|
||||
return static_cast<T>(uresult);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type
|
||||
CheckedSub(T x, T y, RangeConstraint *validity)
|
||||
{
|
||||
// Since the value of x+y is undefined if we have a signed type, we compute
|
||||
// it using the unsigned type of the same size.
|
||||
typedef typename UnsignedIntegerForSize<T>::type UnsignedDst;
|
||||
UnsignedDst ux = static_cast<UnsignedDst>(x);
|
||||
UnsignedDst uy = static_cast<UnsignedDst>(y);
|
||||
UnsignedDst uresult = static_cast<UnsignedDst>(ux - uy);
|
||||
// Subtraction is valid if either x and y have same sign, or (x-y) and x have
|
||||
// the same sign.
|
||||
if (std::numeric_limits<T>::is_signed)
|
||||
{
|
||||
if (HasSignBit(BinaryComplement(static_cast<UnsignedDst>((uresult ^ ux) & (ux ^ uy)))))
|
||||
{
|
||||
*validity = RANGE_VALID;
|
||||
}
|
||||
else
|
||||
{ // Direction of wrap is inverse of result sign.
|
||||
*validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Unsigned is either valid or underflow.
|
||||
*validity = x >= y ? RANGE_VALID : RANGE_UNDERFLOW;
|
||||
}
|
||||
return static_cast<T>(uresult);
|
||||
}
|
||||
|
||||
// Integer multiplication is a bit complicated. In the fast case we just
|
||||
// we just promote to a twice wider type, and range check the result. In the
|
||||
// slow case we need to manually check that the result won't be truncated by
|
||||
// checking with division against the appropriate bound.
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && sizeof(T) * 2 <= sizeof(uintmax_t),
|
||||
T>::type
|
||||
CheckedMul(T x, T y, RangeConstraint *validity)
|
||||
{
|
||||
typedef typename TwiceWiderInteger<T>::type IntermediateType;
|
||||
IntermediateType tmp = static_cast<IntermediateType>(x) * static_cast<IntermediateType>(y);
|
||||
*validity = DstRangeRelationToSrcRange<T>(tmp);
|
||||
return static_cast<T>(tmp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed &&
|
||||
(sizeof(T) * 2 > sizeof(uintmax_t)),
|
||||
T>::type
|
||||
CheckedMul(T x, T y, RangeConstraint *validity)
|
||||
{
|
||||
// If either side is zero then the result will be zero.
|
||||
if (!x || !y)
|
||||
{
|
||||
*validity = RANGE_VALID;
|
||||
return static_cast<T>(0);
|
||||
}
|
||||
else if (x > 0)
|
||||
{
|
||||
if (y > 0)
|
||||
*validity = x <= std::numeric_limits<T>::max() / y ? RANGE_VALID : RANGE_OVERFLOW;
|
||||
else
|
||||
*validity = y >= std::numeric_limits<T>::min() / x ? RANGE_VALID : RANGE_UNDERFLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y > 0)
|
||||
*validity = x >= std::numeric_limits<T>::min() / y ? RANGE_VALID : RANGE_UNDERFLOW;
|
||||
else
|
||||
*validity = y >= std::numeric_limits<T>::max() / x ? RANGE_VALID : RANGE_OVERFLOW;
|
||||
}
|
||||
|
||||
return static_cast<T>(x * y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed &&
|
||||
(sizeof(T) * 2 > sizeof(uintmax_t)),
|
||||
T>::type
|
||||
CheckedMul(T x, T y, RangeConstraint *validity)
|
||||
{
|
||||
*validity = (y == 0 || x <= std::numeric_limits<T>::max() / y) ? RANGE_VALID : RANGE_OVERFLOW;
|
||||
return static_cast<T>(x * y);
|
||||
}
|
||||
|
||||
// Division just requires a check for an invalid negation on signed min/-1.
|
||||
template <typename T>
|
||||
T CheckedDiv(T x,
|
||||
T y,
|
||||
RangeConstraint *validity,
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer, int>::type = 0)
|
||||
{
|
||||
if (std::numeric_limits<T>::is_signed && x == std::numeric_limits<T>::min() &&
|
||||
y == static_cast<T>(-1))
|
||||
{
|
||||
*validity = RANGE_OVERFLOW;
|
||||
return std::numeric_limits<T>::min();
|
||||
}
|
||||
|
||||
*validity = RANGE_VALID;
|
||||
return static_cast<T>(x / y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
|
||||
T>::type
|
||||
CheckedMod(T x, T y, RangeConstraint *validity)
|
||||
{
|
||||
*validity = y > 0 ? RANGE_VALID : RANGE_INVALID;
|
||||
return static_cast<T>(x % y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
|
||||
T>::type
|
||||
CheckedMod(T x, T y, RangeConstraint *validity)
|
||||
{
|
||||
*validity = RANGE_VALID;
|
||||
return static_cast<T>(x % y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
|
||||
T>::type
|
||||
CheckedNeg(T value, RangeConstraint *validity)
|
||||
{
|
||||
*validity = value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
|
||||
// The negation of signed min is min, so catch that one.
|
||||
return static_cast<T>(-value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
|
||||
T>::type
|
||||
CheckedNeg(T value, RangeConstraint *validity)
|
||||
{
|
||||
// The only legal unsigned negation is zero.
|
||||
*validity = value ? RANGE_UNDERFLOW : RANGE_VALID;
|
||||
return static_cast<T>(-static_cast<typename SignedIntegerForSize<T>::type>(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
|
||||
T>::type
|
||||
CheckedAbs(T value, RangeConstraint *validity)
|
||||
{
|
||||
*validity = value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
|
||||
return static_cast<T>(std::abs(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
|
||||
T>::type
|
||||
CheckedAbs(T value, RangeConstraint *validity)
|
||||
{
|
||||
// T is unsigned, so |value| must already be positive.
|
||||
*validity = RANGE_VALID;
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
|
||||
typename UnsignedIntegerForSize<T>::type>::type
|
||||
CheckedUnsignedAbs(T value)
|
||||
{
|
||||
typedef typename UnsignedIntegerForSize<T>::type UnsignedT;
|
||||
return value == std::numeric_limits<T>::min()
|
||||
? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1
|
||||
: static_cast<UnsignedT>(std::abs(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
|
||||
T>::type
|
||||
CheckedUnsignedAbs(T value)
|
||||
{
|
||||
// T is unsigned, so |value| must already be positive.
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
// These are the floating point stubs that the compiler needs to see. Only the
|
||||
// negation operation is ever called.
|
||||
#define ANGLEBASE_FLOAT_ARITHMETIC_STUBS(NAME) \
|
||||
template <typename T> \
|
||||
typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type Checked##NAME( \
|
||||
T, T, RangeConstraint *) \
|
||||
{ \
|
||||
NOTREACHED(); \
|
||||
return static_cast<T>(0); \
|
||||
}
|
||||
|
||||
ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Add)
|
||||
ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Sub)
|
||||
ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Mul)
|
||||
ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Div)
|
||||
ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Mod)
|
||||
|
||||
#undef ANGLEBASE_FLOAT_ARITHMETIC_STUBS
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedNeg(T value,
|
||||
RangeConstraint *)
|
||||
{
|
||||
return static_cast<T>(-value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedAbs(T value,
|
||||
RangeConstraint *)
|
||||
{
|
||||
return static_cast<T>(std::abs(value));
|
||||
}
|
||||
|
||||
// Floats carry around their validity state with them, but integers do not. So,
|
||||
// we wrap the underlying value in a specialization in order to hide that detail
|
||||
// and expose an interface via accessors.
|
||||
enum NumericRepresentation
|
||||
{
|
||||
NUMERIC_INTEGER,
|
||||
NUMERIC_FLOATING,
|
||||
NUMERIC_UNKNOWN
|
||||
};
|
||||
|
||||
template <typename NumericType>
|
||||
struct GetNumericRepresentation
|
||||
{
|
||||
static const NumericRepresentation value =
|
||||
std::numeric_limits<NumericType>::is_integer
|
||||
? NUMERIC_INTEGER
|
||||
: (std::numeric_limits<NumericType>::is_iec559 ? NUMERIC_FLOATING : NUMERIC_UNKNOWN);
|
||||
};
|
||||
|
||||
template <typename T, NumericRepresentation type = GetNumericRepresentation<T>::value>
|
||||
class CheckedNumericState
|
||||
{
|
||||
};
|
||||
|
||||
// Integrals require quite a bit of additional housekeeping to manage state.
|
||||
template <typename T>
|
||||
class CheckedNumericState<T, NUMERIC_INTEGER>
|
||||
{
|
||||
private:
|
||||
T value_;
|
||||
RangeConstraint validity_ : CHAR_BIT; // Actually requires only two bits.
|
||||
|
||||
public:
|
||||
template <typename Src, NumericRepresentation type>
|
||||
friend class CheckedNumericState;
|
||||
|
||||
CheckedNumericState() : value_(0), validity_(RANGE_VALID) {}
|
||||
|
||||
template <typename Src>
|
||||
CheckedNumericState(Src value, RangeConstraint validity)
|
||||
: value_(static_cast<T>(value)),
|
||||
validity_(GetRangeConstraint(validity | DstRangeRelationToSrcRange<T>(value)))
|
||||
{
|
||||
static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
|
||||
}
|
||||
|
||||
// Copy constructor.
|
||||
template <typename Src>
|
||||
CheckedNumericState(const CheckedNumericState<Src> &rhs)
|
||||
: value_(static_cast<T>(rhs.value())),
|
||||
validity_(GetRangeConstraint(rhs.validity() | DstRangeRelationToSrcRange<T>(rhs.value())))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
explicit CheckedNumericState(
|
||||
Src value,
|
||||
typename std::enable_if<std::numeric_limits<Src>::is_specialized, int>::type = 0)
|
||||
: value_(static_cast<T>(value)), validity_(DstRangeRelationToSrcRange<T>(value))
|
||||
{
|
||||
}
|
||||
|
||||
RangeConstraint validity() const { return validity_; }
|
||||
T value() const { return value_; }
|
||||
};
|
||||
|
||||
// Floating points maintain their own validity, but need translation wrappers.
|
||||
template <typename T>
|
||||
class CheckedNumericState<T, NUMERIC_FLOATING>
|
||||
{
|
||||
private:
|
||||
T value_;
|
||||
|
||||
public:
|
||||
template <typename Src, NumericRepresentation type>
|
||||
friend class CheckedNumericState;
|
||||
|
||||
CheckedNumericState() : value_(0.0) {}
|
||||
|
||||
template <typename Src>
|
||||
CheckedNumericState(
|
||||
Src value,
|
||||
RangeConstraint validity,
|
||||
typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type = 0)
|
||||
{
|
||||
switch (DstRangeRelationToSrcRange<T>(value))
|
||||
{
|
||||
case RANGE_VALID:
|
||||
value_ = static_cast<T>(value);
|
||||
break;
|
||||
|
||||
case RANGE_UNDERFLOW:
|
||||
value_ = -std::numeric_limits<T>::infinity();
|
||||
break;
|
||||
|
||||
case RANGE_OVERFLOW:
|
||||
value_ = std::numeric_limits<T>::infinity();
|
||||
break;
|
||||
|
||||
case RANGE_INVALID:
|
||||
value_ = std::numeric_limits<T>::quiet_NaN();
|
||||
break;
|
||||
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
explicit CheckedNumericState(
|
||||
Src value,
|
||||
typename std::enable_if<std::numeric_limits<Src>::is_specialized, int>::type = 0)
|
||||
: value_(static_cast<T>(value))
|
||||
{
|
||||
}
|
||||
|
||||
// Copy constructor.
|
||||
template <typename Src>
|
||||
CheckedNumericState(const CheckedNumericState<Src> &rhs) : value_(static_cast<T>(rhs.value()))
|
||||
{
|
||||
}
|
||||
|
||||
RangeConstraint validity() const
|
||||
{
|
||||
return GetRangeConstraint(value_ <= std::numeric_limits<T>::max(),
|
||||
value_ >= -std::numeric_limits<T>::max());
|
||||
}
|
||||
T value() const { return value_; }
|
||||
};
|
||||
|
||||
// For integers less than 128-bit and floats 32-bit or larger, we have the type
|
||||
// with the larger maximum exponent take precedence.
|
||||
enum ArithmeticPromotionCategory
|
||||
{
|
||||
LEFT_PROMOTION,
|
||||
RIGHT_PROMOTION
|
||||
};
|
||||
|
||||
template <typename Lhs,
|
||||
typename Rhs = Lhs,
|
||||
ArithmeticPromotionCategory Promotion =
|
||||
(MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) ? LEFT_PROMOTION
|
||||
: RIGHT_PROMOTION>
|
||||
struct ArithmeticPromotion;
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
struct ArithmeticPromotion<Lhs, Rhs, LEFT_PROMOTION>
|
||||
{
|
||||
typedef Lhs type;
|
||||
};
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
struct ArithmeticPromotion<Lhs, Rhs, RIGHT_PROMOTION>
|
||||
{
|
||||
typedef Rhs type;
|
||||
};
|
||||
|
||||
// We can statically check if operations on the provided types can wrap, so we
|
||||
// can skip the checked operations if they're not needed. So, for an integer we
|
||||
// care if the destination type preserves the sign and is twice the width of
|
||||
// the source.
|
||||
template <typename T, typename Lhs, typename Rhs>
|
||||
struct IsIntegerArithmeticSafe
|
||||
{
|
||||
static const bool value =
|
||||
!std::numeric_limits<T>::is_iec559 &&
|
||||
StaticDstRangeRelationToSrcRange<T, Lhs>::value == NUMERIC_RANGE_CONTAINED &&
|
||||
sizeof(T) >= (2 * sizeof(Lhs)) &&
|
||||
StaticDstRangeRelationToSrcRange<T, Rhs>::value != NUMERIC_RANGE_CONTAINED &&
|
||||
sizeof(T) >= (2 * sizeof(Rhs));
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLEBASE_NUMERICS_SAFE_MATH_IMPL_H_
|
|
@ -1,771 +0,0 @@
|
|||
// Copyright 2013 The Chromium 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/numerics/safe_math.h"
|
||||
#include "build/build_config.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
|
||||
#include <mmintrin.h>
|
||||
#endif
|
||||
|
||||
using std::numeric_limits;
|
||||
using base::CheckedNumeric;
|
||||
using base::checked_cast;
|
||||
using base::IsValueInRangeForNumericType;
|
||||
using base::IsValueNegative;
|
||||
using base::SizeT;
|
||||
using base::StrictNumeric;
|
||||
using base::saturated_cast;
|
||||
using base::strict_cast;
|
||||
using base::internal::MaxExponent;
|
||||
using base::internal::RANGE_VALID;
|
||||
using base::internal::RANGE_INVALID;
|
||||
using base::internal::RANGE_OVERFLOW;
|
||||
using base::internal::RANGE_UNDERFLOW;
|
||||
using base::internal::SignedIntegerForSize;
|
||||
|
||||
// These tests deliberately cause arithmetic overflows. If the compiler is
|
||||
// aggressive enough, it can const fold these overflows. Disable warnings about
|
||||
// overflows for const expressions.
|
||||
#if defined(OS_WIN)
|
||||
#pragma warning(disable : 4756)
|
||||
#endif
|
||||
|
||||
// This is a helper function for finding the maximum value in Src that can be
|
||||
// wholy represented as the destination floating-point type.
|
||||
template <typename Dst, typename Src>
|
||||
Dst GetMaxConvertibleToFloat()
|
||||
{
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
typedef numeric_limits<Src> SrcLimits;
|
||||
static_assert(SrcLimits::is_specialized, "Source must be numeric.");
|
||||
static_assert(DstLimits::is_specialized, "Destination must be numeric.");
|
||||
CHECK(DstLimits::is_iec559);
|
||||
|
||||
if (SrcLimits::digits <= DstLimits::digits &&
|
||||
MaxExponent<Src>::value <= MaxExponent<Dst>::value)
|
||||
return SrcLimits::max();
|
||||
Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
|
||||
while (max != static_cast<Src>(static_cast<Dst>(max)))
|
||||
{
|
||||
max /= 2;
|
||||
}
|
||||
return static_cast<Dst>(max);
|
||||
}
|
||||
|
||||
// Helper macros to wrap displaying the conversion types and line numbers.
|
||||
#define TEST_EXPECTED_VALIDITY(expected, actual) \
|
||||
EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid()) \
|
||||
<< "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst << " on line " \
|
||||
<< line;
|
||||
|
||||
#define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
|
||||
#define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
|
||||
|
||||
#define TEST_EXPECTED_VALUE(expected, actual) \
|
||||
EXPECT_EQ(static_cast<Dst>(expected), CheckedNumeric<Dst>(actual).ValueUnsafe()) \
|
||||
<< "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst << " on line " \
|
||||
<< line;
|
||||
|
||||
// Signed integer arithmetic.
|
||||
template <typename Dst>
|
||||
static void TestSpecializedArithmetic(
|
||||
const char *dst,
|
||||
int line,
|
||||
typename std::enable_if<numeric_limits<Dst>::is_integer && numeric_limits<Dst>::is_signed,
|
||||
int>::type = 0)
|
||||
{
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::min()));
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()).Abs());
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
|
||||
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1);
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max());
|
||||
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1);
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) - -1);
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max());
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max());
|
||||
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) * 2);
|
||||
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) / -1);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
|
||||
|
||||
// Modulus is legal only for integers.
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
|
||||
TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-1) % -2);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
|
||||
// Test all the different modulus combinations.
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
|
||||
CheckedNumeric<Dst> checked_dst = 1;
|
||||
TEST_EXPECTED_VALUE(0, checked_dst %= 1);
|
||||
}
|
||||
|
||||
// Unsigned integer arithmetic.
|
||||
template <typename Dst>
|
||||
static void TestSpecializedArithmetic(
|
||||
const char *dst,
|
||||
int line,
|
||||
typename std::enable_if<numeric_limits<Dst>::is_integer && !numeric_limits<Dst>::is_signed,
|
||||
int>::type = 0)
|
||||
{
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min()));
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs());
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1);
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs());
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<typename SignedIntegerForSize<Dst>::type>(
|
||||
std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min())
|
||||
.UnsignedAbs());
|
||||
|
||||
// Modulus is legal only for integers.
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
|
||||
// Test all the different modulus combinations.
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
|
||||
CheckedNumeric<Dst> checked_dst = 1;
|
||||
TEST_EXPECTED_VALUE(0, checked_dst %= 1);
|
||||
}
|
||||
|
||||
// Floating point arithmetic.
|
||||
template <typename Dst>
|
||||
void TestSpecializedArithmetic(
|
||||
const char *dst,
|
||||
int line,
|
||||
typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0)
|
||||
{
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min()));
|
||||
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs());
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
|
||||
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + -1);
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max());
|
||||
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max());
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max());
|
||||
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) * 2);
|
||||
|
||||
TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
|
||||
EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating());
|
||||
}
|
||||
|
||||
// Generic arithmetic tests.
|
||||
template <typename Dst>
|
||||
static void TestArithmetic(const char *dst, int line)
|
||||
{
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
|
||||
EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
|
||||
EXPECT_EQ(
|
||||
false,
|
||||
CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max()).IsValid());
|
||||
EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
|
||||
EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
|
||||
EXPECT_EQ(static_cast<Dst>(1),
|
||||
CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max())
|
||||
.ValueOrDefault(1));
|
||||
|
||||
// Test the operator combinations.
|
||||
TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1);
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1);
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1);
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
|
||||
CheckedNumeric<Dst> checked_dst = 1;
|
||||
TEST_EXPECTED_VALUE(2, checked_dst += 1);
|
||||
checked_dst = 1;
|
||||
TEST_EXPECTED_VALUE(0, checked_dst -= 1);
|
||||
checked_dst = 1;
|
||||
TEST_EXPECTED_VALUE(1, checked_dst *= 1);
|
||||
checked_dst = 1;
|
||||
TEST_EXPECTED_VALUE(1, checked_dst /= 1);
|
||||
|
||||
// Generic negation.
|
||||
TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
|
||||
TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
|
||||
TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
|
||||
TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
|
||||
-CheckedNumeric<Dst>(DstLimits::max()));
|
||||
|
||||
// Generic absolute value.
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
|
||||
TEST_EXPECTED_VALUE(DstLimits::max(), CheckedNumeric<Dst>(DstLimits::max()).Abs());
|
||||
|
||||
// Generic addition.
|
||||
TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
|
||||
TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
|
||||
TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + 1);
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
|
||||
|
||||
// Generic subtraction.
|
||||
TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
|
||||
TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
|
||||
TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
|
||||
TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
|
||||
|
||||
// Generic multiplication.
|
||||
TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
|
||||
TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
|
||||
TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
|
||||
TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
|
||||
TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
|
||||
TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
|
||||
TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
|
||||
|
||||
// Generic division.
|
||||
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
|
||||
TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
|
||||
TEST_EXPECTED_VALUE(DstLimits::min() / 2, CheckedNumeric<Dst>(DstLimits::min()) / 2);
|
||||
TEST_EXPECTED_VALUE(DstLimits::max() / 2, CheckedNumeric<Dst>(DstLimits::max()) / 2);
|
||||
|
||||
TestSpecializedArithmetic<Dst>(dst, line);
|
||||
}
|
||||
|
||||
// Helper macro to wrap displaying the conversion types and line numbers.
|
||||
#define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
|
||||
|
||||
TEST(SafeNumerics, SignedIntegerMath)
|
||||
{
|
||||
TEST_ARITHMETIC(int8_t);
|
||||
TEST_ARITHMETIC(int);
|
||||
TEST_ARITHMETIC(intptr_t);
|
||||
TEST_ARITHMETIC(intmax_t);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, UnsignedIntegerMath)
|
||||
{
|
||||
TEST_ARITHMETIC(uint8_t);
|
||||
TEST_ARITHMETIC(unsigned int);
|
||||
TEST_ARITHMETIC(uintptr_t);
|
||||
TEST_ARITHMETIC(uintmax_t);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, FloatingPointMath)
|
||||
{
|
||||
TEST_ARITHMETIC(float);
|
||||
TEST_ARITHMETIC(double);
|
||||
}
|
||||
|
||||
// Enumerates the five different conversions types we need to test.
|
||||
enum NumericConversionType
|
||||
{
|
||||
SIGN_PRESERVING_VALUE_PRESERVING,
|
||||
SIGN_PRESERVING_NARROW,
|
||||
SIGN_TO_UNSIGN_WIDEN_OR_EQUAL,
|
||||
SIGN_TO_UNSIGN_NARROW,
|
||||
UNSIGN_TO_SIGN_NARROW_OR_EQUAL,
|
||||
};
|
||||
|
||||
// Template covering the different conversion tests.
|
||||
template <typename Dst, typename Src, NumericConversionType conversion>
|
||||
struct TestNumericConversion
|
||||
{
|
||||
};
|
||||
|
||||
// EXPECT_EQ wrappers providing specific detail on test failures.
|
||||
#define TEST_EXPECTED_RANGE(expected, actual) \
|
||||
EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual)) \
|
||||
<< "Conversion test: " << src << " value " << actual << " to " << dst << " on line " \
|
||||
<< line;
|
||||
|
||||
template <typename Dst, typename Src>
|
||||
struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING>
|
||||
{
|
||||
static void Test(const char *dst, const char *src, int line)
|
||||
{
|
||||
typedef numeric_limits<Src> SrcLimits;
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
// Integral to floating.
|
||||
static_assert(
|
||||
(DstLimits::is_iec559 && SrcLimits::is_integer) ||
|
||||
// Not floating to integral and...
|
||||
(!(DstLimits::is_integer && SrcLimits::is_iec559) &&
|
||||
// Same sign, same numeric, source is narrower or same.
|
||||
((SrcLimits::is_signed == DstLimits::is_signed && sizeof(Dst) >= sizeof(Src)) ||
|
||||
// Or signed destination and source is smaller
|
||||
(DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))),
|
||||
"Comparison must be sign preserving and value preserving");
|
||||
|
||||
const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
|
||||
TEST_EXPECTED_SUCCESS(checked_dst);
|
||||
if (MaxExponent<Dst>::value > MaxExponent<Src>::value)
|
||||
{
|
||||
if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1)
|
||||
{
|
||||
// At least twice larger type.
|
||||
TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
|
||||
}
|
||||
else
|
||||
{ // Larger, but not at least twice as large.
|
||||
TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
|
||||
TEST_EXPECTED_SUCCESS(checked_dst + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Same width type.
|
||||
TEST_EXPECTED_FAILURE(checked_dst + 1);
|
||||
}
|
||||
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
|
||||
if (SrcLimits::is_iec559)
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
|
||||
TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
|
||||
}
|
||||
else if (numeric_limits<Src>::is_signed)
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Dst, typename Src>
|
||||
struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW>
|
||||
{
|
||||
static void Test(const char *dst, const char *src, int line)
|
||||
{
|
||||
typedef numeric_limits<Src> SrcLimits;
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
static_assert(SrcLimits::is_signed == DstLimits::is_signed,
|
||||
"Destination and source sign must be the same");
|
||||
static_assert(sizeof(Dst) < sizeof(Src) || (DstLimits::is_integer && SrcLimits::is_iec559),
|
||||
"Destination must be narrower than source");
|
||||
|
||||
const CheckedNumeric<Dst> checked_dst;
|
||||
TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
|
||||
TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
|
||||
TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
|
||||
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
|
||||
if (SrcLimits::is_iec559)
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
|
||||
TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
|
||||
if (DstLimits::is_integer)
|
||||
{
|
||||
if (SrcLimits::digits < DstLimits::digits)
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, static_cast<Src>(DstLimits::max()));
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
|
||||
}
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID,
|
||||
static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
|
||||
}
|
||||
}
|
||||
else if (SrcLimits::is_signed)
|
||||
{
|
||||
TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Dst, typename Src>
|
||||
struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL>
|
||||
{
|
||||
static void Test(const char *dst, const char *src, int line)
|
||||
{
|
||||
typedef numeric_limits<Src> SrcLimits;
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
static_assert(sizeof(Dst) >= sizeof(Src),
|
||||
"Destination must be equal or wider than source.");
|
||||
static_assert(SrcLimits::is_signed, "Source must be signed");
|
||||
static_assert(!DstLimits::is_signed, "Destination must be unsigned");
|
||||
|
||||
const CheckedNumeric<Dst> checked_dst;
|
||||
TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
|
||||
TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
|
||||
TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max());
|
||||
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Dst, typename Src>
|
||||
struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW>
|
||||
{
|
||||
static void Test(const char *dst, const char *src, int line)
|
||||
{
|
||||
typedef numeric_limits<Src> SrcLimits;
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
static_assert(
|
||||
(DstLimits::is_integer && SrcLimits::is_iec559) || (sizeof(Dst) < sizeof(Src)),
|
||||
"Destination must be narrower than source.");
|
||||
static_assert(SrcLimits::is_signed, "Source must be signed.");
|
||||
static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
|
||||
|
||||
const CheckedNumeric<Dst> checked_dst;
|
||||
TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
|
||||
TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
|
||||
TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
|
||||
TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max());
|
||||
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
|
||||
if (SrcLimits::is_iec559)
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
|
||||
TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
|
||||
if (DstLimits::is_integer)
|
||||
{
|
||||
if (SrcLimits::digits < DstLimits::digits)
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, static_cast<Src>(DstLimits::max()));
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
|
||||
}
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID,
|
||||
static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Dst, typename Src>
|
||||
struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL>
|
||||
{
|
||||
static void Test(const char *dst, const char *src, int line)
|
||||
{
|
||||
typedef numeric_limits<Src> SrcLimits;
|
||||
typedef numeric_limits<Dst> DstLimits;
|
||||
static_assert(sizeof(Dst) <= sizeof(Src),
|
||||
"Destination must be narrower or equal to source.");
|
||||
static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
|
||||
static_assert(DstLimits::is_signed, "Destination must be signed.");
|
||||
|
||||
const CheckedNumeric<Dst> checked_dst;
|
||||
TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
|
||||
TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
|
||||
TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min());
|
||||
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
|
||||
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
|
||||
TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
|
||||
}
|
||||
};
|
||||
|
||||
// Helper macro to wrap displaying the conversion types and line numbers
|
||||
#define TEST_NUMERIC_CONVERSION(d, s, t) TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__)
|
||||
|
||||
TEST(SafeNumerics, IntMinOperations)
|
||||
{
|
||||
TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
|
||||
TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, IntOperations)
|
||||
{
|
||||
TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
|
||||
TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, IntMaxOperations)
|
||||
{
|
||||
TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(intmax_t, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
|
||||
TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW);
|
||||
TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, FloatOperations)
|
||||
{
|
||||
TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(float, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(float, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
|
||||
TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, DoubleOperations)
|
||||
{
|
||||
TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(double, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
TEST_NUMERIC_CONVERSION(double, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, SizeTOperations)
|
||||
{
|
||||
TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
|
||||
TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, CastTests)
|
||||
{
|
||||
// MSVC catches and warns that we're forcing saturation in these tests.
|
||||
// Since that's intentional, we need to shut this warning off.
|
||||
#if defined(COMPILER_MSVC)
|
||||
#pragma warning(disable : 4756)
|
||||
#endif
|
||||
|
||||
int small_positive = 1;
|
||||
int small_negative = -1;
|
||||
double double_small = 1.0;
|
||||
double double_large = numeric_limits<double>::max();
|
||||
double double_infinity = numeric_limits<float>::infinity();
|
||||
double double_large_int = numeric_limits<int>::max();
|
||||
double double_small_int = numeric_limits<int>::min();
|
||||
|
||||
// Just test that the casts compile, since the other tests cover logic.
|
||||
EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0)));
|
||||
EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0)));
|
||||
EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0)));
|
||||
EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0)));
|
||||
EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U)));
|
||||
EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U)));
|
||||
EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U)));
|
||||
|
||||
EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid());
|
||||
EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
|
||||
EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
|
||||
|
||||
EXPECT_TRUE(IsValueNegative(-1));
|
||||
EXPECT_TRUE(IsValueNegative(numeric_limits<int>::min()));
|
||||
EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::min()));
|
||||
EXPECT_TRUE(IsValueNegative(-numeric_limits<double>::max()));
|
||||
EXPECT_FALSE(IsValueNegative(0));
|
||||
EXPECT_FALSE(IsValueNegative(1));
|
||||
EXPECT_FALSE(IsValueNegative(0u));
|
||||
EXPECT_FALSE(IsValueNegative(1u));
|
||||
EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
|
||||
EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
|
||||
EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
|
||||
|
||||
// These casts and coercions will fail to compile:
|
||||
// EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
|
||||
// EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
|
||||
// EXPECT_EQ(1ULL, StrictNumeric<size_t>(1));
|
||||
// EXPECT_EQ(1, StrictNumeric<size_t>(1U));
|
||||
|
||||
// Test various saturation corner cases.
|
||||
EXPECT_EQ(saturated_cast<int>(small_negative), static_cast<int>(small_negative));
|
||||
EXPECT_EQ(saturated_cast<int>(small_positive), static_cast<int>(small_positive));
|
||||
EXPECT_EQ(saturated_cast<unsigned>(small_negative), static_cast<unsigned>(0));
|
||||
EXPECT_EQ(saturated_cast<int>(double_small), static_cast<int>(double_small));
|
||||
EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max());
|
||||
EXPECT_EQ(saturated_cast<float>(double_large), double_infinity);
|
||||
EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
|
||||
EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int));
|
||||
EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
|
||||
|
||||
float not_a_number =
|
||||
std::numeric_limits<float>::infinity() - std::numeric_limits<float>::infinity();
|
||||
EXPECT_TRUE(std::isnan(not_a_number));
|
||||
EXPECT_EQ(0, saturated_cast<int>(not_a_number));
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(SafeNumerics, SaturatedCastChecks)
|
||||
{
|
||||
float not_a_number =
|
||||
std::numeric_limits<float>::infinity() - std::numeric_limits<float>::infinity();
|
||||
EXPECT_TRUE(std::isnan(not_a_number));
|
||||
EXPECT_DEATH((saturated_cast<int, base::SaturatedCastNaNBehaviorCheck>(not_a_number)), "");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(SafeNumerics, IsValueInRangeForNumericType)
|
||||
{
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(std::numeric_limits<int32_t>::min()));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(std::numeric_limits<int64_t>::min()));
|
||||
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(std::numeric_limits<int32_t>::min()));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
|
||||
static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
|
||||
static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(std::numeric_limits<int64_t>::min()));
|
||||
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(std::numeric_limits<int32_t>::min()));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(std::numeric_limits<int64_t>::min()));
|
||||
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
|
||||
EXPECT_FALSE(IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(std::numeric_limits<int32_t>::min()));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
|
||||
static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
|
||||
EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(std::numeric_limits<int64_t>::min()));
|
||||
}
|
||||
|
||||
TEST(SafeNumerics, CompoundNumericOperations)
|
||||
{
|
||||
CheckedNumeric<int> a = 1;
|
||||
CheckedNumeric<int> b = 2;
|
||||
CheckedNumeric<int> c = 3;
|
||||
CheckedNumeric<int> d = 4;
|
||||
a += b;
|
||||
EXPECT_EQ(3, a.ValueOrDie());
|
||||
a -= c;
|
||||
EXPECT_EQ(0, a.ValueOrDie());
|
||||
d /= b;
|
||||
EXPECT_EQ(2, d.ValueOrDie());
|
||||
d *= d;
|
||||
EXPECT_EQ(4, d.ValueOrDie());
|
||||
|
||||
CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
|
||||
EXPECT_TRUE(too_large.IsValid());
|
||||
too_large += d;
|
||||
EXPECT_FALSE(too_large.IsValid());
|
||||
too_large -= d;
|
||||
EXPECT_FALSE(too_large.IsValid());
|
||||
too_large /= d;
|
||||
EXPECT_FALSE(too_large.IsValid());
|
||||
}
|
|
@ -1,245 +0,0 @@
|
|||
// Copyright (c) 2011 The Chromium 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 "anglebase/sha1.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "anglebase/sys_byteorder.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
|
||||
// Implementation of SHA-1. Only handles data in byte-sized blocks,
|
||||
// which simplifies the code a fair bit.
|
||||
|
||||
// Identifier names follow notation in FIPS PUB 180-3, where you'll
|
||||
// also find a description of the algorithm:
|
||||
// http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
|
||||
|
||||
// Usage example:
|
||||
//
|
||||
// SecureHashAlgorithm sha;
|
||||
// while(there is data to hash)
|
||||
// sha.Update(moredata, size of data);
|
||||
// sha.Final();
|
||||
// memcpy(somewhere, sha.Digest(), 20);
|
||||
//
|
||||
// to reuse the instance of sha, call sha.Init();
|
||||
|
||||
// TODO(jhawkins): Replace this implementation with a per-platform
|
||||
// implementation using each platform's crypto library. See
|
||||
// http://crbug.com/47218
|
||||
|
||||
class SecureHashAlgorithm
|
||||
{
|
||||
public:
|
||||
SecureHashAlgorithm() { Init(); }
|
||||
|
||||
static const int kDigestSizeBytes;
|
||||
|
||||
void Init();
|
||||
void Update(const void *data, size_t nbytes);
|
||||
void Final();
|
||||
|
||||
// 20 bytes of message digest.
|
||||
const unsigned char *Digest() const { return reinterpret_cast<const unsigned char *>(H); }
|
||||
|
||||
private:
|
||||
void Pad();
|
||||
void Process();
|
||||
|
||||
uint32_t A, B, C, D, E;
|
||||
|
||||
uint32_t H[5];
|
||||
|
||||
union {
|
||||
uint32_t W[80];
|
||||
uint8_t M[64];
|
||||
};
|
||||
|
||||
uint32_t cursor;
|
||||
uint64_t l;
|
||||
};
|
||||
|
||||
static inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D)
|
||||
{
|
||||
if (t < 20)
|
||||
{
|
||||
return (B & C) | ((~B) & D);
|
||||
}
|
||||
else if (t < 40)
|
||||
{
|
||||
return B ^ C ^ D;
|
||||
}
|
||||
else if (t < 60)
|
||||
{
|
||||
return (B & C) | (B & D) | (C & D);
|
||||
}
|
||||
else
|
||||
{
|
||||
return B ^ C ^ D;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t S(uint32_t n, uint32_t X)
|
||||
{
|
||||
return (X << n) | (X >> (32 - n));
|
||||
}
|
||||
|
||||
static inline uint32_t K(uint32_t t)
|
||||
{
|
||||
if (t < 20)
|
||||
{
|
||||
return 0x5a827999;
|
||||
}
|
||||
else if (t < 40)
|
||||
{
|
||||
return 0x6ed9eba1;
|
||||
}
|
||||
else if (t < 60)
|
||||
{
|
||||
return 0x8f1bbcdc;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0xca62c1d6;
|
||||
}
|
||||
}
|
||||
|
||||
const int SecureHashAlgorithm::kDigestSizeBytes = 20;
|
||||
|
||||
void SecureHashAlgorithm::Init()
|
||||
{
|
||||
A = 0;
|
||||
B = 0;
|
||||
C = 0;
|
||||
D = 0;
|
||||
E = 0;
|
||||
cursor = 0;
|
||||
l = 0;
|
||||
H[0] = 0x67452301;
|
||||
H[1] = 0xefcdab89;
|
||||
H[2] = 0x98badcfe;
|
||||
H[3] = 0x10325476;
|
||||
H[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
void SecureHashAlgorithm::Final()
|
||||
{
|
||||
Pad();
|
||||
Process();
|
||||
|
||||
for (int t = 0; t < 5; ++t)
|
||||
H[t] = ByteSwap(H[t]);
|
||||
}
|
||||
|
||||
void SecureHashAlgorithm::Update(const void *data, size_t nbytes)
|
||||
{
|
||||
const uint8_t *d = reinterpret_cast<const uint8_t *>(data);
|
||||
while (nbytes--)
|
||||
{
|
||||
M[cursor++] = *d++;
|
||||
if (cursor >= 64)
|
||||
Process();
|
||||
l += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void SecureHashAlgorithm::Pad()
|
||||
{
|
||||
M[cursor++] = 0x80;
|
||||
|
||||
if (cursor > 64 - 8)
|
||||
{
|
||||
// pad out to next block
|
||||
while (cursor < 64)
|
||||
M[cursor++] = 0;
|
||||
|
||||
Process();
|
||||
}
|
||||
|
||||
while (cursor < 64 - 8)
|
||||
M[cursor++] = 0;
|
||||
|
||||
M[cursor++] = (l >> 56) & 0xff;
|
||||
M[cursor++] = (l >> 48) & 0xff;
|
||||
M[cursor++] = (l >> 40) & 0xff;
|
||||
M[cursor++] = (l >> 32) & 0xff;
|
||||
M[cursor++] = (l >> 24) & 0xff;
|
||||
M[cursor++] = (l >> 16) & 0xff;
|
||||
M[cursor++] = (l >> 8) & 0xff;
|
||||
M[cursor++] = l & 0xff;
|
||||
}
|
||||
|
||||
void SecureHashAlgorithm::Process()
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
// Each a...e corresponds to a section in the FIPS 180-3 algorithm.
|
||||
|
||||
// a.
|
||||
//
|
||||
// W and M are in a union, so no need to memcpy.
|
||||
// memcpy(W, M, sizeof(M));
|
||||
for (t = 0; t < 16; ++t)
|
||||
W[t] = ByteSwap(W[t]);
|
||||
|
||||
// b.
|
||||
for (t = 16; t < 80; ++t)
|
||||
W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
|
||||
|
||||
// c.
|
||||
A = H[0];
|
||||
B = H[1];
|
||||
C = H[2];
|
||||
D = H[3];
|
||||
E = H[4];
|
||||
|
||||
// d.
|
||||
for (t = 0; t < 80; ++t)
|
||||
{
|
||||
uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t);
|
||||
E = D;
|
||||
D = C;
|
||||
C = S(30, B);
|
||||
B = A;
|
||||
A = TEMP;
|
||||
}
|
||||
|
||||
// e.
|
||||
H[0] += A;
|
||||
H[1] += B;
|
||||
H[2] += C;
|
||||
H[3] += D;
|
||||
H[4] += E;
|
||||
|
||||
cursor = 0;
|
||||
}
|
||||
|
||||
std::string SHA1HashString(const std::string &str)
|
||||
{
|
||||
char hash[SecureHashAlgorithm::kDigestSizeBytes];
|
||||
SHA1HashBytes(reinterpret_cast<const unsigned char *>(str.c_str()), str.length(),
|
||||
reinterpret_cast<unsigned char *>(hash));
|
||||
return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes);
|
||||
}
|
||||
|
||||
void SHA1HashBytes(const unsigned char *data, size_t len, unsigned char *hash)
|
||||
{
|
||||
SecureHashAlgorithm sha;
|
||||
sha.Update(data, len);
|
||||
sha.Final();
|
||||
|
||||
memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (c) 2011 The Chromium 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 ANGLEBASE_SHA1_H_
|
||||
#define ANGLEBASE_SHA1_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "anglebase/base_export.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
|
||||
// These functions perform SHA-1 operations.
|
||||
|
||||
static const size_t kSHA1Length = 20; // Length in bytes of a SHA-1 hash.
|
||||
|
||||
// Computes the SHA-1 hash of the input string |str| and returns the full
|
||||
// hash.
|
||||
ANGLEBASE_EXPORT std::string SHA1HashString(const std::string &str);
|
||||
|
||||
// Computes the SHA-1 hash of the |len| bytes in |data| and puts the hash
|
||||
// in |hash|. |hash| must be kSHA1Length bytes long.
|
||||
ANGLEBASE_EXPORT void SHA1HashBytes(const unsigned char *data, size_t len, unsigned char *hash);
|
||||
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLEBASE_SHA1_H_
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
// sys_byteorder.h: Compatiblity hacks for importing Chromium's base/SHA1.
|
||||
|
||||
#ifndef ANGLEBASE_SYS_BYTEORDER_H_
|
||||
#define ANGLEBASE_SYS_BYTEORDER_H_
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
namespace base
|
||||
{
|
||||
|
||||
// Returns a value with all bytes in |x| swapped, i.e. reverses the endianness.
|
||||
inline uint16_t ByteSwap(uint16_t x)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
return _byteswap_ushort(x);
|
||||
#else
|
||||
return __builtin_bswap16(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t ByteSwap(uint32_t x)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
return _byteswap_ulong(x);
|
||||
#else
|
||||
return __builtin_bswap32(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64_t ByteSwap(uint64_t x)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
return _byteswap_uint64(x);
|
||||
#else
|
||||
return __builtin_bswap64(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLEBASE_SYS_BYTEORDER_H_
|
|
@ -1,2 +0,0 @@
|
|||
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
|
@ -1,338 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
|
||||
// Note - The x86 and x64 versions do _not_ produce the same results, as the
|
||||
// algorithms are optimized for their respective platforms. You can still
|
||||
// compile and run any of them on any platform, but your performance with the
|
||||
// non-native version will be less than optimal.
|
||||
|
||||
#include "MurmurHash3.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Platform-specific functions and macros
|
||||
|
||||
// Microsoft Visual Studio
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#define FORCE_INLINE __forceinline
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ROTL32(x,y) _rotl(x,y)
|
||||
#define ROTL64(x,y) _rotl64(x,y)
|
||||
|
||||
#define BIG_CONSTANT(x) (x)
|
||||
|
||||
// Other compilers
|
||||
|
||||
#else // defined(_MSC_VER)
|
||||
|
||||
#define FORCE_INLINE inline __attribute__((always_inline))
|
||||
|
||||
inline uint32_t rotl32 ( uint32_t x, int8_t r )
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
}
|
||||
|
||||
inline uint64_t rotl64 ( uint64_t x, int8_t r )
|
||||
{
|
||||
return (x << r) | (x >> (64 - r));
|
||||
}
|
||||
|
||||
#define ROTL32(x,y) rotl32(x,y)
|
||||
#define ROTL64(x,y) rotl64(x,y)
|
||||
|
||||
#define BIG_CONSTANT(x) (x##LLU)
|
||||
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Block read - if your platform needs to do endian-swapping or can only
|
||||
// handle aligned reads, do the conversion here
|
||||
|
||||
FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finalization mix - force all bits of a hash block to avalanche
|
||||
|
||||
FORCE_INLINE uint32_t fmix32 ( uint32_t h )
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
//----------
|
||||
|
||||
FORCE_INLINE uint64_t fmix64 ( uint64_t k )
|
||||
{
|
||||
k ^= k >> 33;
|
||||
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
|
||||
k ^= k >> 33;
|
||||
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
|
||||
k ^= k >> 33;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace angle
|
||||
{
|
||||
void MurmurHash3_x86_32 ( const void * key, int len,
|
||||
uint32_t seed, void * out )
|
||||
{
|
||||
const uint8_t * data = (const uint8_t*)key;
|
||||
const int nblocks = len / 4;
|
||||
|
||||
uint32_t h1 = seed;
|
||||
|
||||
const uint32_t c1 = 0xcc9e2d51;
|
||||
const uint32_t c2 = 0x1b873593;
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
|
||||
|
||||
for(int i = -nblocks; i; i++)
|
||||
{
|
||||
uint32_t k1 = getblock32(blocks,i);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = ROTL32(k1,15);
|
||||
k1 *= c2;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = ROTL32(h1,13);
|
||||
h1 = h1*5+0xe6546b64;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
|
||||
|
||||
uint32_t k1 = 0;
|
||||
|
||||
switch(len & 3)
|
||||
{
|
||||
case 3: k1 ^= tail[2] << 16;
|
||||
case 2: k1 ^= tail[1] << 8;
|
||||
case 1: k1 ^= tail[0];
|
||||
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len;
|
||||
|
||||
h1 = fmix32(h1);
|
||||
|
||||
*(uint32_t*)out = h1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MurmurHash3_x86_128 ( const void * key, const int len,
|
||||
uint32_t seed, void * out )
|
||||
{
|
||||
const uint8_t * data = (const uint8_t*)key;
|
||||
const int nblocks = len / 16;
|
||||
|
||||
uint32_t h1 = seed;
|
||||
uint32_t h2 = seed;
|
||||
uint32_t h3 = seed;
|
||||
uint32_t h4 = seed;
|
||||
|
||||
const uint32_t c1 = 0x239b961b;
|
||||
const uint32_t c2 = 0xab0e9789;
|
||||
const uint32_t c3 = 0x38b34ae5;
|
||||
const uint32_t c4 = 0xa1e38b93;
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
|
||||
|
||||
for(int i = -nblocks; i; i++)
|
||||
{
|
||||
uint32_t k1 = getblock32(blocks,i*4+0);
|
||||
uint32_t k2 = getblock32(blocks,i*4+1);
|
||||
uint32_t k3 = getblock32(blocks,i*4+2);
|
||||
uint32_t k4 = getblock32(blocks,i*4+3);
|
||||
|
||||
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
|
||||
h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
|
||||
|
||||
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
|
||||
|
||||
h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
|
||||
|
||||
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
|
||||
|
||||
h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
|
||||
|
||||
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
|
||||
|
||||
h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
|
||||
|
||||
uint32_t k1 = 0;
|
||||
uint32_t k2 = 0;
|
||||
uint32_t k3 = 0;
|
||||
uint32_t k4 = 0;
|
||||
|
||||
switch(len & 15)
|
||||
{
|
||||
case 15: k4 ^= tail[14] << 16;
|
||||
case 14: k4 ^= tail[13] << 8;
|
||||
case 13: k4 ^= tail[12] << 0;
|
||||
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
|
||||
|
||||
case 12: k3 ^= tail[11] << 24;
|
||||
case 11: k3 ^= tail[10] << 16;
|
||||
case 10: k3 ^= tail[ 9] << 8;
|
||||
case 9: k3 ^= tail[ 8] << 0;
|
||||
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
|
||||
|
||||
case 8: k2 ^= tail[ 7] << 24;
|
||||
case 7: k2 ^= tail[ 6] << 16;
|
||||
case 6: k2 ^= tail[ 5] << 8;
|
||||
case 5: k2 ^= tail[ 4] << 0;
|
||||
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
|
||||
|
||||
case 4: k1 ^= tail[ 3] << 24;
|
||||
case 3: k1 ^= tail[ 2] << 16;
|
||||
case 2: k1 ^= tail[ 1] << 8;
|
||||
case 1: k1 ^= tail[ 0] << 0;
|
||||
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
|
||||
|
||||
h1 += h2; h1 += h3; h1 += h4;
|
||||
h2 += h1; h3 += h1; h4 += h1;
|
||||
|
||||
h1 = fmix32(h1);
|
||||
h2 = fmix32(h2);
|
||||
h3 = fmix32(h3);
|
||||
h4 = fmix32(h4);
|
||||
|
||||
h1 += h2; h1 += h3; h1 += h4;
|
||||
h2 += h1; h3 += h1; h4 += h1;
|
||||
|
||||
((uint32_t*)out)[0] = h1;
|
||||
((uint32_t*)out)[1] = h2;
|
||||
((uint32_t*)out)[2] = h3;
|
||||
((uint32_t*)out)[3] = h4;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MurmurHash3_x64_128 ( const void * key, const int len,
|
||||
const uint32_t seed, void * out )
|
||||
{
|
||||
const uint8_t * data = (const uint8_t*)key;
|
||||
const int nblocks = len / 16;
|
||||
|
||||
uint64_t h1 = seed;
|
||||
uint64_t h2 = seed;
|
||||
|
||||
const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
|
||||
const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
|
||||
|
||||
//----------
|
||||
// body
|
||||
|
||||
const uint64_t * blocks = (const uint64_t *)(data);
|
||||
|
||||
for(int i = 0; i < nblocks; i++)
|
||||
{
|
||||
uint64_t k1 = getblock64(blocks,i*2+0);
|
||||
uint64_t k2 = getblock64(blocks,i*2+1);
|
||||
|
||||
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
|
||||
h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
|
||||
|
||||
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
|
||||
h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
|
||||
}
|
||||
|
||||
//----------
|
||||
// tail
|
||||
|
||||
const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
|
||||
|
||||
uint64_t k1 = 0;
|
||||
uint64_t k2 = 0;
|
||||
|
||||
switch(len & 15)
|
||||
{
|
||||
case 15: k2 ^= ((uint64_t)tail[14]) << 48;
|
||||
case 14: k2 ^= ((uint64_t)tail[13]) << 40;
|
||||
case 13: k2 ^= ((uint64_t)tail[12]) << 32;
|
||||
case 12: k2 ^= ((uint64_t)tail[11]) << 24;
|
||||
case 11: k2 ^= ((uint64_t)tail[10]) << 16;
|
||||
case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
|
||||
case 9: k2 ^= ((uint64_t)tail[ 8]) << 0;
|
||||
k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
|
||||
|
||||
case 8: k1 ^= ((uint64_t)tail[ 7]) << 56;
|
||||
case 7: k1 ^= ((uint64_t)tail[ 6]) << 48;
|
||||
case 6: k1 ^= ((uint64_t)tail[ 5]) << 40;
|
||||
case 5: k1 ^= ((uint64_t)tail[ 4]) << 32;
|
||||
case 4: k1 ^= ((uint64_t)tail[ 3]) << 24;
|
||||
case 3: k1 ^= ((uint64_t)tail[ 2]) << 16;
|
||||
case 2: k1 ^= ((uint64_t)tail[ 1]) << 8;
|
||||
case 1: k1 ^= ((uint64_t)tail[ 0]) << 0;
|
||||
k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
|
||||
};
|
||||
|
||||
//----------
|
||||
// finalization
|
||||
|
||||
h1 ^= len; h2 ^= len;
|
||||
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
h1 = fmix64(h1);
|
||||
h2 = fmix64(h2);
|
||||
|
||||
h1 += h2;
|
||||
h2 += h1;
|
||||
|
||||
((uint64_t*)out)[0] = h1;
|
||||
((uint64_t*)out)[1] = h2;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
|
||||
#ifndef _MURMURHASH3_H_
|
||||
#define _MURMURHASH3_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Platform-specific functions and macros
|
||||
|
||||
// Microsoft Visual Studio
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
// Other compilers
|
||||
|
||||
#else // defined(_MSC_VER)
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace angle
|
||||
{
|
||||
void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out );
|
||||
|
||||
void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );
|
||||
|
||||
void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // _MURMURHASH3_H_
|
|
@ -1,156 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// tls.cpp: Simple cross-platform interface for thread local storage.
|
||||
|
||||
#include "common/tls.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
#include <vector>
|
||||
#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;
|
||||
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
#ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
if (!freeTlsIndices.empty())
|
||||
{
|
||||
DWORD result = freeTlsIndices.back();
|
||||
freeTlsIndices.pop_back();
|
||||
index = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = nextTlsIndex++;
|
||||
}
|
||||
#else
|
||||
index = TlsAlloc();
|
||||
#endif
|
||||
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
// Create global pool key
|
||||
if ((pthread_key_create(&index, nullptr)) != 0)
|
||||
{
|
||||
index = TLS_INVALID_INDEX;
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(index != TLS_INVALID_INDEX && "CreateTLSIndex(): Unable to allocate Thread Local Storage");
|
||||
return index;
|
||||
}
|
||||
|
||||
bool DestroyTLSIndex(TLSIndex index)
|
||||
{
|
||||
assert(index != TLS_INVALID_INDEX && "DestroyTLSIndex(): Invalid TLS Index");
|
||||
if (index == TLS_INVALID_INDEX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#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;
|
||||
#else
|
||||
return (TlsFree(index) == TRUE);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return (pthread_key_delete(index) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SetTLSValue(TLSIndex index, void *value)
|
||||
{
|
||||
assert(index != TLS_INVALID_INDEX && "SetTLSValue(): Invalid TLS Index");
|
||||
if (index == TLS_INVALID_INDEX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#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;
|
||||
#else
|
||||
return (TlsSetValue(index, value) == TRUE);
|
||||
#endif
|
||||
#elif defined(ANGLE_PLATFORM_POSIX)
|
||||
return (pthread_setspecific(index, value) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *GetTLSValue(TLSIndex index)
|
||||
{
|
||||
assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
|
||||
if (index == TLS_INVALID_INDEX)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#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
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// tls.h: Simple cross-platform interface for thread local storage.
|
||||
|
||||
#ifndef COMMON_TLS_H_
|
||||
#define COMMON_TLS_H_
|
||||
|
||||
#include "common/platform.h"
|
||||
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
|
||||
// TLS does not exist for Windows Store and needs to be emulated
|
||||
# ifdef ANGLE_ENABLE_WINDOWS_STORE
|
||||
# ifndef TLS_OUT_OF_INDEXES
|
||||
# define TLS_OUT_OF_INDEXES static_cast<DWORD>(0xFFFFFFFF)
|
||||
# endif
|
||||
# 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)
|
||||
# include <pthread.h>
|
||||
# include <semaphore.h>
|
||||
# include <errno.h>
|
||||
typedef pthread_key_t TLSIndex;
|
||||
# define TLS_INVALID_INDEX (static_cast<TLSIndex>(-1))
|
||||
#else
|
||||
# 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);
|
||||
|
||||
bool SetTLSValue(TLSIndex index, void *value);
|
||||
void *GetTLSValue(TLSIndex index);
|
||||
|
||||
#endif // COMMON_TLS_H_
|
|
@ -1,275 +0,0 @@
|
|||
// GENERATED FILE - DO NOT EDIT.
|
||||
// Generated by gen_uniform_type_table.py.
|
||||
//
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
// Uniform type info table:
|
||||
// Metadata about a particular uniform format, indexed by GL type.
|
||||
|
||||
#include <array>
|
||||
#include "common/utilities.h"
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr std::array<UniformTypeInfo, 59> kInfoTable = {
|
||||
{{GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, 0, 0, 0, 0, 0 * 0, 0 * 0, false, false, false},
|
||||
{GL_BOOL, GL_BOOL, GL_NONE, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4,
|
||||
sizeof(GLint) * 1, false, false, false},
|
||||
{GL_BOOL_VEC2, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 2, false, false, false},
|
||||
{GL_BOOL_VEC3, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 3, false, false, false},
|
||||
{GL_BOOL_VEC4, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 4, false, false, false},
|
||||
{GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL, 1, 1, 1, sizeof(GLfloat), sizeof(GLfloat) * 4,
|
||||
sizeof(GLfloat) * 1, false, false, false},
|
||||
{GL_FLOAT_MAT2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2, GL_NONE, 2, 2, 4, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 8, sizeof(GLfloat) * 4, false, true, false},
|
||||
{GL_FLOAT_MAT2x3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3x2, GL_NONE, 3, 2, 6, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 12, sizeof(GLfloat) * 6, false, true, false},
|
||||
{GL_FLOAT_MAT2x4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4x2, GL_NONE, 4, 2, 8, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 16, sizeof(GLfloat) * 8, false, true, false},
|
||||
{GL_FLOAT_MAT3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3, GL_NONE, 3, 3, 9, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 12, sizeof(GLfloat) * 9, false, true, false},
|
||||
{GL_FLOAT_MAT3x2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2x3, GL_NONE, 2, 3, 6, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 8, sizeof(GLfloat) * 6, false, true, false},
|
||||
{GL_FLOAT_MAT3x4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4x3, GL_NONE, 4, 3, 12, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 16, sizeof(GLfloat) * 12, false, true, false},
|
||||
{GL_FLOAT_MAT4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4, GL_NONE, 4, 4, 16, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 16, sizeof(GLfloat) * 16, false, true, false},
|
||||
{GL_FLOAT_MAT4x2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2x4, GL_NONE, 2, 4, 8, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 8, sizeof(GLfloat) * 8, false, true, false},
|
||||
{GL_FLOAT_MAT4x3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3x4, GL_NONE, 3, 4, 12, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 12, sizeof(GLfloat) * 12, false, true, false},
|
||||
{GL_FLOAT_VEC2, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 4, sizeof(GLfloat) * 2, false, false, false},
|
||||
{GL_FLOAT_VEC3, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 4, sizeof(GLfloat) * 3, false, false, false},
|
||||
{GL_FLOAT_VEC4, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, sizeof(GLfloat),
|
||||
sizeof(GLfloat) * 4, sizeof(GLfloat) * 4, false, false, false},
|
||||
{GL_IMAGE_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_IMAGE_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_IMAGE_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_IMAGE_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_INT, GL_INT, GL_NONE, GL_NONE, GL_BOOL, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4,
|
||||
sizeof(GLint) * 1, false, false, false},
|
||||
{GL_INT_IMAGE_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_INT_IMAGE_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_INT_IMAGE_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_INT_IMAGE_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
|
||||
{GL_INT_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_INT_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_INT_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_INT_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_INT_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_INT_VEC2, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 2, false, false, false},
|
||||
{GL_INT_VEC3, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 3, false, false, false},
|
||||
{GL_INT_VEC4, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 4, false, false, false},
|
||||
{GL_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_2D_ARRAY_SHADOW, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_2D_RECT_ANGLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_2D_SHADOW, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_CUBE_SHADOW, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint),
|
||||
sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_SAMPLER_EXTERNAL_OES, GL_INT, GL_TEXTURE_EXTERNAL_OES, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
|
||||
{GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL, 1, 1, 1, sizeof(GLuint),
|
||||
sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, false},
|
||||
{GL_UNSIGNED_INT_ATOMIC_COUNTER, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, false},
|
||||
{GL_UNSIGNED_INT_IMAGE_2D, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true},
|
||||
{GL_UNSIGNED_INT_IMAGE_2D_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1,
|
||||
1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true},
|
||||
{GL_UNSIGNED_INT_IMAGE_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true},
|
||||
{GL_UNSIGNED_INT_IMAGE_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true},
|
||||
{GL_UNSIGNED_INT_SAMPLER_2D, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
|
||||
{GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1,
|
||||
1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
|
||||
{GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1,
|
||||
1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
|
||||
{GL_UNSIGNED_INT_SAMPLER_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
|
||||
{GL_UNSIGNED_INT_SAMPLER_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
|
||||
{GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 2, false, false, false},
|
||||
{GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 3, false, false, false},
|
||||
{GL_UNSIGNED_INT_VEC4, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4,
|
||||
sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 4, false, false, false}}};
|
||||
|
||||
size_t GetTypeInfoIndex(GLenum uniformType)
|
||||
{
|
||||
switch (uniformType)
|
||||
{
|
||||
case GL_NONE:
|
||||
return 0;
|
||||
case GL_BOOL:
|
||||
return 1;
|
||||
case GL_BOOL_VEC2:
|
||||
return 2;
|
||||
case GL_BOOL_VEC3:
|
||||
return 3;
|
||||
case GL_BOOL_VEC4:
|
||||
return 4;
|
||||
case GL_FLOAT:
|
||||
return 5;
|
||||
case GL_FLOAT_MAT2:
|
||||
return 6;
|
||||
case GL_FLOAT_MAT2x3:
|
||||
return 7;
|
||||
case GL_FLOAT_MAT2x4:
|
||||
return 8;
|
||||
case GL_FLOAT_MAT3:
|
||||
return 9;
|
||||
case GL_FLOAT_MAT3x2:
|
||||
return 10;
|
||||
case GL_FLOAT_MAT3x4:
|
||||
return 11;
|
||||
case GL_FLOAT_MAT4:
|
||||
return 12;
|
||||
case GL_FLOAT_MAT4x2:
|
||||
return 13;
|
||||
case GL_FLOAT_MAT4x3:
|
||||
return 14;
|
||||
case GL_FLOAT_VEC2:
|
||||
return 15;
|
||||
case GL_FLOAT_VEC3:
|
||||
return 16;
|
||||
case GL_FLOAT_VEC4:
|
||||
return 17;
|
||||
case GL_IMAGE_2D:
|
||||
return 18;
|
||||
case GL_IMAGE_2D_ARRAY:
|
||||
return 19;
|
||||
case GL_IMAGE_3D:
|
||||
return 20;
|
||||
case GL_IMAGE_CUBE:
|
||||
return 21;
|
||||
case GL_INT:
|
||||
return 22;
|
||||
case GL_INT_IMAGE_2D:
|
||||
return 23;
|
||||
case GL_INT_IMAGE_2D_ARRAY:
|
||||
return 24;
|
||||
case GL_INT_IMAGE_3D:
|
||||
return 25;
|
||||
case GL_INT_IMAGE_CUBE:
|
||||
return 26;
|
||||
case GL_INT_SAMPLER_2D:
|
||||
return 27;
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
return 28;
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
return 29;
|
||||
case GL_INT_SAMPLER_3D:
|
||||
return 30;
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
return 31;
|
||||
case GL_INT_VEC2:
|
||||
return 32;
|
||||
case GL_INT_VEC3:
|
||||
return 33;
|
||||
case GL_INT_VEC4:
|
||||
return 34;
|
||||
case GL_SAMPLER_2D:
|
||||
return 35;
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
return 36;
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
return 37;
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
return 38;
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
return 39;
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
return 40;
|
||||
case GL_SAMPLER_3D:
|
||||
return 41;
|
||||
case GL_SAMPLER_CUBE:
|
||||
return 42;
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
return 43;
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
return 44;
|
||||
case GL_UNSIGNED_INT:
|
||||
return 45;
|
||||
case GL_UNSIGNED_INT_ATOMIC_COUNTER:
|
||||
return 46;
|
||||
case GL_UNSIGNED_INT_IMAGE_2D:
|
||||
return 47;
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
|
||||
return 48;
|
||||
case GL_UNSIGNED_INT_IMAGE_3D:
|
||||
return 49;
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE:
|
||||
return 50;
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
return 51;
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
return 52;
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
return 53;
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
return 54;
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
return 55;
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
return 56;
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
return 57;
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
return 58;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType)
|
||||
{
|
||||
ASSERT(kInfoTable[GetTypeInfoIndex(uniformType)].type == uniformType);
|
||||
return kInfoTable[GetTypeInfoIndex(uniformType)];
|
||||
}
|
||||
|
||||
} // namespace gl
|
|
@ -1,986 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
||||
// utilities.cpp: Conversion functions and other utility routines.
|
||||
|
||||
#include "common/utilities.h"
|
||||
#include "common/mathutil.h"
|
||||
#include "common/platform.h"
|
||||
|
||||
#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
|
||||
{
|
||||
|
||||
template <class IndexType>
|
||||
gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
|
||||
size_t count,
|
||||
bool primitiveRestartEnabled,
|
||||
GLuint primitiveRestartIndex)
|
||||
{
|
||||
ASSERT(count > 0);
|
||||
|
||||
IndexType minIndex = 0;
|
||||
IndexType maxIndex = 0;
|
||||
size_t nonPrimitiveRestartIndices = 0;
|
||||
|
||||
if (primitiveRestartEnabled)
|
||||
{
|
||||
// Find the first non-primitive restart index to initialize the min and max values
|
||||
size_t i = 0;
|
||||
for (; i < count; i++)
|
||||
{
|
||||
if (indices[i] != primitiveRestartIndex)
|
||||
{
|
||||
minIndex = indices[i];
|
||||
maxIndex = indices[i];
|
||||
nonPrimitiveRestartIndices++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over the rest of the indices
|
||||
for (; i < count; i++)
|
||||
{
|
||||
if (indices[i] != primitiveRestartIndex)
|
||||
{
|
||||
if (minIndex > indices[i])
|
||||
{
|
||||
minIndex = indices[i];
|
||||
}
|
||||
if (maxIndex < indices[i])
|
||||
{
|
||||
maxIndex = indices[i];
|
||||
}
|
||||
nonPrimitiveRestartIndices++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
minIndex = indices[0];
|
||||
maxIndex = indices[0];
|
||||
nonPrimitiveRestartIndices = count;
|
||||
|
||||
for (size_t i = 1; i < count; i++)
|
||||
{
|
||||
if (minIndex > indices[i])
|
||||
{
|
||||
minIndex = indices[i];
|
||||
}
|
||||
if (maxIndex < indices[i])
|
||||
{
|
||||
maxIndex = indices[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
|
||||
nonPrimitiveRestartIndices);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
int VariableComponentCount(GLenum type)
|
||||
{
|
||||
return VariableRowCount(type) * VariableColumnCount(type);
|
||||
}
|
||||
|
||||
GLenum VariableComponentType(GLenum type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case GL_BOOL:
|
||||
case GL_BOOL_VEC2:
|
||||
case GL_BOOL_VEC3:
|
||||
case GL_BOOL_VEC4:
|
||||
return GL_BOOL;
|
||||
case GL_FLOAT:
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_FLOAT_VEC3:
|
||||
case GL_FLOAT_VEC4:
|
||||
case GL_FLOAT_MAT2:
|
||||
case GL_FLOAT_MAT3:
|
||||
case GL_FLOAT_MAT4:
|
||||
case GL_FLOAT_MAT2x3:
|
||||
case GL_FLOAT_MAT3x2:
|
||||
case GL_FLOAT_MAT2x4:
|
||||
case GL_FLOAT_MAT4x2:
|
||||
case GL_FLOAT_MAT3x4:
|
||||
case GL_FLOAT_MAT4x3:
|
||||
return GL_FLOAT;
|
||||
case GL_INT:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_INT_VEC2:
|
||||
case GL_INT_VEC3:
|
||||
case GL_INT_VEC4:
|
||||
case GL_IMAGE_2D:
|
||||
case GL_INT_IMAGE_2D:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D:
|
||||
case GL_IMAGE_3D:
|
||||
case GL_INT_IMAGE_3D:
|
||||
case GL_UNSIGNED_INT_IMAGE_3D:
|
||||
case GL_IMAGE_2D_ARRAY:
|
||||
case GL_INT_IMAGE_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
|
||||
case GL_IMAGE_CUBE:
|
||||
case GL_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_ATOMIC_COUNTER:
|
||||
return GL_INT;
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
return GL_UNSIGNED_INT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return GL_NONE;
|
||||
}
|
||||
|
||||
size_t VariableComponentSize(GLenum type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case GL_BOOL: return sizeof(GLint);
|
||||
case GL_FLOAT: return sizeof(GLfloat);
|
||||
case GL_INT: return sizeof(GLint);
|
||||
case GL_UNSIGNED_INT: return sizeof(GLuint);
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t VariableInternalSize(GLenum type)
|
||||
{
|
||||
// Expanded to 4-element vectors
|
||||
return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
|
||||
}
|
||||
|
||||
size_t VariableExternalSize(GLenum type)
|
||||
{
|
||||
return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
|
||||
}
|
||||
|
||||
GLenum VariableBoolVectorType(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
return GL_BOOL;
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_INT_VEC2:
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
return GL_BOOL_VEC2;
|
||||
case GL_FLOAT_VEC3:
|
||||
case GL_INT_VEC3:
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
return GL_BOOL_VEC3;
|
||||
case GL_FLOAT_VEC4:
|
||||
case GL_INT_VEC4:
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
return GL_BOOL_VEC4;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return GL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
int VariableRowCount(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_NONE:
|
||||
return 0;
|
||||
case GL_BOOL:
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_BOOL_VEC2:
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_INT_VEC2:
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
case GL_BOOL_VEC3:
|
||||
case GL_FLOAT_VEC3:
|
||||
case GL_INT_VEC3:
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
case GL_BOOL_VEC4:
|
||||
case GL_FLOAT_VEC4:
|
||||
case GL_INT_VEC4:
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_IMAGE_2D:
|
||||
case GL_INT_IMAGE_2D:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D:
|
||||
case GL_IMAGE_2D_ARRAY:
|
||||
case GL_INT_IMAGE_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
|
||||
case GL_IMAGE_3D:
|
||||
case GL_INT_IMAGE_3D:
|
||||
case GL_UNSIGNED_INT_IMAGE_3D:
|
||||
case GL_IMAGE_CUBE:
|
||||
case GL_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_ATOMIC_COUNTER:
|
||||
return 1;
|
||||
case GL_FLOAT_MAT2:
|
||||
case GL_FLOAT_MAT3x2:
|
||||
case GL_FLOAT_MAT4x2:
|
||||
return 2;
|
||||
case GL_FLOAT_MAT3:
|
||||
case GL_FLOAT_MAT2x3:
|
||||
case GL_FLOAT_MAT4x3:
|
||||
return 3;
|
||||
case GL_FLOAT_MAT4:
|
||||
case GL_FLOAT_MAT2x4:
|
||||
case GL_FLOAT_MAT3x4:
|
||||
return 4;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VariableColumnCount(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_NONE:
|
||||
return 0;
|
||||
case GL_BOOL:
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_IMAGE_2D:
|
||||
case GL_INT_IMAGE_2D:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D:
|
||||
case GL_IMAGE_3D:
|
||||
case GL_INT_IMAGE_3D:
|
||||
case GL_UNSIGNED_INT_IMAGE_3D:
|
||||
case GL_IMAGE_2D_ARRAY:
|
||||
case GL_INT_IMAGE_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
|
||||
case GL_IMAGE_CUBE:
|
||||
case GL_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_ATOMIC_COUNTER:
|
||||
return 1;
|
||||
case GL_BOOL_VEC2:
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_INT_VEC2:
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
case GL_FLOAT_MAT2:
|
||||
case GL_FLOAT_MAT2x3:
|
||||
case GL_FLOAT_MAT2x4:
|
||||
return 2;
|
||||
case GL_BOOL_VEC3:
|
||||
case GL_FLOAT_VEC3:
|
||||
case GL_INT_VEC3:
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
case GL_FLOAT_MAT3:
|
||||
case GL_FLOAT_MAT3x2:
|
||||
case GL_FLOAT_MAT3x4:
|
||||
return 3;
|
||||
case GL_BOOL_VEC4:
|
||||
case GL_FLOAT_VEC4:
|
||||
case GL_INT_VEC4:
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
case GL_FLOAT_MAT4:
|
||||
case GL_FLOAT_MAT4x2:
|
||||
case GL_FLOAT_MAT4x3:
|
||||
return 4;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsSamplerType(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsImageType(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_IMAGE_2D:
|
||||
case GL_INT_IMAGE_2D:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D:
|
||||
case GL_IMAGE_3D:
|
||||
case GL_INT_IMAGE_3D:
|
||||
case GL_UNSIGNED_INT_IMAGE_3D:
|
||||
case GL_IMAGE_2D_ARRAY:
|
||||
case GL_INT_IMAGE_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
|
||||
case GL_IMAGE_CUBE:
|
||||
case GL_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsAtomicCounterType(GLenum type)
|
||||
{
|
||||
return type == GL_UNSIGNED_INT_ATOMIC_COUNTER;
|
||||
}
|
||||
|
||||
bool IsOpaqueType(GLenum type)
|
||||
{
|
||||
// ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
|
||||
return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
|
||||
}
|
||||
|
||||
GLenum SamplerTypeToTextureType(GLenum samplerType)
|
||||
{
|
||||
switch (samplerType)
|
||||
{
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
return GL_TEXTURE_2D;
|
||||
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
return GL_TEXTURE_EXTERNAL_OES;
|
||||
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
return GL_TEXTURE_CUBE_MAP;
|
||||
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
return GL_TEXTURE_2D_ARRAY;
|
||||
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
return GL_TEXTURE_3D;
|
||||
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
return GL_TEXTURE_2D_MULTISAMPLE;
|
||||
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
return GL_TEXTURE_RECTANGLE_ANGLE;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsMatrixType(GLenum type)
|
||||
{
|
||||
return VariableRowCount(type) > 1;
|
||||
}
|
||||
|
||||
GLenum TransposeMatrixType(GLenum type)
|
||||
{
|
||||
if (!IsMatrixType(type))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
|
||||
case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
|
||||
case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
|
||||
case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
|
||||
case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
|
||||
case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
|
||||
case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
|
||||
case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
|
||||
case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
|
||||
default: UNREACHABLE(); return GL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
|
||||
{
|
||||
ASSERT(IsMatrixType(type));
|
||||
return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
|
||||
}
|
||||
|
||||
int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
|
||||
{
|
||||
ASSERT(IsMatrixType(type));
|
||||
return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
|
||||
}
|
||||
|
||||
int VariableRegisterCount(GLenum type)
|
||||
{
|
||||
return IsMatrixType(type) ? VariableColumnCount(type) : 1;
|
||||
}
|
||||
|
||||
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
|
||||
{
|
||||
ASSERT(allocationSize <= bitsSize);
|
||||
|
||||
unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
|
||||
|
||||
for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
|
||||
{
|
||||
if ((*bits & mask) == 0)
|
||||
{
|
||||
*bits |= mask;
|
||||
return i;
|
||||
}
|
||||
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
|
||||
static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
|
||||
|
||||
bool IsCubeMapTextureTarget(GLenum target)
|
||||
{
|
||||
return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
|
||||
}
|
||||
|
||||
size_t CubeMapTextureTargetToLayerIndex(GLenum target)
|
||||
{
|
||||
ASSERT(IsCubeMapTextureTarget(target));
|
||||
return target - static_cast<size_t>(FirstCubeMapTextureTarget);
|
||||
}
|
||||
|
||||
GLenum LayerIndexToCubeMapTextureTarget(size_t index)
|
||||
{
|
||||
ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
|
||||
return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
|
||||
}
|
||||
|
||||
IndexRange ComputeIndexRange(GLenum indexType,
|
||||
const GLvoid *indices,
|
||||
size_t count,
|
||||
bool primitiveRestartEnabled)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
case GL_UNSIGNED_BYTE:
|
||||
return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
|
||||
primitiveRestartEnabled,
|
||||
GetPrimitiveRestartIndex(indexType));
|
||||
case GL_UNSIGNED_SHORT:
|
||||
return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
|
||||
primitiveRestartEnabled,
|
||||
GetPrimitiveRestartIndex(indexType));
|
||||
case GL_UNSIGNED_INT:
|
||||
return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
|
||||
primitiveRestartEnabled,
|
||||
GetPrimitiveRestartIndex(indexType));
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return IndexRange();
|
||||
}
|
||||
}
|
||||
|
||||
GLuint GetPrimitiveRestartIndex(GLenum indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
case GL_UNSIGNED_BYTE:
|
||||
return 0xFF;
|
||||
case GL_UNSIGNED_SHORT:
|
||||
return 0xFFFF;
|
||||
case GL_UNSIGNED_INT:
|
||||
return 0xFFFFFFFF;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsTriangleMode(GLenum drawMode)
|
||||
{
|
||||
switch (drawMode)
|
||||
{
|
||||
case GL_TRIANGLES:
|
||||
case GL_TRIANGLE_FAN:
|
||||
case GL_TRIANGLE_STRIP:
|
||||
return true;
|
||||
case GL_POINTS:
|
||||
case GL_LINES:
|
||||
case GL_LINE_LOOP:
|
||||
case GL_LINE_STRIP:
|
||||
return false;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsIntegerFormat(GLenum unsizedFormat)
|
||||
{
|
||||
switch (unsizedFormat)
|
||||
{
|
||||
case GL_RGBA_INTEGER:
|
||||
case GL_RGB_INTEGER:
|
||||
case GL_RG_INTEGER:
|
||||
case GL_RED_INTEGER:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// [OpenGL ES SL 3.00.4] Section 11 p. 120
|
||||
// Vertex Outs/Fragment Ins packing priorities
|
||||
int VariableSortOrder(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
// 1. Arrays of mat4 and mat4
|
||||
// Non-square matrices of type matCxR consume the same space as a square
|
||||
// matrix of type matN where N is the greater of C and R
|
||||
case GL_FLOAT_MAT4:
|
||||
case GL_FLOAT_MAT2x4:
|
||||
case GL_FLOAT_MAT3x4:
|
||||
case GL_FLOAT_MAT4x2:
|
||||
case GL_FLOAT_MAT4x3:
|
||||
return 0;
|
||||
|
||||
// 2. Arrays of mat2 and mat2 (since they occupy full rows)
|
||||
case GL_FLOAT_MAT2:
|
||||
return 1;
|
||||
|
||||
// 3. Arrays of vec4 and vec4
|
||||
case GL_FLOAT_VEC4:
|
||||
case GL_INT_VEC4:
|
||||
case GL_BOOL_VEC4:
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
return 2;
|
||||
|
||||
// 4. Arrays of mat3 and mat3
|
||||
case GL_FLOAT_MAT3:
|
||||
case GL_FLOAT_MAT2x3:
|
||||
case GL_FLOAT_MAT3x2:
|
||||
return 3;
|
||||
|
||||
// 5. Arrays of vec3 and vec3
|
||||
case GL_FLOAT_VEC3:
|
||||
case GL_INT_VEC3:
|
||||
case GL_BOOL_VEC3:
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
return 4;
|
||||
|
||||
// 6. Arrays of vec2 and vec2
|
||||
case GL_FLOAT_VEC2:
|
||||
case GL_INT_VEC2:
|
||||
case GL_BOOL_VEC2:
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
return 5;
|
||||
|
||||
// 7. Single component types
|
||||
case GL_FLOAT:
|
||||
case GL_INT:
|
||||
case GL_BOOL:
|
||||
case GL_UNSIGNED_INT:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_CUBE:
|
||||
case GL_SAMPLER_EXTERNAL_OES:
|
||||
case GL_SAMPLER_2D_RECT_ANGLE:
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
case GL_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_2D:
|
||||
case GL_INT_SAMPLER_3D:
|
||||
case GL_INT_SAMPLER_CUBE:
|
||||
case GL_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_3D:
|
||||
case GL_UNSIGNED_INT_SAMPLER_CUBE:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
|
||||
case GL_SAMPLER_2D_SHADOW:
|
||||
case GL_SAMPLER_2D_ARRAY_SHADOW:
|
||||
case GL_SAMPLER_CUBE_SHADOW:
|
||||
case GL_IMAGE_2D:
|
||||
case GL_INT_IMAGE_2D:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D:
|
||||
case GL_IMAGE_3D:
|
||||
case GL_INT_IMAGE_3D:
|
||||
case GL_UNSIGNED_INT_IMAGE_3D:
|
||||
case GL_IMAGE_2D_ARRAY:
|
||||
case GL_INT_IMAGE_2D_ARRAY:
|
||||
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
|
||||
case GL_IMAGE_CUBE:
|
||||
case GL_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_IMAGE_CUBE:
|
||||
case GL_UNSIGNED_INT_ATOMIC_COUNTER:
|
||||
return 6;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ParseResourceName(const std::string &name, size_t *outSubscript)
|
||||
{
|
||||
// Strip any trailing array operator and retrieve the subscript
|
||||
size_t open = name.find_last_of('[');
|
||||
size_t close = name.find_last_of(']');
|
||||
bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
|
||||
if (!hasIndex)
|
||||
{
|
||||
if (outSubscript)
|
||||
{
|
||||
*outSubscript = GL_INVALID_INDEX;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
if (outSubscript)
|
||||
{
|
||||
int index = atoi(name.substr(open + 1).c_str());
|
||||
if (index >= 0)
|
||||
{
|
||||
*outSubscript = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
*outSubscript = GL_INVALID_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
return name.substr(0, open);
|
||||
}
|
||||
|
||||
template <>
|
||||
GLuint ConvertToGLuint(GLfloat param)
|
||||
{
|
||||
return uiround<GLuint>(param);
|
||||
}
|
||||
|
||||
template <>
|
||||
GLint ConvertToGLint(uint32_t param)
|
||||
{
|
||||
uint32_t max = static_cast<uint32_t>(std::numeric_limits<GLint>::max());
|
||||
return static_cast<GLint>(param >= max ? max : param);
|
||||
}
|
||||
|
||||
template <>
|
||||
GLint ConvertToGLint(uint64_t param)
|
||||
{
|
||||
uint64_t max = static_cast<uint64_t>(std::numeric_limits<GLint>::max());
|
||||
return static_cast<GLint>(param >= max ? max : param);
|
||||
}
|
||||
|
||||
template <>
|
||||
GLint ConvertToGLint(GLfloat param)
|
||||
{
|
||||
return iround<GLint>(param);
|
||||
}
|
||||
|
||||
template <>
|
||||
GLint ConvertFromGLfloat(GLfloat param)
|
||||
{
|
||||
return iround<GLint>(param);
|
||||
}
|
||||
template <>
|
||||
GLuint ConvertFromGLfloat(GLfloat param)
|
||||
{
|
||||
return uiround<GLuint>(param);
|
||||
}
|
||||
|
||||
unsigned int ParseAndStripArrayIndex(std::string *name)
|
||||
{
|
||||
unsigned int subscript = GL_INVALID_INDEX;
|
||||
|
||||
// Strip any trailing array operator and retrieve the subscript
|
||||
size_t open = name->find_last_of('[');
|
||||
size_t close = name->find_last_of(']');
|
||||
if (open != std::string::npos && close == name->length() - 1)
|
||||
{
|
||||
subscript = atoi(name->c_str() + open + 1);
|
||||
name->erase(open);
|
||||
}
|
||||
|
||||
return subscript;
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
||||
namespace egl
|
||||
{
|
||||
static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
|
||||
"Unexpected EGL cube map enum value.");
|
||||
static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
|
||||
"Unexpected EGL cube map enum value.");
|
||||
static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
|
||||
"Unexpected EGL cube map enum value.");
|
||||
static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
|
||||
"Unexpected EGL cube map enum value.");
|
||||
static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
|
||||
"Unexpected EGL cube map enum value.");
|
||||
|
||||
bool IsCubeMapTextureTarget(EGLenum target)
|
||||
{
|
||||
return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
|
||||
}
|
||||
|
||||
size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
|
||||
{
|
||||
ASSERT(IsCubeMapTextureTarget(target));
|
||||
return target - static_cast<size_t>(FirstCubeMapTextureTarget);
|
||||
}
|
||||
|
||||
EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
|
||||
{
|
||||
ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
|
||||
return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
|
||||
}
|
||||
|
||||
bool IsTextureTarget(EGLenum target)
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case EGL_GL_TEXTURE_2D_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
|
||||
case EGL_GL_TEXTURE_3D_KHR:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsRenderbufferTarget(EGLenum target)
|
||||
{
|
||||
return target == EGL_GL_RENDERBUFFER_KHR;
|
||||
}
|
||||
} // namespace egl
|
||||
|
||||
namespace egl_gl
|
||||
{
|
||||
GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
|
||||
{
|
||||
ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
|
||||
return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
|
||||
}
|
||||
|
||||
GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
|
||||
{
|
||||
switch (eglTarget)
|
||||
{
|
||||
case EGL_GL_TEXTURE_2D_KHR:
|
||||
return GL_TEXTURE_2D;
|
||||
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
|
||||
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
|
||||
return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
|
||||
|
||||
case EGL_GL_TEXTURE_3D_KHR:
|
||||
return GL_TEXTURE_3D;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return GL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
|
||||
{
|
||||
return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
|
||||
}
|
||||
} // namespace egl_gl
|
||||
|
||||
namespace gl_egl
|
||||
{
|
||||
EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
|
||||
{
|
||||
switch (glComponentType)
|
||||
{
|
||||
case GL_FLOAT:
|
||||
return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
|
||||
|
||||
case GL_UNSIGNED_NORMALIZED:
|
||||
return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return EGL_NONE;
|
||||
}
|
||||
}
|
||||
} // namespace gl_egl
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::string getTempPath()
|
||||
{
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
char path[MAX_PATH];
|
||||
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
|
||||
if (pathLen == 0)
|
||||
{
|
||||
UNREACHABLE();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
UINT unique = GetTempFileNameA(path, "sh", 0, path);
|
||||
if (unique == 0)
|
||||
{
|
||||
UNREACHABLE();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return path;
|
||||
#else
|
||||
UNIMPLEMENTED();
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
void writeFile(const char* path, const void* content, size_t size)
|
||||
{
|
||||
FILE* file = fopen(path, "w");
|
||||
if (!file)
|
||||
{
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(content, sizeof(char), size, file);
|
||||
fclose(file);
|
||||
}
|
||||
#endif // !ANGLE_ENABLE_WINDOWS_STORE
|
||||
|
||||
#if defined (ANGLE_PLATFORM_WINDOWS)
|
||||
|
||||
// Causes the thread to relinquish the remainder of its time slice to any
|
||||
// other thread that is ready to run.If there are no other threads ready
|
||||
// to run, the function returns immediately, and the thread continues execution.
|
||||
void ScheduleYield()
|
||||
{
|
||||
Sleep(0);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,245 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2002-2013 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.
|
||||
//
|
||||
|
||||
// utilities.h: Conversion functions and other utility routines.
|
||||
|
||||
#ifndef COMMON_UTILITIES_H_
|
||||
#define COMMON_UTILITIES_H_
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include <string>
|
||||
#include <math.h>
|
||||
|
||||
#include "common/mathutil.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
int VariableComponentCount(GLenum type);
|
||||
GLenum VariableComponentType(GLenum type);
|
||||
size_t VariableComponentSize(GLenum type);
|
||||
size_t VariableInternalSize(GLenum type);
|
||||
size_t VariableExternalSize(GLenum type);
|
||||
int VariableRowCount(GLenum type);
|
||||
int VariableColumnCount(GLenum type);
|
||||
bool IsSamplerType(GLenum type);
|
||||
bool IsImageType(GLenum type);
|
||||
bool IsAtomicCounterType(GLenum type);
|
||||
bool IsOpaqueType(GLenum type);
|
||||
GLenum SamplerTypeToTextureType(GLenum samplerType);
|
||||
bool IsMatrixType(GLenum type);
|
||||
GLenum TransposeMatrixType(GLenum type);
|
||||
int VariableRegisterCount(GLenum type);
|
||||
int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix);
|
||||
int MatrixComponentCount(GLenum type, bool isRowMajorMatrix);
|
||||
int VariableSortOrder(GLenum type);
|
||||
GLenum VariableBoolVectorType(GLenum type);
|
||||
|
||||
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
|
||||
|
||||
static const GLenum FirstCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
static const GLenum LastCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
|
||||
bool IsCubeMapTextureTarget(GLenum target);
|
||||
size_t CubeMapTextureTargetToLayerIndex(GLenum target);
|
||||
GLenum LayerIndexToCubeMapTextureTarget(size_t index);
|
||||
|
||||
// Parse the base resource name and array index. Returns the base name of the resource.
|
||||
// outSubscript is set to GL_INVALID_INDEX if the provided name is not an array or the array index
|
||||
// is invalid.
|
||||
std::string ParseResourceName(const std::string &name, size_t *outSubscript);
|
||||
|
||||
// Find the range of index values in the provided indices pointer. Primitive restart indices are
|
||||
// only counted in the range if primitive restart is disabled.
|
||||
IndexRange ComputeIndexRange(GLenum indexType,
|
||||
const GLvoid *indices,
|
||||
size_t count,
|
||||
bool primitiveRestartEnabled);
|
||||
|
||||
// Get the primitive restart index value for the given index type.
|
||||
GLuint GetPrimitiveRestartIndex(GLenum indexType);
|
||||
|
||||
bool IsTriangleMode(GLenum drawMode);
|
||||
bool IsIntegerFormat(GLenum unsizedFormat);
|
||||
|
||||
// [OpenGL ES 3.0.2] Section 2.3.1 page 14
|
||||
// Data Conversion For State-Setting Commands
|
||||
// Floating-point values are rounded to the nearest integer, instead of truncated, as done by static_cast.
|
||||
template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
|
||||
template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
|
||||
|
||||
// Helper for converting arbitrary GL types to other GL types used in queries and state setting
|
||||
|
||||
// TODO(jie.a.chen@intel.com): Add the conversion rule for all helpers as the spec requires:
|
||||
// "If a value is so large in magnitude that it cannot be represented with the requested type,"
|
||||
// "then the nearest value representable using the requested type is returned."
|
||||
|
||||
template <typename ParamType>
|
||||
GLuint ConvertToGLuint(ParamType param)
|
||||
{
|
||||
return static_cast<GLuint>(param);
|
||||
}
|
||||
template <>
|
||||
GLuint ConvertToGLuint(GLfloat param);
|
||||
|
||||
template <typename ParamType>
|
||||
GLint ConvertToGLint(ParamType param)
|
||||
{
|
||||
return static_cast<GLint>(param);
|
||||
}
|
||||
|
||||
template <>
|
||||
GLint ConvertToGLint(uint32_t param);
|
||||
|
||||
template <>
|
||||
GLint ConvertToGLint(uint64_t param);
|
||||
|
||||
template <>
|
||||
GLint ConvertToGLint(GLfloat param);
|
||||
|
||||
// Same conversion as uint
|
||||
template <typename ParamType>
|
||||
GLenum ConvertToGLenum(ParamType param)
|
||||
{
|
||||
return static_cast<GLenum>(ConvertToGLuint(param));
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
GLfloat ConvertToGLfloat(ParamType param)
|
||||
{
|
||||
return static_cast<GLfloat>(param);
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
ParamType ConvertFromGLfloat(GLfloat param)
|
||||
{
|
||||
return static_cast<ParamType>(param);
|
||||
}
|
||||
template <>
|
||||
GLint ConvertFromGLfloat(GLfloat param);
|
||||
template <>
|
||||
GLuint ConvertFromGLfloat(GLfloat param);
|
||||
|
||||
template <typename ParamType>
|
||||
ParamType ConvertFromGLenum(GLenum param)
|
||||
{
|
||||
return static_cast<ParamType>(param);
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
ParamType ConvertFromGLuint(GLuint param)
|
||||
{
|
||||
return static_cast<ParamType>(param);
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
ParamType ConvertFromGLint(GLint param)
|
||||
{
|
||||
return static_cast<ParamType>(param);
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
ParamType ConvertFromGLboolean(GLboolean param)
|
||||
{
|
||||
return static_cast<ParamType>(param ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
template <typename ParamType>
|
||||
ParamType ConvertFromGLint64(GLint64 param)
|
||||
{
|
||||
return clampCast<ParamType>(param);
|
||||
}
|
||||
|
||||
unsigned int ParseAndStripArrayIndex(std::string *name);
|
||||
|
||||
struct UniformTypeInfo final : angle::NonCopyable
|
||||
{
|
||||
constexpr UniformTypeInfo(GLenum type,
|
||||
GLenum componentType,
|
||||
GLenum samplerTextureType,
|
||||
GLenum transposedMatrixType,
|
||||
GLenum boolVectorType,
|
||||
int rowCount,
|
||||
int columnCount,
|
||||
int componentCount,
|
||||
size_t componentSize,
|
||||
size_t internalSize,
|
||||
size_t externalSize,
|
||||
bool isSampler,
|
||||
bool isMatrixType,
|
||||
bool isImageType)
|
||||
: type(type),
|
||||
componentType(componentType),
|
||||
samplerTextureType(samplerTextureType),
|
||||
transposedMatrixType(transposedMatrixType),
|
||||
boolVectorType(boolVectorType),
|
||||
rowCount(rowCount),
|
||||
columnCount(columnCount),
|
||||
componentCount(componentCount),
|
||||
componentSize(componentSize),
|
||||
internalSize(internalSize),
|
||||
externalSize(externalSize),
|
||||
isSampler(isSampler),
|
||||
isMatrixType(isMatrixType),
|
||||
isImageType(isImageType)
|
||||
{
|
||||
}
|
||||
|
||||
GLenum type;
|
||||
GLenum componentType;
|
||||
GLenum samplerTextureType;
|
||||
GLenum transposedMatrixType;
|
||||
GLenum boolVectorType;
|
||||
int rowCount;
|
||||
int columnCount;
|
||||
int componentCount;
|
||||
size_t componentSize;
|
||||
size_t internalSize;
|
||||
size_t externalSize;
|
||||
bool isSampler;
|
||||
bool isMatrixType;
|
||||
bool isImageType;
|
||||
};
|
||||
|
||||
const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType);
|
||||
|
||||
} // namespace gl
|
||||
|
||||
namespace egl
|
||||
{
|
||||
static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
|
||||
static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
|
||||
bool IsCubeMapTextureTarget(EGLenum target);
|
||||
size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
|
||||
EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
|
||||
bool IsTextureTarget(EGLenum target);
|
||||
bool IsRenderbufferTarget(EGLenum target);
|
||||
}
|
||||
|
||||
namespace egl_gl
|
||||
{
|
||||
GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget);
|
||||
GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget);
|
||||
GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
|
||||
}
|
||||
|
||||
namespace gl_egl
|
||||
{
|
||||
EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
|
||||
} // namespace gl_egl
|
||||
|
||||
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
|
||||
std::string getTempPath();
|
||||
void writeFile(const char* path, const void* data, size_t size);
|
||||
#endif
|
||||
|
||||
#if defined (ANGLE_PLATFORM_WINDOWS)
|
||||
void ScheduleYield();
|
||||
#endif
|
||||
|
||||
#endif // COMMON_UTILITIES_H_
|
|
@ -1,55 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2015 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.
|
||||
|
||||
// utilities_unittest.cpp: Unit tests for ANGLE's GL utility functions
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "common/utilities.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST(ParseResourceName, ArrayIndex)
|
||||
{
|
||||
size_t index;
|
||||
EXPECT_EQ("foo", gl::ParseResourceName("foo[123]", &index));
|
||||
EXPECT_EQ(123u, index);
|
||||
|
||||
EXPECT_EQ("bar", gl::ParseResourceName("bar[0]", &index));
|
||||
EXPECT_EQ(0u, index);
|
||||
}
|
||||
|
||||
TEST(ParseResourceName, NegativeArrayIndex)
|
||||
{
|
||||
size_t index;
|
||||
EXPECT_EQ("foo", gl::ParseResourceName("foo[-1]", &index));
|
||||
EXPECT_EQ(GL_INVALID_INDEX, index);
|
||||
}
|
||||
|
||||
TEST(ParseResourceName, NoArrayIndex)
|
||||
{
|
||||
size_t index;
|
||||
EXPECT_EQ("foo", gl::ParseResourceName("foo", &index));
|
||||
EXPECT_EQ(GL_INVALID_INDEX, index);
|
||||
}
|
||||
|
||||
TEST(ParseResourceName, NULLArrayIndex)
|
||||
{
|
||||
EXPECT_EQ("foo", gl::ParseResourceName("foo[10]", nullptr));
|
||||
}
|
||||
|
||||
TEST(ParseResourceName, TrailingWhitespace)
|
||||
{
|
||||
size_t index;
|
||||
EXPECT_EQ("foo ", gl::ParseResourceName("foo ", &index));
|
||||
EXPECT_EQ(GL_INVALID_INDEX, index);
|
||||
|
||||
EXPECT_EQ("foo[10] ", gl::ParseResourceName("foo[10] ", &index));
|
||||
EXPECT_EQ(GL_INVALID_INDEX, index);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,523 +0,0 @@
|
|||
//
|
||||
// Copyright 2016 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.
|
||||
//
|
||||
// vector_utils.h: Utility classes implementing various vector operations
|
||||
|
||||
#ifndef COMMON_VECTOR_UTILS_H_
|
||||
#define COMMON_VECTOR_UTILS_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
class Vector;
|
||||
|
||||
using Vector2 = Vector<2, float>;
|
||||
using Vector3 = Vector<3, float>;
|
||||
using Vector4 = Vector<4, float>;
|
||||
|
||||
using Vector2I = Vector<2, int>;
|
||||
using Vector3I = Vector<3, int>;
|
||||
using Vector4I = Vector<4, int>;
|
||||
|
||||
using Vector2U = Vector<2, unsigned int>;
|
||||
using Vector3U = Vector<3, unsigned int>;
|
||||
using Vector4U = Vector<4, unsigned int>;
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
class VectorBase
|
||||
{
|
||||
public:
|
||||
using VectorN = Vector<Dimension, Type>;
|
||||
|
||||
// Constructors
|
||||
VectorBase() = default;
|
||||
explicit VectorBase(Type element);
|
||||
|
||||
template <typename Type2>
|
||||
VectorBase(const VectorBase<Dimension, Type2> &other);
|
||||
|
||||
template <typename Arg1, typename Arg2, typename... Args>
|
||||
VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &... args);
|
||||
|
||||
// Access the vector backing storage directly
|
||||
const Type *data() const { return mData; }
|
||||
Type *data() { return mData; }
|
||||
constexpr size_t size() const { return Dimension; }
|
||||
|
||||
// Load or store the pointer from / to raw data
|
||||
static VectorN Load(const Type *source);
|
||||
static void Store(const VectorN &source, Type *destination);
|
||||
|
||||
// Index the vector
|
||||
Type &operator[](size_t i) { return mData[i]; }
|
||||
const Type &operator[](size_t i) const { return mData[i]; }
|
||||
|
||||
// Basic arithmetic operations
|
||||
VectorN operator+() const;
|
||||
VectorN operator-() const;
|
||||
VectorN operator+(const VectorN &other) const;
|
||||
VectorN operator-(const VectorN &other) const;
|
||||
VectorN operator*(const VectorN &other) const;
|
||||
VectorN operator/(const VectorN &other) const;
|
||||
VectorN operator*(Type other) const;
|
||||
VectorN operator/(Type other) const;
|
||||
friend VectorN operator*(Type a, const VectorN &b) { return b * a; }
|
||||
|
||||
// Compound arithmetic operations
|
||||
VectorN &operator+=(const VectorN &other);
|
||||
VectorN &operator-=(const VectorN &other);
|
||||
VectorN &operator*=(const VectorN &other);
|
||||
VectorN &operator/=(const VectorN &other);
|
||||
VectorN &operator*=(Type other);
|
||||
VectorN &operator/=(Type other);
|
||||
|
||||
// Comparison operators
|
||||
bool operator==(const VectorN &other) const;
|
||||
bool operator!=(const VectorN &other) const;
|
||||
|
||||
// Other arithmetic operations
|
||||
Type length() const;
|
||||
Type lengthSquared() const;
|
||||
Type dot(const VectorBase<Dimension, Type> &other) const;
|
||||
VectorN normalized() const;
|
||||
|
||||
protected:
|
||||
template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
|
||||
void initWithList(const Vector<OtherDimension, OtherType> &arg1, const Args &... args);
|
||||
|
||||
// Some old compilers consider this function an alternative for initWithList(Vector)
|
||||
// when the variant above is more precise. Use SFINAE on the return value to hide
|
||||
// this variant for non-arithmetic types. The return value is still void.
|
||||
template <size_t CurrentIndex, typename OtherType, typename... Args>
|
||||
typename std::enable_if<std::is_arithmetic<OtherType>::value>::type initWithList(
|
||||
OtherType arg1,
|
||||
const Args &... args);
|
||||
|
||||
template <size_t CurrentIndex>
|
||||
void initWithList() const;
|
||||
|
||||
template <size_t Dimension2, typename Type2>
|
||||
friend class VectorBase;
|
||||
|
||||
Type mData[Dimension];
|
||||
};
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector);
|
||||
|
||||
template <typename Type>
|
||||
class Vector<2, Type> : public VectorBase<2, Type>
|
||||
{
|
||||
public:
|
||||
// Import the constructors defined in VectorBase
|
||||
using VectorBase<2, Type>::VectorBase;
|
||||
|
||||
// Element shorthands
|
||||
Type &x() { return this->mData[0]; }
|
||||
Type &y() { return this->mData[1]; }
|
||||
|
||||
const Type &x() const { return this->mData[0]; }
|
||||
const Type &y() const { return this->mData[1]; }
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector);
|
||||
|
||||
template <typename Type>
|
||||
class Vector<3, Type> : public VectorBase<3, Type>
|
||||
{
|
||||
public:
|
||||
// Import the constructors defined in VectorBase
|
||||
using VectorBase<3, Type>::VectorBase;
|
||||
|
||||
// Additional operations
|
||||
Vector<3, Type> cross(const Vector<3, Type> &other) const;
|
||||
|
||||
// Element shorthands
|
||||
Type &x() { return this->mData[0]; }
|
||||
Type &y() { return this->mData[1]; }
|
||||
Type &z() { return this->mData[2]; }
|
||||
|
||||
const Type &x() const { return this->mData[0]; }
|
||||
const Type &y() const { return this->mData[1]; }
|
||||
const Type &z() const { return this->mData[2]; }
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector);
|
||||
|
||||
template <typename Type>
|
||||
class Vector<4, Type> : public VectorBase<4, Type>
|
||||
{
|
||||
public:
|
||||
// Import the constructors defined in VectorBase
|
||||
using VectorBase<4, Type>::VectorBase;
|
||||
|
||||
// Element shorthands
|
||||
Type &x() { return this->mData[0]; }
|
||||
Type &y() { return this->mData[1]; }
|
||||
Type &z() { return this->mData[2]; }
|
||||
Type &w() { return this->mData[3]; }
|
||||
|
||||
const Type &x() const { return this->mData[0]; }
|
||||
const Type &y() const { return this->mData[1]; }
|
||||
const Type &z() const { return this->mData[2]; }
|
||||
const Type &w() const { return this->mData[3]; }
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector);
|
||||
|
||||
// Implementation of constructors and misc operations
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
VectorBase<Dimension, Type>::VectorBase(Type element)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] = element;
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
template <typename Type2>
|
||||
VectorBase<Dimension, Type>::VectorBase(const VectorBase<Dimension, Type2> &other)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] = static_cast<Type>(other.mData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Ideally we would like to have only two constructors:
|
||||
// - a scalar constructor that takes Type as a parameter
|
||||
// - a compound constructor
|
||||
// However if we define the compound constructor for when it has a single arguments, then calling
|
||||
// Vector2(0.0) will be ambiguous. To solve this we take advantage of there being a single compound
|
||||
// constructor with a single argument, which is the copy constructor. We end up with three
|
||||
// constructors:
|
||||
// - the scalar constructor
|
||||
// - the copy constructor
|
||||
// - the compound constructor for two or more arguments, hence the arg1, and arg2 here.
|
||||
template <size_t Dimension, typename Type>
|
||||
template <typename Arg1, typename Arg2, typename... Args>
|
||||
VectorBase<Dimension, Type>::VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &... args)
|
||||
{
|
||||
initWithList<0>(arg1, arg2, args...);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
|
||||
void VectorBase<Dimension, Type>::initWithList(const Vector<OtherDimension, OtherType> &arg1,
|
||||
const Args &... args)
|
||||
{
|
||||
static_assert(CurrentIndex + OtherDimension <= Dimension,
|
||||
"Too much data in the vector constructor.");
|
||||
for (size_t i = 0; i < OtherDimension; ++i)
|
||||
{
|
||||
mData[CurrentIndex + i] = static_cast<Type>(arg1.mData[i]);
|
||||
}
|
||||
initWithList<CurrentIndex + OtherDimension>(args...);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
template <size_t CurrentIndex, typename OtherType, typename... Args>
|
||||
typename std::enable_if<std::is_arithmetic<OtherType>::value>::type
|
||||
VectorBase<Dimension, Type>::initWithList(OtherType arg1, const Args &... args)
|
||||
{
|
||||
static_assert(CurrentIndex + 1 <= Dimension, "Too much data in the vector constructor.");
|
||||
mData[CurrentIndex] = static_cast<Type>(arg1);
|
||||
initWithList<CurrentIndex + 1>(args...);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
template <size_t CurrentIndex>
|
||||
void VectorBase<Dimension, Type>::initWithList() const
|
||||
{
|
||||
static_assert(CurrentIndex == Dimension, "Not enough data in the vector constructor.");
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::Load(const Type *source)
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = source[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
void VectorBase<Dimension, Type>::Store(const Vector<Dimension, Type> &source, Type *destination)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
destination[i] = source.mData[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of basic arithmetic operations
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+() const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = +mData[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-() const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = -mData[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+(
|
||||
const Vector<Dimension, Type> &other) const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = mData[i] + other.mData[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-(
|
||||
const Vector<Dimension, Type> &other) const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = mData[i] - other.mData[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(
|
||||
const Vector<Dimension, Type> &other) const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = mData[i] * other.mData[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(
|
||||
const Vector<Dimension, Type> &other) const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = mData[i] / other.mData[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(Type other) const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = mData[i] * other;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(Type other) const
|
||||
{
|
||||
Vector<Dimension, Type> result;
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
result.mData[i] = mData[i] / other;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implementation of compound arithmetic operations
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator+=(
|
||||
const Vector<Dimension, Type> &other)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] += other.mData[i];
|
||||
}
|
||||
return *reinterpret_cast<Vector<Dimension, Type> *>(this);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator-=(
|
||||
const Vector<Dimension, Type> &other)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] -= other.mData[i];
|
||||
}
|
||||
return *reinterpret_cast<Vector<Dimension, Type> *>(this);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(
|
||||
const Vector<Dimension, Type> &other)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] *= other.mData[i];
|
||||
}
|
||||
return *reinterpret_cast<Vector<Dimension, Type> *>(this);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(
|
||||
const Vector<Dimension, Type> &other)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] /= other.mData[i];
|
||||
}
|
||||
return *reinterpret_cast<Vector<Dimension, Type> *>(this);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(Type other)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] *= other;
|
||||
}
|
||||
return *reinterpret_cast<Vector<Dimension, Type> *>(this);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(Type other)
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
mData[i] /= other;
|
||||
}
|
||||
return *reinterpret_cast<Vector<Dimension, Type> *>(this);
|
||||
}
|
||||
|
||||
// Implementation of comparison operators
|
||||
template <size_t Dimension, typename Type>
|
||||
bool VectorBase<Dimension, Type>::operator==(const Vector<Dimension, Type> &other) const
|
||||
{
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
if (mData[i] != other.mData[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
bool VectorBase<Dimension, Type>::operator!=(const Vector<Dimension, Type> &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
// Implementation of other arithmetic operations
|
||||
template <size_t Dimension, typename Type>
|
||||
Type VectorBase<Dimension, Type>::length() const
|
||||
{
|
||||
static_assert(std::is_floating_point<Type>::value,
|
||||
"VectorN::length is only defined for floating point vectors");
|
||||
return std::sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Type VectorBase<Dimension, Type>::lengthSquared() const
|
||||
{
|
||||
return dot(*this);
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Type VectorBase<Dimension, Type>::dot(const VectorBase<Dimension, Type> &other) const
|
||||
{
|
||||
Type sum = Type();
|
||||
for (size_t i = 0; i < Dimension; ++i)
|
||||
{
|
||||
sum += mData[i] * other.mData[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector)
|
||||
{
|
||||
ostream << "[ ";
|
||||
for (size_t elementIdx = 0; elementIdx < Dimension; elementIdx++)
|
||||
{
|
||||
if (elementIdx > 0)
|
||||
{
|
||||
ostream << ", ";
|
||||
}
|
||||
ostream << vector.data()[elementIdx];
|
||||
}
|
||||
ostream << " ]";
|
||||
return ostream;
|
||||
}
|
||||
|
||||
template <size_t Dimension, typename Type>
|
||||
Vector<Dimension, Type> VectorBase<Dimension, Type>::normalized() const
|
||||
{
|
||||
static_assert(std::is_floating_point<Type>::value,
|
||||
"VectorN::normalized is only defined for floating point vectors");
|
||||
return *this / length();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector)
|
||||
{
|
||||
return ostream << static_cast<const VectorBase<2, Type> &>(vector);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
Vector<3, Type> Vector<3, Type>::cross(const Vector<3, Type> &other) const
|
||||
{
|
||||
return Vector<3, Type>(y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(),
|
||||
x() * other.y() - y() * other.x());
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector)
|
||||
{
|
||||
return ostream << static_cast<const VectorBase<3, Type> &>(vector);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector)
|
||||
{
|
||||
return ostream << static_cast<const VectorBase<4, Type> &>(vector);
|
||||
}
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // COMMON_VECTOR_UTILS_H_
|
|
@ -1,225 +0,0 @@
|
|||
//
|
||||
// Copyright 2016 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.
|
||||
//
|
||||
// vector_utils_unittests.cpp: Unit tests for the vector utils.
|
||||
//
|
||||
|
||||
#include "vector_utils.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace angle;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// First test that comparing vectors work
|
||||
TEST(VectorUtilsTest, Comparison)
|
||||
{
|
||||
// Don't use ASSERT_EQ at first because the == is more hidden
|
||||
ASSERT_TRUE(Vector2(2.0, 3.0) == Vector2(2.0, 3.0));
|
||||
ASSERT_TRUE(Vector2(2.0, 3.0) != Vector2(2.0, 4.0));
|
||||
|
||||
// Check ASSERT_EQ and ASSERT_NE work correctly
|
||||
ASSERT_EQ(Vector2(2.0, 3.0), Vector2(2.0, 3.0));
|
||||
ASSERT_NE(Vector2(2.0, 3.0), Vector2(2.0, 4.0));
|
||||
|
||||
// Check comparison works on all elements
|
||||
ASSERT_EQ(Vector4(0.0), Vector4(0.0));
|
||||
ASSERT_NE(Vector4(1.0, 0.0, 0.0, 0.0), Vector4(0.0));
|
||||
ASSERT_NE(Vector4(0.0, 1.0, 0.0, 0.0), Vector4(0.0));
|
||||
ASSERT_NE(Vector4(0.0, 0.0, 1.0, 0.0), Vector4(0.0));
|
||||
ASSERT_NE(Vector4(0.0, 0.0, 0.0, 1.0), Vector4(0.0));
|
||||
}
|
||||
|
||||
// Test indexing
|
||||
TEST(VectorUtilsTest, Indexing)
|
||||
{
|
||||
Vector2 vec(1.0, 2.0);
|
||||
ASSERT_EQ(1.0, vec[0]);
|
||||
ASSERT_EQ(2.0, vec[1]);
|
||||
|
||||
vec[0] = 3.0;
|
||||
vec[1] = 4.0;
|
||||
ASSERT_EQ(Vector2(3.0, 4.0), vec);
|
||||
}
|
||||
|
||||
// Test for the various constructors
|
||||
TEST(VectorUtilsTest, Constructors)
|
||||
{
|
||||
// Constructor initializing all to a single element
|
||||
{
|
||||
Vector2 vec(3.0);
|
||||
ASSERT_EQ(3.0, vec[0]);
|
||||
ASSERT_EQ(3.0, vec[1]);
|
||||
}
|
||||
|
||||
// Constructor initializing from another Vector
|
||||
{
|
||||
Vector2 vec(Vector2(1.0, 2.0));
|
||||
ASSERT_EQ(1.0, vec[0]);
|
||||
ASSERT_EQ(2.0, vec[1]);
|
||||
}
|
||||
|
||||
// Mixed constructor
|
||||
{
|
||||
Vector4 vec(1.0, Vector2(2.0, 3.0), 4.0);
|
||||
ASSERT_EQ(1.0, vec[0]);
|
||||
ASSERT_EQ(2.0, vec[1]);
|
||||
ASSERT_EQ(3.0, vec[2]);
|
||||
ASSERT_EQ(4.0, vec[3]);
|
||||
}
|
||||
}
|
||||
|
||||
// Test accessing the data directly
|
||||
TEST(VectorUtilsTest, DataAccess)
|
||||
{
|
||||
Vector2 vec(1.0, 2.0);
|
||||
ASSERT_EQ(2u, vec.size());
|
||||
|
||||
ASSERT_EQ(1.0, vec.data()[0]);
|
||||
ASSERT_EQ(2.0, vec.data()[1]);
|
||||
|
||||
vec.data()[0] = 3.0;
|
||||
vec.data()[1] = 4.0;
|
||||
|
||||
ASSERT_EQ(Vector2(3.0, 4.0), vec);
|
||||
}
|
||||
|
||||
// Test accessing the data directly
|
||||
TEST(VectorUtilsTest, LoadStore)
|
||||
{
|
||||
float data[] = {1.0, 2.0};
|
||||
|
||||
Vector2 vec = Vector2::Load(data);
|
||||
|
||||
ASSERT_EQ(1.0, vec.data()[0]);
|
||||
ASSERT_EQ(2.0, vec.data()[1]);
|
||||
|
||||
vec = Vector2(3.0, 4.0);
|
||||
Vector2::Store(vec, data);
|
||||
|
||||
ASSERT_EQ(3.0, data[0]);
|
||||
ASSERT_EQ(4.0, data[1]);
|
||||
}
|
||||
|
||||
// Test basic arithmetic operations
|
||||
TEST(VectorUtilsTest, BasicArithmetic)
|
||||
{
|
||||
ASSERT_EQ(Vector2(2.0, 3.0), +Vector2(2.0, 3.0));
|
||||
ASSERT_EQ(Vector2(-2.0, -3.0), -Vector2(2.0, 3.0));
|
||||
ASSERT_EQ(Vector2(4.0, 6.0), Vector2(1.0, 2.0) + Vector2(3.0, 4.0));
|
||||
ASSERT_EQ(Vector2(-2.0, -2.0), Vector2(1.0, 2.0) - Vector2(3.0, 4.0));
|
||||
ASSERT_EQ(Vector2(3.0, 8.0), Vector2(1.0, 2.0) * Vector2(3.0, 4.0));
|
||||
ASSERT_EQ(Vector2(3.0, 2.0), Vector2(3.0, 4.0) / Vector2(1.0, 2.0));
|
||||
|
||||
ASSERT_EQ(Vector2(2.0, 4.0), Vector2(1.0, 2.0) * 2);
|
||||
ASSERT_EQ(Vector2(2.0, 4.0), 2 * Vector2(1.0, 2.0));
|
||||
ASSERT_EQ(Vector2(0.5, 1.0), Vector2(1.0, 2.0) / 2);
|
||||
}
|
||||
|
||||
// Test compound arithmetic operations
|
||||
TEST(VectorUtilsTest, CompoundArithmetic)
|
||||
{
|
||||
{
|
||||
Vector2 vec(1.0, 2.0);
|
||||
vec += Vector2(3.0, 4.0);
|
||||
ASSERT_EQ(Vector2(4.0, 6.0), vec);
|
||||
}
|
||||
{
|
||||
Vector2 vec(1.0, 2.0);
|
||||
vec -= Vector2(3.0, 4.0);
|
||||
ASSERT_EQ(Vector2(-2.0, -2.0), vec);
|
||||
}
|
||||
{
|
||||
Vector2 vec(1.0, 2.0);
|
||||
vec *= Vector2(3.0, 4.0);
|
||||
ASSERT_EQ(Vector2(3.0, 8.0), vec);
|
||||
}
|
||||
{
|
||||
Vector2 vec(3.0, 4.0);
|
||||
vec /= Vector2(1.0, 2.0);
|
||||
ASSERT_EQ(Vector2(3.0, 2.0), vec);
|
||||
}
|
||||
{
|
||||
Vector2 vec(1.0, 2.0);
|
||||
vec *= 2.0;
|
||||
ASSERT_EQ(Vector2(2.0, 4.0), vec);
|
||||
}
|
||||
{
|
||||
Vector2 vec(1.0, 2.0);
|
||||
vec /= 2.0;
|
||||
ASSERT_EQ(Vector2(0.5, 1.0), vec);
|
||||
}
|
||||
}
|
||||
|
||||
// Test other arithmetic operations
|
||||
TEST(VectorUtilsTest, OtherArithmeticOperations)
|
||||
{
|
||||
Vector2 vec(3.0, 4.0);
|
||||
|
||||
ASSERT_EQ(25.0, vec.lengthSquared());
|
||||
ASSERT_EQ(5.0, vec.length());
|
||||
ASSERT_EQ(Vector2(0.6, 0.8), vec.normalized());
|
||||
|
||||
ASSERT_EQ(11.0, vec.dot(Vector2(1.0, 2.0)));
|
||||
}
|
||||
|
||||
// Test element shortcuts
|
||||
TEST(VectorUtilsTest, ElementShortcuts)
|
||||
{
|
||||
Vector2 vec2(1.0, 2.0);
|
||||
Vector3 vec3(1.0, 2.0, 3.0);
|
||||
Vector4 vec4(1.0, 2.0, 3.0, 4.0);
|
||||
|
||||
ASSERT_EQ(1.0, vec2.x());
|
||||
ASSERT_EQ(1.0, vec3.x());
|
||||
ASSERT_EQ(1.0, vec4.x());
|
||||
|
||||
ASSERT_EQ(2.0, vec2.y());
|
||||
ASSERT_EQ(2.0, vec3.y());
|
||||
ASSERT_EQ(2.0, vec4.y());
|
||||
|
||||
ASSERT_EQ(3.0, vec3.z());
|
||||
ASSERT_EQ(3.0, vec4.z());
|
||||
|
||||
ASSERT_EQ(4.0, vec4.w());
|
||||
|
||||
vec2.x() = 0.0;
|
||||
ASSERT_EQ(Vector2(0.0, 2.0), vec2);
|
||||
}
|
||||
|
||||
// Test the cross product
|
||||
TEST(VectorUtilsTest, CrossProduct)
|
||||
{
|
||||
ASSERT_EQ(Vector3(0.0, 0.0, 1.0), Vector3(1.0, 0.0, 0.0).cross(Vector3(0.0, 1.0, 0.0)));
|
||||
ASSERT_EQ(Vector3(-3.0, 6.0, -3.0), Vector3(1.0, 2.0, 3.0).cross(Vector3(4.0, 5.0, 6.0)));
|
||||
}
|
||||
|
||||
// Test basic functionality of int vectors
|
||||
TEST(VectorUtilsTest, IntVector)
|
||||
{
|
||||
Vector2I vec(0);
|
||||
|
||||
int *data = vec.data();
|
||||
data[1] = 1;
|
||||
|
||||
ASSERT_EQ(0, vec[0]);
|
||||
ASSERT_EQ(1, vec[1]);
|
||||
}
|
||||
|
||||
// Test basic functionality of int vectors
|
||||
TEST(VectorUtilsTest, UIntVector)
|
||||
{
|
||||
Vector2U vec(0);
|
||||
|
||||
unsigned int *data = vec.data();
|
||||
data[1] = 1;
|
||||
|
||||
ASSERT_EQ(0u, vec[0]);
|
||||
ASSERT_EQ(1u, vec[1]);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
|
@ -1,28 +0,0 @@
|
|||
//
|
||||
// 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 COMMON_VERSION_H_
|
||||
#define COMMON_VERSION_H_
|
||||
|
||||
#include "id/commit.h"
|
||||
|
||||
#define ANGLE_MAJOR_VERSION 2
|
||||
#define ANGLE_MINOR_VERSION 1
|
||||
|
||||
#ifndef ANGLE_REVISION
|
||||
#define ANGLE_REVISION 0
|
||||
#endif
|
||||
|
||||
#define ANGLE_STRINGIFY(x) #x
|
||||
#define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
|
||||
|
||||
#define ANGLE_VERSION_STRING \
|
||||
ANGLE_MACRO_STRINGIFY(ANGLE_MAJOR_VERSION) "." \
|
||||
ANGLE_MACRO_STRINGIFY(ANGLE_MINOR_VERSION) "." \
|
||||
ANGLE_MACRO_STRINGIFY(ANGLE_REVISION) "." \
|
||||
ANGLE_COMMIT_HASH
|
||||
|
||||
#endif // COMMON_VERSION_H_
|
|
@ -1,381 +0,0 @@
|
|||
# Copyright (c) 2013 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.
|
||||
|
||||
{
|
||||
'variables':
|
||||
{
|
||||
# These file lists are shared with the GN build.
|
||||
'angle_translator_sources':
|
||||
[
|
||||
'../include/EGL/egl.h',
|
||||
'../include/EGL/eglext.h',
|
||||
'../include/EGL/eglplatform.h',
|
||||
'../include/GLES2/gl2.h',
|
||||
'../include/GLES2/gl2ext.h',
|
||||
'../include/GLES2/gl2platform.h',
|
||||
'../include/GLES3/gl3.h',
|
||||
'../include/GLES3/gl3platform.h',
|
||||
'../include/GLES3/gl31.h',
|
||||
'../include/GLES3/gl32.h',
|
||||
'../include/GLSLANG/ShaderLang.h',
|
||||
'../include/GLSLANG/ShaderVars.h',
|
||||
'../include/KHR/khrplatform.h',
|
||||
'../include/angle_gl.h',
|
||||
'compiler/translator/AddAndTrueToLoopCondition.cpp',
|
||||
'compiler/translator/AddAndTrueToLoopCondition.h',
|
||||
'compiler/translator/BaseTypes.h',
|
||||
'compiler/translator/BuiltInFunctionEmulator.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulator.h',
|
||||
'compiler/translator/BreakVariableAliasingInInnerLoops.cpp',
|
||||
'compiler/translator/BreakVariableAliasingInInnerLoops.h',
|
||||
'compiler/translator/Cache.cpp',
|
||||
'compiler/translator/Cache.h',
|
||||
'compiler/translator/CallDAG.cpp',
|
||||
'compiler/translator/CallDAG.h',
|
||||
'compiler/translator/ClampPointSize.cpp',
|
||||
'compiler/translator/ClampPointSize.h',
|
||||
'compiler/translator/CodeGen.cpp',
|
||||
'compiler/translator/CollectVariables.cpp',
|
||||
'compiler/translator/CollectVariables.h',
|
||||
'compiler/translator/Common.h',
|
||||
'compiler/translator/Compiler.cpp',
|
||||
'compiler/translator/Compiler.h',
|
||||
'compiler/translator/ConstantUnion.cpp',
|
||||
'compiler/translator/ConstantUnion.h',
|
||||
'compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h',
|
||||
'compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp',
|
||||
'compiler/translator/DeferGlobalInitializers.cpp',
|
||||
'compiler/translator/DeferGlobalInitializers.h',
|
||||
'compiler/translator/Diagnostics.cpp',
|
||||
'compiler/translator/Diagnostics.h',
|
||||
'compiler/translator/DirectiveHandler.cpp',
|
||||
'compiler/translator/DirectiveHandler.h',
|
||||
'compiler/translator/EmulateGLFragColorBroadcast.cpp',
|
||||
'compiler/translator/EmulateGLFragColorBroadcast.h',
|
||||
'compiler/translator/EmulatePrecision.cpp',
|
||||
'compiler/translator/EmulatePrecision.h',
|
||||
'compiler/translator/ExpandIntegerPowExpressions.cpp',
|
||||
'compiler/translator/ExpandIntegerPowExpressions.h',
|
||||
'compiler/translator/ExtensionBehavior.cpp',
|
||||
'compiler/translator/ExtensionBehavior.h',
|
||||
'compiler/translator/FindMain.cpp',
|
||||
'compiler/translator/FindMain.h',
|
||||
'compiler/translator/FindSymbolNode.cpp',
|
||||
'compiler/translator/FindSymbolNode.h',
|
||||
'compiler/translator/FlagStd140Structs.cpp',
|
||||
'compiler/translator/FlagStd140Structs.h',
|
||||
'compiler/translator/HashNames.cpp',
|
||||
'compiler/translator/HashNames.h',
|
||||
'compiler/translator/InfoSink.cpp',
|
||||
'compiler/translator/InfoSink.h',
|
||||
'compiler/translator/Initialize.cpp',
|
||||
'compiler/translator/Initialize.h',
|
||||
'compiler/translator/InitializeDll.cpp',
|
||||
'compiler/translator/InitializeDll.h',
|
||||
'compiler/translator/InitializeGlobals.h',
|
||||
'compiler/translator/InitializeVariables.cpp',
|
||||
'compiler/translator/InitializeVariables.h',
|
||||
'compiler/translator/IntermNode.h',
|
||||
'compiler/translator/IntermNode.cpp',
|
||||
'compiler/translator/IntermNodePatternMatcher.cpp',
|
||||
'compiler/translator/IntermNodePatternMatcher.h',
|
||||
'compiler/translator/IntermNode_util.cpp',
|
||||
'compiler/translator/IntermNode_util.h',
|
||||
'compiler/translator/IntermTraverse.cpp',
|
||||
'compiler/translator/IntermTraverse.h',
|
||||
'compiler/translator/IsASTDepthBelowLimit.cpp',
|
||||
'compiler/translator/IsASTDepthBelowLimit.h',
|
||||
'compiler/translator/NodeSearch.h',
|
||||
'compiler/translator/Operator.cpp',
|
||||
'compiler/translator/Operator.h',
|
||||
'compiler/translator/OutputTree.cpp',
|
||||
'compiler/translator/OutputTree.h',
|
||||
'compiler/translator/ParamType.h',
|
||||
'compiler/translator/ParseContext.cpp',
|
||||
'compiler/translator/ParseContext.h',
|
||||
'compiler/translator/PoolAlloc.cpp',
|
||||
'compiler/translator/PoolAlloc.h',
|
||||
'compiler/translator/Pragma.h',
|
||||
'compiler/translator/PruneEmptyDeclarations.cpp',
|
||||
'compiler/translator/PruneEmptyDeclarations.h',
|
||||
'compiler/translator/PrunePureLiteralStatements.cpp',
|
||||
'compiler/translator/PrunePureLiteralStatements.h',
|
||||
'compiler/translator/QualifierTypes.h',
|
||||
'compiler/translator/QualifierTypes.cpp',
|
||||
'compiler/translator/RecordConstantPrecision.cpp',
|
||||
'compiler/translator/RecordConstantPrecision.h',
|
||||
'compiler/translator/RegenerateStructNames.cpp',
|
||||
'compiler/translator/RegenerateStructNames.h',
|
||||
'compiler/translator/RemoveArrayLengthMethod.cpp',
|
||||
'compiler/translator/RemoveArrayLengthMethod.h',
|
||||
'compiler/translator/RemoveInvariantDeclaration.cpp',
|
||||
'compiler/translator/RemoveInvariantDeclaration.h',
|
||||
'compiler/translator/RemovePow.cpp',
|
||||
'compiler/translator/RemovePow.h',
|
||||
'compiler/translator/RewriteDoWhile.cpp',
|
||||
'compiler/translator/RewriteDoWhile.h',
|
||||
'compiler/translator/RewriteTexelFetchOffset.cpp',
|
||||
'compiler/translator/RewriteTexelFetchOffset.h',
|
||||
'compiler/translator/RewriteUnaryMinusOperatorFloat.cpp',
|
||||
'compiler/translator/RewriteUnaryMinusOperatorFloat.h',
|
||||
'compiler/translator/RewriteUnaryMinusOperatorInt.cpp',
|
||||
'compiler/translator/RewriteUnaryMinusOperatorInt.h',
|
||||
'compiler/translator/RunAtTheEndOfShader.cpp',
|
||||
'compiler/translator/RunAtTheEndOfShader.h',
|
||||
'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp',
|
||||
'compiler/translator/ScalarizeVecAndMatConstructorArgs.h',
|
||||
'compiler/translator/SearchSymbol.cpp',
|
||||
'compiler/translator/SearchSymbol.h',
|
||||
'compiler/translator/SeparateDeclarations.cpp',
|
||||
'compiler/translator/SeparateDeclarations.h',
|
||||
'compiler/translator/Severity.h',
|
||||
'compiler/translator/ShaderLang.cpp',
|
||||
'compiler/translator/ShaderVars.cpp',
|
||||
'compiler/translator/SimplifyLoopConditions.cpp',
|
||||
'compiler/translator/SimplifyLoopConditions.h',
|
||||
'compiler/translator/SplitSequenceOperator.cpp',
|
||||
'compiler/translator/SplitSequenceOperator.h',
|
||||
'compiler/translator/SymbolTable.cpp',
|
||||
'compiler/translator/SymbolTable.h',
|
||||
'compiler/translator/Types.cpp',
|
||||
'compiler/translator/Types.h',
|
||||
'compiler/translator/UnfoldShortCircuitAST.cpp',
|
||||
'compiler/translator/UnfoldShortCircuitAST.h',
|
||||
'compiler/translator/UseInterfaceBlockFields.cpp',
|
||||
'compiler/translator/UseInterfaceBlockFields.h',
|
||||
'compiler/translator/ValidateGlobalInitializer.cpp',
|
||||
'compiler/translator/ValidateGlobalInitializer.h',
|
||||
'compiler/translator/ValidateLimitations.cpp',
|
||||
'compiler/translator/ValidateLimitations.h',
|
||||
'compiler/translator/ValidateMaxParameters.h',
|
||||
'compiler/translator/ValidateMaxParameters.cpp',
|
||||
'compiler/translator/ValidateOutputs.cpp',
|
||||
'compiler/translator/ValidateOutputs.h',
|
||||
'compiler/translator/ValidateSwitch.cpp',
|
||||
'compiler/translator/ValidateSwitch.h',
|
||||
'compiler/translator/ValidateVaryingLocations.cpp',
|
||||
'compiler/translator/ValidateVaryingLocations.h',
|
||||
'compiler/translator/VariablePacker.cpp',
|
||||
'compiler/translator/VariablePacker.h',
|
||||
'compiler/translator/blocklayout.cpp',
|
||||
'compiler/translator/blocklayout.h',
|
||||
'compiler/translator/glslang.h',
|
||||
'compiler/translator/glslang.l',
|
||||
'compiler/translator/glslang.y',
|
||||
'compiler/translator/glslang_lex.cpp',
|
||||
'compiler/translator/glslang_tab.cpp',
|
||||
'compiler/translator/glslang_tab.h',
|
||||
'compiler/translator/length_limits.h',
|
||||
'compiler/translator/util.cpp',
|
||||
'compiler/translator/util.h',
|
||||
'third_party/compiler/ArrayBoundsClamper.cpp',
|
||||
'third_party/compiler/ArrayBoundsClamper.h',
|
||||
],
|
||||
'angle_translator_essl_sources':
|
||||
[
|
||||
'compiler/translator/OutputESSL.cpp',
|
||||
'compiler/translator/OutputESSL.h',
|
||||
'compiler/translator/TranslatorESSL.cpp',
|
||||
'compiler/translator/TranslatorESSL.h',
|
||||
],
|
||||
'angle_translator_glsl_sources':
|
||||
[
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulatorGLSL.h',
|
||||
'compiler/translator/ExtensionGLSL.cpp',
|
||||
'compiler/translator/ExtensionGLSL.h',
|
||||
'compiler/translator/OutputGLSL.cpp',
|
||||
'compiler/translator/OutputGLSL.h',
|
||||
'compiler/translator/OutputGLSLBase.cpp',
|
||||
'compiler/translator/OutputGLSLBase.h',
|
||||
'compiler/translator/TranslatorGLSL.cpp',
|
||||
'compiler/translator/TranslatorGLSL.h',
|
||||
'compiler/translator/VersionGLSL.cpp',
|
||||
'compiler/translator/VersionGLSL.h',
|
||||
],
|
||||
'angle_translator_hlsl_sources':
|
||||
[
|
||||
'compiler/translator/AddDefaultReturnStatements.cpp',
|
||||
'compiler/translator/AddDefaultReturnStatements.h',
|
||||
'compiler/translator/ArrayReturnValueToOutParameter.cpp',
|
||||
'compiler/translator/ArrayReturnValueToOutParameter.h',
|
||||
'compiler/translator/ASTMetadataHLSL.cpp',
|
||||
'compiler/translator/ASTMetadataHLSL.h',
|
||||
'compiler/translator/blocklayoutHLSL.cpp',
|
||||
'compiler/translator/blocklayoutHLSL.h',
|
||||
'compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
|
||||
'compiler/translator/BuiltInFunctionEmulatorHLSL.h',
|
||||
'compiler/translator/OutputHLSL.cpp',
|
||||
'compiler/translator/OutputHLSL.h',
|
||||
'compiler/translator/RemoveDynamicIndexing.cpp',
|
||||
'compiler/translator/RemoveDynamicIndexing.h',
|
||||
'compiler/translator/RemoveSwitchFallThrough.cpp',
|
||||
'compiler/translator/RemoveSwitchFallThrough.h',
|
||||
'compiler/translator/RewriteElseBlocks.cpp',
|
||||
'compiler/translator/RewriteElseBlocks.h',
|
||||
'compiler/translator/SeparateArrayInitialization.cpp',
|
||||
'compiler/translator/SeparateArrayInitialization.h',
|
||||
'compiler/translator/SeparateExpressionsReturningArrays.cpp',
|
||||
'compiler/translator/SeparateExpressionsReturningArrays.h',
|
||||
'compiler/translator/StructureHLSL.cpp',
|
||||
'compiler/translator/StructureHLSL.h',
|
||||
'compiler/translator/TextureFunctionHLSL.cpp',
|
||||
'compiler/translator/TextureFunctionHLSL.h',
|
||||
'compiler/translator/TranslatorHLSL.cpp',
|
||||
'compiler/translator/TranslatorHLSL.h',
|
||||
'compiler/translator/UnfoldShortCircuitToIf.cpp',
|
||||
'compiler/translator/UnfoldShortCircuitToIf.h',
|
||||
'compiler/translator/UniformHLSL.cpp',
|
||||
'compiler/translator/UniformHLSL.h',
|
||||
'compiler/translator/UtilsHLSL.cpp',
|
||||
'compiler/translator/UtilsHLSL.h',
|
||||
'compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp',
|
||||
],
|
||||
'angle_translator_lib_vulkan_sources':
|
||||
[
|
||||
'compiler/translator/OutputVulkanGLSL.cpp',
|
||||
'compiler/translator/OutputVulkanGLSL.h',
|
||||
'compiler/translator/TranslatorVulkan.cpp',
|
||||
'compiler/translator/TranslatorVulkan.h',
|
||||
],
|
||||
'angle_preprocessor_sources':
|
||||
[
|
||||
'compiler/preprocessor/DiagnosticsBase.cpp',
|
||||
'compiler/preprocessor/DiagnosticsBase.h',
|
||||
'compiler/preprocessor/DirectiveHandlerBase.cpp',
|
||||
'compiler/preprocessor/DirectiveHandlerBase.h',
|
||||
'compiler/preprocessor/DirectiveParser.cpp',
|
||||
'compiler/preprocessor/DirectiveParser.h',
|
||||
'compiler/preprocessor/ExpressionParser.cpp',
|
||||
'compiler/preprocessor/ExpressionParser.h',
|
||||
'compiler/preprocessor/ExpressionParser.y',
|
||||
'compiler/preprocessor/Input.cpp',
|
||||
'compiler/preprocessor/Input.h',
|
||||
'compiler/preprocessor/Lexer.cpp',
|
||||
'compiler/preprocessor/Lexer.h',
|
||||
'compiler/preprocessor/Macro.cpp',
|
||||
'compiler/preprocessor/Macro.h',
|
||||
'compiler/preprocessor/MacroExpander.cpp',
|
||||
'compiler/preprocessor/MacroExpander.h',
|
||||
'compiler/preprocessor/Preprocessor.cpp',
|
||||
'compiler/preprocessor/Preprocessor.h',
|
||||
'compiler/preprocessor/SourceLocation.h',
|
||||
'compiler/preprocessor/Token.cpp',
|
||||
'compiler/preprocessor/Token.h',
|
||||
'compiler/preprocessor/Tokenizer.cpp',
|
||||
'compiler/preprocessor/Tokenizer.h',
|
||||
'compiler/preprocessor/Tokenizer.l',
|
||||
'compiler/preprocessor/numeric_lex.h',
|
||||
],
|
||||
},
|
||||
# Everything below this is duplicated in the GN build. If you change
|
||||
# anything also change angle/BUILD.gn
|
||||
'targets':
|
||||
[
|
||||
{
|
||||
'target_name': 'preprocessor',
|
||||
'type': 'static_library',
|
||||
'dependencies': [ 'angle_common' ],
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'sources': [ '<@(angle_preprocessor_sources)', ],
|
||||
},
|
||||
{
|
||||
'target_name': 'translator',
|
||||
'type': 'static_library',
|
||||
'dependencies': [ 'preprocessor', 'angle_common' ],
|
||||
'includes': [ '../gyp/common_defines.gypi', ],
|
||||
'include_dirs':
|
||||
[
|
||||
'.',
|
||||
'../include',
|
||||
],
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_sources)',
|
||||
],
|
||||
'msvs_settings':
|
||||
{
|
||||
'VCLibrarianTool':
|
||||
{
|
||||
'AdditionalOptions': ['/ignore:4221']
|
||||
},
|
||||
},
|
||||
'conditions':
|
||||
[
|
||||
['angle_enable_essl==1',
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_ESSL',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_ESSL',
|
||||
],
|
||||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_essl_sources)',
|
||||
],
|
||||
}],
|
||||
['angle_enable_glsl==1',
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_GLSL',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_GLSL',
|
||||
],
|
||||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_glsl_sources)',
|
||||
],
|
||||
}],
|
||||
['angle_enable_hlsl==1',
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_HLSL',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_HLSL',
|
||||
],
|
||||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_hlsl_sources)',
|
||||
],
|
||||
}],
|
||||
['angle_enable_vulkan==1',
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_VULKAN',
|
||||
],
|
||||
'direct_dependent_settings':
|
||||
{
|
||||
'defines':
|
||||
[
|
||||
'ANGLE_ENABLE_VULKAN',
|
||||
],
|
||||
},
|
||||
'sources':
|
||||
[
|
||||
'<@(angle_translator_lib_vulkan_sources)',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2016 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.
|
||||
//
|
||||
|
||||
// translator_fuzzer.cpp: A libfuzzer fuzzer for the shader translator.
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "angle_gl.h"
|
||||
#include "compiler/translator/Compiler.h"
|
||||
#include "compiler/translator/util.h"
|
||||
|
||||
using namespace sh;
|
||||
|
||||
struct TranslatorCacheKey
|
||||
{
|
||||
bool operator==(const TranslatorCacheKey &other) const
|
||||
{
|
||||
return type == other.type && spec == other.spec && output == other.output;
|
||||
}
|
||||
|
||||
uint32_t type = 0;
|
||||
uint32_t spec = 0;
|
||||
uint32_t output = 0;
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <>
|
||||
struct hash<TranslatorCacheKey>
|
||||
{
|
||||
std::size_t operator()(const TranslatorCacheKey &k) const
|
||||
{
|
||||
return (hash<uint32_t>()(k.type) << 1) ^ (hash<uint32_t>()(k.spec) >> 1) ^
|
||||
hash<uint32_t>()(k.output);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
struct TCompilerDeleter
|
||||
{
|
||||
void operator()(TCompiler *compiler) const { DeleteCompiler(compiler); }
|
||||
};
|
||||
|
||||
using UniqueTCompiler = std::unique_ptr<TCompiler, TCompilerDeleter>;
|
||||
|
||||
static std::unordered_map<TranslatorCacheKey, UniqueTCompiler> translators;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
// Reserve some size for future compile options
|
||||
const size_t kHeaderSize = 128;
|
||||
|
||||
if (size <= kHeaderSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make sure the rest of data will be a valid C string so that we don't have to copy it.
|
||||
if (data[size - 1] != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t type = *reinterpret_cast<const uint32_t *>(data);
|
||||
uint32_t spec = *reinterpret_cast<const uint32_t *>(data + 4);
|
||||
uint32_t output = *reinterpret_cast<const uint32_t *>(data + 8);
|
||||
uint64_t options = *reinterpret_cast<const uint64_t *>(data + 12);
|
||||
|
||||
if (type != GL_FRAGMENT_SHADER && type != GL_VERTEX_SHADER)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (spec != SH_GLES2_SPEC && type != SH_WEBGL_SPEC && spec != SH_GLES3_SPEC &&
|
||||
spec != SH_WEBGL2_SPEC)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ShShaderOutput shaderOutput = static_cast<ShShaderOutput>(output);
|
||||
if (!(IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput)) &&
|
||||
(options & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u)
|
||||
{
|
||||
// This compiler option is only available in ESSL and GLSL.
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> validOutputs;
|
||||
validOutputs.push_back(SH_ESSL_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_COMPATIBILITY_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_130_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_140_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_410_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_420_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_430_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_440_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_GLSL_450_CORE_OUTPUT);
|
||||
validOutputs.push_back(SH_HLSL_3_0_OUTPUT);
|
||||
validOutputs.push_back(SH_HLSL_4_1_OUTPUT);
|
||||
validOutputs.push_back(SH_HLSL_4_0_FL9_3_OUTPUT);
|
||||
bool found = false;
|
||||
for (auto valid : validOutputs)
|
||||
{
|
||||
found = found || (valid == output);
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size -= kHeaderSize;
|
||||
data += kHeaderSize;
|
||||
|
||||
if (!sh::Initialize())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TranslatorCacheKey key;
|
||||
key.type = type;
|
||||
key.spec = spec;
|
||||
key.output = output;
|
||||
|
||||
if (translators.find(key) == translators.end())
|
||||
{
|
||||
UniqueTCompiler translator(
|
||||
ConstructCompiler(type, static_cast<ShShaderSpec>(spec), shaderOutput));
|
||||
|
||||
if (translator == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ShBuiltInResources resources;
|
||||
sh::InitBuiltInResources(&resources);
|
||||
|
||||
// Enable all the extensions to have more coverage
|
||||
resources.OES_standard_derivatives = 1;
|
||||
resources.OES_EGL_image_external = 1;
|
||||
resources.OES_EGL_image_external_essl3 = 1;
|
||||
resources.NV_EGL_stream_consumer_external = 1;
|
||||
resources.ARB_texture_rectangle = 1;
|
||||
resources.EXT_blend_func_extended = 1;
|
||||
resources.EXT_draw_buffers = 1;
|
||||
resources.EXT_frag_depth = 1;
|
||||
resources.EXT_shader_texture_lod = 1;
|
||||
resources.WEBGL_debug_shader_precision = 1;
|
||||
resources.EXT_shader_framebuffer_fetch = 1;
|
||||
resources.NV_shader_framebuffer_fetch = 1;
|
||||
resources.ARM_shader_framebuffer_fetch = 1;
|
||||
resources.EXT_YUV_target = 1;
|
||||
resources.MaxDualSourceDrawBuffers = 1;
|
||||
|
||||
if (!translator->Init(resources))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
translators[key] = std::move(translator);
|
||||
}
|
||||
|
||||
auto &translator = translators[key];
|
||||
|
||||
const char *shaderStrings[] = {reinterpret_cast<const char *>(data)};
|
||||
translator->compile(shaderStrings, 1, options);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
diff --git a/src/compiler/preprocessor/Tokenizer.cpp b/src/compiler/preprocessor/Tokenizer.cpp
|
||||
index 0d7ad58..5ef0e5e 100644
|
||||
--- a/src/compiler/preprocessor/Tokenizer.cpp
|
||||
+++ b/src/compiler/preprocessor/Tokenizer.cpp
|
||||
@@ -1746,8 +1746,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
|
||||
num_to_read = YY_READ_BUF_SIZE;
|
||||
|
||||
/* Read in more data. */
|
||||
+ yy_size_t ret = 0;
|
||||
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
|
||||
- yyg->yy_n_chars, num_to_read );
|
||||
+ ret, num_to_read );
|
||||
+ yyg->yy_n_chars = static_cast<int>(ret);
|
||||
|
||||
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2012 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 "compiler/preprocessor/DiagnosticsBase.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
Diagnostics::~Diagnostics()
|
||||
{
|
||||
}
|
||||
|
||||
void Diagnostics::report(ID id, const SourceLocation &loc, const std::string &text)
|
||||
{
|
||||
print(id, loc, text);
|
||||
}
|
||||
|
||||
bool Diagnostics::isError(ID id)
|
||||
{
|
||||
if ((id > PP_ERROR_BEGIN) && (id < PP_ERROR_END))
|
||||
return true;
|
||||
|
||||
if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
|
||||
return false;
|
||||
|
||||
UNREACHABLE();
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *Diagnostics::message(ID id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
// Errors begin.
|
||||
case PP_INTERNAL_ERROR:
|
||||
return "internal error";
|
||||
case PP_OUT_OF_MEMORY:
|
||||
return "out of memory";
|
||||
case PP_INVALID_CHARACTER:
|
||||
return "invalid character";
|
||||
case PP_INVALID_NUMBER:
|
||||
return "invalid number";
|
||||
case PP_INTEGER_OVERFLOW:
|
||||
return "integer overflow";
|
||||
case PP_FLOAT_OVERFLOW:
|
||||
return "float overflow";
|
||||
case PP_TOKEN_TOO_LONG:
|
||||
return "token too long";
|
||||
case PP_INVALID_EXPRESSION:
|
||||
return "invalid expression";
|
||||
case PP_DIVISION_BY_ZERO:
|
||||
return "division by zero";
|
||||
case PP_EOF_IN_COMMENT:
|
||||
return "unexpected end of file found in comment";
|
||||
case PP_UNEXPECTED_TOKEN:
|
||||
return "unexpected token";
|
||||
case PP_DIRECTIVE_INVALID_NAME:
|
||||
return "invalid directive name";
|
||||
case PP_MACRO_NAME_RESERVED:
|
||||
return "macro name is reserved";
|
||||
case PP_MACRO_REDEFINED:
|
||||
return "macro redefined";
|
||||
case PP_MACRO_PREDEFINED_REDEFINED:
|
||||
return "predefined macro redefined";
|
||||
case PP_MACRO_PREDEFINED_UNDEFINED:
|
||||
return "predefined macro undefined";
|
||||
case PP_MACRO_UNTERMINATED_INVOCATION:
|
||||
return "unterminated macro invocation";
|
||||
case PP_MACRO_UNDEFINED_WHILE_INVOKED:
|
||||
return "macro undefined while being invoked";
|
||||
case PP_MACRO_TOO_FEW_ARGS:
|
||||
return "Not enough arguments for macro";
|
||||
case PP_MACRO_TOO_MANY_ARGS:
|
||||
return "Too many arguments for macro";
|
||||
case PP_MACRO_DUPLICATE_PARAMETER_NAMES:
|
||||
return "duplicate macro parameter name";
|
||||
case PP_MACRO_INVOCATION_CHAIN_TOO_DEEP:
|
||||
return "macro invocation chain too deep";
|
||||
case PP_CONDITIONAL_ENDIF_WITHOUT_IF:
|
||||
return "unexpected #endif found without a matching #if";
|
||||
case PP_CONDITIONAL_ELSE_WITHOUT_IF:
|
||||
return "unexpected #else found without a matching #if";
|
||||
case PP_CONDITIONAL_ELSE_AFTER_ELSE:
|
||||
return "unexpected #else found after another #else";
|
||||
case PP_CONDITIONAL_ELIF_WITHOUT_IF:
|
||||
return "unexpected #elif found without a matching #if";
|
||||
case PP_CONDITIONAL_ELIF_AFTER_ELSE:
|
||||
return "unexpected #elif found after #else";
|
||||
case PP_CONDITIONAL_UNTERMINATED:
|
||||
return "unexpected end of file found in conditional block";
|
||||
case PP_INVALID_EXTENSION_NAME:
|
||||
return "invalid extension name";
|
||||
case PP_INVALID_EXTENSION_BEHAVIOR:
|
||||
return "invalid extension behavior";
|
||||
case PP_INVALID_EXTENSION_DIRECTIVE:
|
||||
return "invalid extension directive";
|
||||
case PP_INVALID_VERSION_NUMBER:
|
||||
return "invalid version number";
|
||||
case PP_INVALID_VERSION_DIRECTIVE:
|
||||
return "invalid version directive";
|
||||
case PP_VERSION_NOT_FIRST_STATEMENT:
|
||||
return "#version directive must occur before anything else, "
|
||||
"except for comments and white space";
|
||||
case PP_VERSION_NOT_FIRST_LINE_ESSL3:
|
||||
return "#version directive must occur on the first line of the shader";
|
||||
case PP_INVALID_LINE_NUMBER:
|
||||
return "invalid line number";
|
||||
case PP_INVALID_FILE_NUMBER:
|
||||
return "invalid file number";
|
||||
case PP_INVALID_LINE_DIRECTIVE:
|
||||
return "invalid line directive";
|
||||
case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3:
|
||||
return "extension directive must occur before any non-preprocessor tokens in ESSL3";
|
||||
case PP_UNDEFINED_SHIFT:
|
||||
return "shift exponent is negative or undefined";
|
||||
// Errors end.
|
||||
// Warnings begin.
|
||||
case PP_EOF_IN_DIRECTIVE:
|
||||
return "unexpected end of file found in directive";
|
||||
case PP_CONDITIONAL_UNEXPECTED_TOKEN:
|
||||
return "unexpected token after conditional expression";
|
||||
case PP_UNRECOGNIZED_PRAGMA:
|
||||
return "unrecognized pragma";
|
||||
case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1:
|
||||
return "extension directive should occur before any non-preprocessor tokens";
|
||||
case PP_WARNING_MACRO_NAME_RESERVED:
|
||||
return "macro name with a double underscore is reserved - unintented behavior is "
|
||||
"possible";
|
||||
// Warnings end.
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pp
|
|
@ -1,90 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2012 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 COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
|
||||
#define COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
struct SourceLocation;
|
||||
|
||||
// Base class for reporting diagnostic messages.
|
||||
// Derived classes are responsible for formatting and printing the messages.
|
||||
class Diagnostics
|
||||
{
|
||||
public:
|
||||
enum ID
|
||||
{
|
||||
PP_ERROR_BEGIN,
|
||||
PP_INTERNAL_ERROR,
|
||||
PP_OUT_OF_MEMORY,
|
||||
PP_INVALID_CHARACTER,
|
||||
PP_INVALID_NUMBER,
|
||||
PP_INTEGER_OVERFLOW,
|
||||
PP_FLOAT_OVERFLOW,
|
||||
PP_TOKEN_TOO_LONG,
|
||||
PP_INVALID_EXPRESSION,
|
||||
PP_DIVISION_BY_ZERO,
|
||||
PP_EOF_IN_COMMENT,
|
||||
PP_UNEXPECTED_TOKEN,
|
||||
PP_DIRECTIVE_INVALID_NAME,
|
||||
PP_MACRO_NAME_RESERVED,
|
||||
PP_MACRO_REDEFINED,
|
||||
PP_MACRO_PREDEFINED_REDEFINED,
|
||||
PP_MACRO_PREDEFINED_UNDEFINED,
|
||||
PP_MACRO_UNTERMINATED_INVOCATION,
|
||||
PP_MACRO_UNDEFINED_WHILE_INVOKED,
|
||||
PP_MACRO_TOO_FEW_ARGS,
|
||||
PP_MACRO_TOO_MANY_ARGS,
|
||||
PP_MACRO_DUPLICATE_PARAMETER_NAMES,
|
||||
PP_MACRO_INVOCATION_CHAIN_TOO_DEEP,
|
||||
PP_CONDITIONAL_ENDIF_WITHOUT_IF,
|
||||
PP_CONDITIONAL_ELSE_WITHOUT_IF,
|
||||
PP_CONDITIONAL_ELSE_AFTER_ELSE,
|
||||
PP_CONDITIONAL_ELIF_WITHOUT_IF,
|
||||
PP_CONDITIONAL_ELIF_AFTER_ELSE,
|
||||
PP_CONDITIONAL_UNTERMINATED,
|
||||
PP_CONDITIONAL_UNEXPECTED_TOKEN,
|
||||
PP_INVALID_EXTENSION_NAME,
|
||||
PP_INVALID_EXTENSION_BEHAVIOR,
|
||||
PP_INVALID_EXTENSION_DIRECTIVE,
|
||||
PP_INVALID_VERSION_NUMBER,
|
||||
PP_INVALID_VERSION_DIRECTIVE,
|
||||
PP_VERSION_NOT_FIRST_STATEMENT,
|
||||
PP_VERSION_NOT_FIRST_LINE_ESSL3,
|
||||
PP_INVALID_LINE_NUMBER,
|
||||
PP_INVALID_FILE_NUMBER,
|
||||
PP_INVALID_LINE_DIRECTIVE,
|
||||
PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3,
|
||||
PP_UNDEFINED_SHIFT,
|
||||
PP_TOKENIZER_ERROR,
|
||||
PP_ERROR_END,
|
||||
|
||||
PP_WARNING_BEGIN,
|
||||
PP_EOF_IN_DIRECTIVE,
|
||||
PP_UNRECOGNIZED_PRAGMA,
|
||||
PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
|
||||
PP_WARNING_MACRO_NAME_RESERVED,
|
||||
PP_WARNING_END
|
||||
};
|
||||
|
||||
virtual ~Diagnostics();
|
||||
|
||||
void report(ID id, const SourceLocation &loc, const std::string &text);
|
||||
|
||||
protected:
|
||||
bool isError(ID id);
|
||||
const char *message(ID id);
|
||||
|
||||
virtual void print(ID id, const SourceLocation &loc, const std::string &text) = 0;
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2012 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 "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
DirectiveHandler::~DirectiveHandler()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace pp
|
|
@ -1,43 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2012 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 COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
|
||||
#define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
struct SourceLocation;
|
||||
|
||||
// Base class for handling directives.
|
||||
// Preprocessor uses this class to notify the clients about certain
|
||||
// preprocessor directives. Derived classes are responsible for
|
||||
// handling them in an appropriate manner.
|
||||
class DirectiveHandler
|
||||
{
|
||||
public:
|
||||
virtual ~DirectiveHandler();
|
||||
|
||||
virtual void handleError(const SourceLocation &loc, const std::string &msg) = 0;
|
||||
|
||||
// Handle pragma of form: #pragma name[(value)]
|
||||
virtual void handlePragma(const SourceLocation &loc,
|
||||
const std::string &name,
|
||||
const std::string &value,
|
||||
bool stdgl) = 0;
|
||||
|
||||
virtual void handleExtension(const SourceLocation &loc,
|
||||
const std::string &name,
|
||||
const std::string &behavior) = 0;
|
||||
|
||||
virtual void handleVersion(const SourceLocation &loc, int version) = 0;
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
|
|
@ -1,996 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2011-2013 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 "compiler/preprocessor/DirectiveParser.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
#include "compiler/preprocessor/DirectiveHandlerBase.h"
|
||||
#include "compiler/preprocessor/ExpressionParser.h"
|
||||
#include "compiler/preprocessor/MacroExpander.h"
|
||||
#include "compiler/preprocessor/Token.h"
|
||||
#include "compiler/preprocessor/Tokenizer.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum DirectiveType
|
||||
{
|
||||
DIRECTIVE_NONE,
|
||||
DIRECTIVE_DEFINE,
|
||||
DIRECTIVE_UNDEF,
|
||||
DIRECTIVE_IF,
|
||||
DIRECTIVE_IFDEF,
|
||||
DIRECTIVE_IFNDEF,
|
||||
DIRECTIVE_ELSE,
|
||||
DIRECTIVE_ELIF,
|
||||
DIRECTIVE_ENDIF,
|
||||
DIRECTIVE_ERROR,
|
||||
DIRECTIVE_PRAGMA,
|
||||
DIRECTIVE_EXTENSION,
|
||||
DIRECTIVE_VERSION,
|
||||
DIRECTIVE_LINE
|
||||
};
|
||||
|
||||
DirectiveType getDirective(const pp::Token *token)
|
||||
{
|
||||
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;
|
||||
|
||||
if (token->text == kDirectiveDefine)
|
||||
return DIRECTIVE_DEFINE;
|
||||
if (token->text == kDirectiveUndef)
|
||||
return DIRECTIVE_UNDEF;
|
||||
if (token->text == kDirectiveIf)
|
||||
return DIRECTIVE_IF;
|
||||
if (token->text == kDirectiveIfdef)
|
||||
return DIRECTIVE_IFDEF;
|
||||
if (token->text == kDirectiveIfndef)
|
||||
return DIRECTIVE_IFNDEF;
|
||||
if (token->text == kDirectiveElse)
|
||||
return DIRECTIVE_ELSE;
|
||||
if (token->text == kDirectiveElif)
|
||||
return DIRECTIVE_ELIF;
|
||||
if (token->text == kDirectiveEndif)
|
||||
return DIRECTIVE_ENDIF;
|
||||
if (token->text == kDirectiveError)
|
||||
return DIRECTIVE_ERROR;
|
||||
if (token->text == kDirectivePragma)
|
||||
return DIRECTIVE_PRAGMA;
|
||||
if (token->text == kDirectiveExtension)
|
||||
return DIRECTIVE_EXTENSION;
|
||||
if (token->text == kDirectiveVersion)
|
||||
return DIRECTIVE_VERSION;
|
||||
if (token->text == kDirectiveLine)
|
||||
return DIRECTIVE_LINE;
|
||||
|
||||
return DIRECTIVE_NONE;
|
||||
}
|
||||
|
||||
bool isConditionalDirective(DirectiveType directive)
|
||||
{
|
||||
switch (directive)
|
||||
{
|
||||
case DIRECTIVE_IF:
|
||||
case DIRECTIVE_IFDEF:
|
||||
case DIRECTIVE_IFNDEF:
|
||||
case DIRECTIVE_ELSE:
|
||||
case DIRECTIVE_ELIF:
|
||||
case DIRECTIVE_ENDIF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if the token represents End Of Directive.
|
||||
bool isEOD(const pp::Token *token)
|
||||
{
|
||||
return (token->type == '\n') || (token->type == pp::Token::LAST);
|
||||
}
|
||||
|
||||
void skipUntilEOD(pp::Lexer *lexer, pp::Token *token)
|
||||
{
|
||||
while (!isEOD(token))
|
||||
{
|
||||
lexer->lex(token);
|
||||
}
|
||||
}
|
||||
|
||||
bool isMacroNameReserved(const std::string &name)
|
||||
{
|
||||
// Names prefixed with "GL_" and the name "defined" are reserved.
|
||||
return name == "defined" || (name.substr(0, 3) == "GL_");
|
||||
}
|
||||
|
||||
bool hasDoubleUnderscores(const std::string &name)
|
||||
{
|
||||
return (name.find("__") != std::string::npos);
|
||||
}
|
||||
|
||||
bool isMacroPredefined(const std::string &name, const pp::MacroSet ¯oSet)
|
||||
{
|
||||
pp::MacroSet::const_iterator iter = macroSet.find(name);
|
||||
return iter != macroSet.end() ? iter->second->predefined : false;
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
class DefinedParser : public Lexer
|
||||
{
|
||||
public:
|
||||
DefinedParser(Lexer *lexer, const MacroSet *macroSet, Diagnostics *diagnostics)
|
||||
: mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void lex(Token *token) override
|
||||
{
|
||||
const char kDefined[] = "defined";
|
||||
|
||||
mLexer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
return;
|
||||
if (token->text != kDefined)
|
||||
return;
|
||||
|
||||
bool paren = false;
|
||||
mLexer->lex(token);
|
||||
if (token->type == '(')
|
||||
{
|
||||
paren = true;
|
||||
mLexer->lex(token);
|
||||
}
|
||||
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
|
||||
skipUntilEOD(mLexer, token);
|
||||
return;
|
||||
}
|
||||
MacroSet::const_iterator iter = mMacroSet->find(token->text);
|
||||
std::string expression = iter != mMacroSet->end() ? "1" : "0";
|
||||
|
||||
if (paren)
|
||||
{
|
||||
mLexer->lex(token);
|
||||
if (token->type != ')')
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mLexer, token);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We have a valid defined operator.
|
||||
// Convert the current token into a CONST_INT token.
|
||||
token->type = Token::CONST_INT;
|
||||
token->text = expression;
|
||||
}
|
||||
|
||||
private:
|
||||
Lexer *mLexer;
|
||||
const MacroSet *mMacroSet;
|
||||
Diagnostics *mDiagnostics;
|
||||
};
|
||||
|
||||
DirectiveParser::DirectiveParser(Tokenizer *tokenizer,
|
||||
MacroSet *macroSet,
|
||||
Diagnostics *diagnostics,
|
||||
DirectiveHandler *directiveHandler,
|
||||
int maxMacroExpansionDepth)
|
||||
: mPastFirstStatement(false),
|
||||
mSeenNonPreprocessorToken(false),
|
||||
mTokenizer(tokenizer),
|
||||
mMacroSet(macroSet),
|
||||
mDiagnostics(diagnostics),
|
||||
mDirectiveHandler(directiveHandler),
|
||||
mShaderVersion(100),
|
||||
mMaxMacroExpansionDepth(maxMacroExpansionDepth)
|
||||
{
|
||||
}
|
||||
|
||||
void DirectiveParser::lex(Token *token)
|
||||
{
|
||||
do
|
||||
{
|
||||
mTokenizer->lex(token);
|
||||
|
||||
if (token->type == Token::PP_HASH)
|
||||
{
|
||||
parseDirective(token);
|
||||
mPastFirstStatement = true;
|
||||
}
|
||||
else if (!isEOD(token))
|
||||
{
|
||||
mSeenNonPreprocessorToken = true;
|
||||
}
|
||||
|
||||
if (token->type == Token::LAST)
|
||||
{
|
||||
if (!mConditionalStack.empty())
|
||||
{
|
||||
const ConditionalBlock &block = mConditionalStack.back();
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, block.location,
|
||||
block.type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} while (skipping() || (token->type == '\n'));
|
||||
|
||||
mPastFirstStatement = true;
|
||||
}
|
||||
|
||||
void DirectiveParser::parseDirective(Token *token)
|
||||
{
|
||||
ASSERT(token->type == Token::PP_HASH);
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (isEOD(token))
|
||||
{
|
||||
// Empty Directive.
|
||||
return;
|
||||
}
|
||||
|
||||
DirectiveType directive = getDirective(token);
|
||||
|
||||
// While in an excluded conditional block/group,
|
||||
// we only parse conditional directives.
|
||||
if (skipping() && !isConditionalDirective(directive))
|
||||
{
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (directive)
|
||||
{
|
||||
case DIRECTIVE_NONE:
|
||||
mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
break;
|
||||
case DIRECTIVE_DEFINE:
|
||||
parseDefine(token);
|
||||
break;
|
||||
case DIRECTIVE_UNDEF:
|
||||
parseUndef(token);
|
||||
break;
|
||||
case DIRECTIVE_IF:
|
||||
parseIf(token);
|
||||
break;
|
||||
case DIRECTIVE_IFDEF:
|
||||
parseIfdef(token);
|
||||
break;
|
||||
case DIRECTIVE_IFNDEF:
|
||||
parseIfndef(token);
|
||||
break;
|
||||
case DIRECTIVE_ELSE:
|
||||
parseElse(token);
|
||||
break;
|
||||
case DIRECTIVE_ELIF:
|
||||
parseElif(token);
|
||||
break;
|
||||
case DIRECTIVE_ENDIF:
|
||||
parseEndif(token);
|
||||
break;
|
||||
case DIRECTIVE_ERROR:
|
||||
parseError(token);
|
||||
break;
|
||||
case DIRECTIVE_PRAGMA:
|
||||
parsePragma(token);
|
||||
break;
|
||||
case DIRECTIVE_EXTENSION:
|
||||
parseExtension(token);
|
||||
break;
|
||||
case DIRECTIVE_VERSION:
|
||||
parseVersion(token);
|
||||
break;
|
||||
case DIRECTIVE_LINE:
|
||||
parseLine(token);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
if (token->type == Token::LAST)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, token->location, token->text);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectiveParser::parseDefine(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_DEFINE);
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
|
||||
return;
|
||||
}
|
||||
if (isMacroPredefined(token->text, *mMacroSet))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location,
|
||||
token->text);
|
||||
return;
|
||||
}
|
||||
if (isMacroNameReserved(token->text))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text);
|
||||
return;
|
||||
}
|
||||
// Using double underscores is allowed, but may result in unintended
|
||||
// behavior, so a warning is issued. At the time of writing this was
|
||||
// specified in ESSL 3.10, but the intent judging from Khronos
|
||||
// discussions and dEQP tests was that double underscores should be
|
||||
// allowed in earlier ESSL versions too.
|
||||
if (hasDoubleUnderscores(token->text))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location,
|
||||
token->text);
|
||||
}
|
||||
|
||||
std::shared_ptr<Macro> macro = std::make_shared<Macro>();
|
||||
macro->type = Macro::kTypeObj;
|
||||
macro->name = token->text;
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (token->type == '(' && !token->hasLeadingSpace())
|
||||
{
|
||||
// Function-like macro. Collect arguments.
|
||||
macro->type = Macro::kTypeFunc;
|
||||
do
|
||||
{
|
||||
mTokenizer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
break;
|
||||
|
||||
if (std::find(macro->parameters.begin(), macro->parameters.end(), token->text) !=
|
||||
macro->parameters.end())
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES,
|
||||
token->location, token->text);
|
||||
return;
|
||||
}
|
||||
|
||||
macro->parameters.push_back(token->text);
|
||||
|
||||
mTokenizer->lex(token); // Get ','.
|
||||
} while (token->type == ',');
|
||||
|
||||
if (token->type != ')')
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
|
||||
return;
|
||||
}
|
||||
mTokenizer->lex(token); // Get ')'.
|
||||
}
|
||||
|
||||
while ((token->type != '\n') && (token->type != Token::LAST))
|
||||
{
|
||||
// Reset the token location because it is unnecessary in replacement
|
||||
// list. Resetting it also allows us to reuse Token::equals() to
|
||||
// compare macros.
|
||||
token->location = SourceLocation();
|
||||
macro->replacements.push_back(*token);
|
||||
mTokenizer->lex(token);
|
||||
}
|
||||
if (!macro->replacements.empty())
|
||||
{
|
||||
// Whitespace preceding the replacement list is not considered part of
|
||||
// the replacement list for either form of macro.
|
||||
macro->replacements.front().setHasLeadingSpace(false);
|
||||
}
|
||||
|
||||
// Check for macro redefinition.
|
||||
MacroSet::const_iterator iter = mMacroSet->find(macro->name);
|
||||
if (iter != mMacroSet->end() && !macro->equals(*iter->second))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro->name);
|
||||
return;
|
||||
}
|
||||
mMacroSet->insert(std::make_pair(macro->name, macro));
|
||||
}
|
||||
|
||||
void DirectiveParser::parseUndef(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_UNDEF);
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
|
||||
return;
|
||||
}
|
||||
|
||||
MacroSet::iterator iter = mMacroSet->find(token->text);
|
||||
if (iter != mMacroSet->end())
|
||||
{
|
||||
if (iter->second->predefined)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, token->location,
|
||||
token->text);
|
||||
return;
|
||||
}
|
||||
else if (iter->second->expansionCount > 0)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, token->location,
|
||||
token->text);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMacroSet->erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (!isEOD(token))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectiveParser::parseIf(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_IF);
|
||||
parseConditionalIf(token);
|
||||
}
|
||||
|
||||
void DirectiveParser::parseIfdef(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_IFDEF);
|
||||
parseConditionalIf(token);
|
||||
}
|
||||
|
||||
void DirectiveParser::parseIfndef(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_IFNDEF);
|
||||
parseConditionalIf(token);
|
||||
}
|
||||
|
||||
void DirectiveParser::parseElse(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ELSE);
|
||||
|
||||
if (mConditionalStack.empty())
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
|
||||
ConditionalBlock &block = mConditionalStack.back();
|
||||
if (block.skipBlock)
|
||||
{
|
||||
// No diagnostics. Just skip the whole line.
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
if (block.foundElseGroup)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
|
||||
block.foundElseGroup = true;
|
||||
block.skipGroup = block.foundValidGroup;
|
||||
block.foundValidGroup = true;
|
||||
|
||||
// Check if there are extra tokens after #else.
|
||||
mTokenizer->lex(token);
|
||||
if (!isEOD(token))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectiveParser::parseElif(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ELIF);
|
||||
|
||||
if (mConditionalStack.empty())
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
|
||||
ConditionalBlock &block = mConditionalStack.back();
|
||||
if (block.skipBlock)
|
||||
{
|
||||
// No diagnostics. Just skip the whole line.
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
if (block.foundElseGroup)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
if (block.foundValidGroup)
|
||||
{
|
||||
// Do not parse the expression.
|
||||
// Also be careful not to emit a diagnostic.
|
||||
block.skipGroup = true;
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
|
||||
int expression = parseExpressionIf(token);
|
||||
block.skipGroup = expression == 0;
|
||||
block.foundValidGroup = expression != 0;
|
||||
}
|
||||
|
||||
void DirectiveParser::parseEndif(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ENDIF);
|
||||
|
||||
if (mConditionalStack.empty())
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
|
||||
mConditionalStack.pop_back();
|
||||
|
||||
// Check if there are tokens after #endif.
|
||||
mTokenizer->lex(token);
|
||||
if (!isEOD(token))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectiveParser::parseError(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_ERROR);
|
||||
|
||||
std::ostringstream stream;
|
||||
mTokenizer->lex(token);
|
||||
while ((token->type != '\n') && (token->type != Token::LAST))
|
||||
{
|
||||
stream << *token;
|
||||
mTokenizer->lex(token);
|
||||
}
|
||||
mDirectiveHandler->handleError(token->location, stream.str());
|
||||
}
|
||||
|
||||
// Parses pragma of form: #pragma name[(value)].
|
||||
void DirectiveParser::parsePragma(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_PRAGMA);
|
||||
|
||||
enum State
|
||||
{
|
||||
PRAGMA_NAME,
|
||||
LEFT_PAREN,
|
||||
PRAGMA_VALUE,
|
||||
RIGHT_PAREN
|
||||
};
|
||||
|
||||
bool valid = true;
|
||||
std::string name, value;
|
||||
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++)
|
||||
{
|
||||
case PRAGMA_NAME:
|
||||
name = token->text;
|
||||
valid = valid && (token->type == Token::IDENTIFIER);
|
||||
break;
|
||||
case LEFT_PAREN:
|
||||
valid = valid && (token->type == '(');
|
||||
break;
|
||||
case PRAGMA_VALUE:
|
||||
value = token->text;
|
||||
valid = valid && (token->type == Token::IDENTIFIER);
|
||||
break;
|
||||
case RIGHT_PAREN:
|
||||
valid = valid && (token->type == ')');
|
||||
break;
|
||||
default:
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
mTokenizer->lex(token);
|
||||
}
|
||||
|
||||
valid = valid && ((state == PRAGMA_NAME) || // Empty pragma.
|
||||
(state == LEFT_PAREN) || // Without value.
|
||||
(state == RIGHT_PAREN + 1)); // With value.
|
||||
if (!valid)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name);
|
||||
}
|
||||
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
|
||||
{
|
||||
mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectiveParser::parseExtension(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_EXTENSION);
|
||||
|
||||
enum State
|
||||
{
|
||||
EXT_NAME,
|
||||
COLON,
|
||||
EXT_BEHAVIOR
|
||||
};
|
||||
|
||||
bool valid = true;
|
||||
std::string name, behavior;
|
||||
int state = EXT_NAME;
|
||||
|
||||
mTokenizer->lex(token);
|
||||
while ((token->type != '\n') && (token->type != Token::LAST))
|
||||
{
|
||||
switch (state++)
|
||||
{
|
||||
case EXT_NAME:
|
||||
if (valid && (token->type != Token::IDENTIFIER))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
if (valid)
|
||||
name = token->text;
|
||||
break;
|
||||
case COLON:
|
||||
if (valid && (token->type != ':'))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
case EXT_BEHAVIOR:
|
||||
if (valid && (token->type != Token::IDENTIFIER))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR,
|
||||
token->location, token->text);
|
||||
valid = false;
|
||||
}
|
||||
if (valid)
|
||||
behavior = token->text;
|
||||
break;
|
||||
default:
|
||||
if (valid)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mTokenizer->lex(token);
|
||||
}
|
||||
if (valid && (state != EXT_BEHAVIOR + 1))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
if (valid && mSeenNonPreprocessorToken)
|
||||
{
|
||||
if (mShaderVersion >= 300)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3,
|
||||
token->location, token->text);
|
||||
valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
|
||||
token->location, token->text);
|
||||
}
|
||||
}
|
||||
if (valid)
|
||||
mDirectiveHandler->handleExtension(token->location, name, behavior);
|
||||
}
|
||||
|
||||
void DirectiveParser::parseVersion(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_VERSION);
|
||||
|
||||
if (mPastFirstStatement)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return;
|
||||
}
|
||||
|
||||
enum State
|
||||
{
|
||||
VERSION_NUMBER,
|
||||
VERSION_PROFILE,
|
||||
VERSION_ENDLINE
|
||||
};
|
||||
|
||||
bool valid = true;
|
||||
int version = 0;
|
||||
int state = VERSION_NUMBER;
|
||||
|
||||
mTokenizer->lex(token);
|
||||
while (valid && (token->type != '\n') && (token->type != Token::LAST))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case VERSION_NUMBER:
|
||||
if (token->type != Token::CONST_INT)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
if (valid && !token->iValue(&version))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
if (valid)
|
||||
{
|
||||
state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE;
|
||||
}
|
||||
break;
|
||||
case VERSION_PROFILE:
|
||||
if (token->type != Token::IDENTIFIER || token->text != "es")
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
state = VERSION_ENDLINE;
|
||||
break;
|
||||
default:
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
mTokenizer->lex(token);
|
||||
}
|
||||
|
||||
if (valid && (state != VERSION_ENDLINE))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (valid && version >= 300 && token->location.line > 1)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
mDirectiveHandler->handleVersion(token->location, version);
|
||||
mShaderVersion = version;
|
||||
PredefineMacro(mMacroSet, "__VERSION__", version);
|
||||
}
|
||||
}
|
||||
|
||||
void DirectiveParser::parseLine(Token *token)
|
||||
{
|
||||
ASSERT(getDirective(token) == DIRECTIVE_LINE);
|
||||
|
||||
bool valid = true;
|
||||
bool parsedFileNumber = false;
|
||||
int line = 0, file = 0;
|
||||
|
||||
MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, mMaxMacroExpansionDepth);
|
||||
|
||||
// Lex the first token after "#line" so we can check it for EOD.
|
||||
macroExpander.lex(token);
|
||||
|
||||
if (isEOD(token))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text);
|
||||
valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExpressionParser expressionParser(¯oExpander, mDiagnostics);
|
||||
ExpressionParser::ErrorSettings errorSettings;
|
||||
|
||||
// See GLES3 section 12.42
|
||||
errorSettings.integerLiteralsMustFit32BitSignedRange = true;
|
||||
|
||||
errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_LINE_NUMBER;
|
||||
// The first token was lexed earlier to check if it was EOD. Include
|
||||
// the token in parsing for a second time by setting the
|
||||
// parsePresetToken flag to true.
|
||||
expressionParser.parse(token, &line, true, errorSettings, &valid);
|
||||
if (!isEOD(token) && valid)
|
||||
{
|
||||
errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_FILE_NUMBER;
|
||||
// After parsing the line expression expressionParser has also
|
||||
// advanced to the first token of the file expression - this is the
|
||||
// token that makes the parser reduce the "input" rule for the line
|
||||
// expression and stop. So we're using parsePresetToken = true here
|
||||
// as well.
|
||||
expressionParser.parse(token, &file, true, errorSettings, &valid);
|
||||
parsedFileNumber = true;
|
||||
}
|
||||
if (!isEOD(token))
|
||||
{
|
||||
if (valid)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
valid = false;
|
||||
}
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
mTokenizer->setLineNumber(line);
|
||||
if (parsedFileNumber)
|
||||
mTokenizer->setFileNumber(file);
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectiveParser::skipping() const
|
||||
{
|
||||
if (mConditionalStack.empty())
|
||||
return false;
|
||||
|
||||
const ConditionalBlock &block = mConditionalStack.back();
|
||||
return block.skipBlock || block.skipGroup;
|
||||
}
|
||||
|
||||
void DirectiveParser::parseConditionalIf(Token *token)
|
||||
{
|
||||
ConditionalBlock block;
|
||||
block.type = token->text;
|
||||
block.location = token->location;
|
||||
|
||||
if (skipping())
|
||||
{
|
||||
// This conditional block is inside another conditional group
|
||||
// which is skipped. As a consequence this whole block is skipped.
|
||||
// Be careful not to parse the conditional expression that might
|
||||
// emit a diagnostic.
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
block.skipBlock = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectiveType directive = getDirective(token);
|
||||
|
||||
int expression = 0;
|
||||
switch (directive)
|
||||
{
|
||||
case DIRECTIVE_IF:
|
||||
expression = parseExpressionIf(token);
|
||||
break;
|
||||
case DIRECTIVE_IFDEF:
|
||||
expression = parseExpressionIfdef(token);
|
||||
break;
|
||||
case DIRECTIVE_IFNDEF:
|
||||
expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
block.skipGroup = expression == 0;
|
||||
block.foundValidGroup = expression != 0;
|
||||
}
|
||||
mConditionalStack.push_back(block);
|
||||
}
|
||||
|
||||
int DirectiveParser::parseExpressionIf(Token *token)
|
||||
{
|
||||
ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF));
|
||||
|
||||
DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
|
||||
MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics, mMaxMacroExpansionDepth);
|
||||
ExpressionParser expressionParser(¯oExpander, mDiagnostics);
|
||||
|
||||
int expression = 0;
|
||||
ExpressionParser::ErrorSettings errorSettings;
|
||||
errorSettings.integerLiteralsMustFit32BitSignedRange = false;
|
||||
errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN;
|
||||
|
||||
bool valid = true;
|
||||
expressionParser.parse(token, &expression, false, errorSettings, &valid);
|
||||
|
||||
// Check if there are tokens after #if expression.
|
||||
if (!isEOD(token))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
int DirectiveParser::parseExpressionIfdef(Token *token)
|
||||
{
|
||||
ASSERT((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF));
|
||||
|
||||
mTokenizer->lex(token);
|
||||
if (token->type != Token::IDENTIFIER)
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MacroSet::const_iterator iter = mMacroSet->find(token->text);
|
||||
int expression = iter != mMacroSet->end() ? 1 : 0;
|
||||
|
||||
// Check if there are tokens after #ifdef expression.
|
||||
mTokenizer->lex(token);
|
||||
if (!isEOD(token))
|
||||
{
|
||||
mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
|
||||
token->text);
|
||||
skipUntilEOD(mTokenizer, token);
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
} // namespace pp
|
|
@ -1,82 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2012 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 COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
||||
|
||||
#include "compiler/preprocessor/Lexer.h"
|
||||
#include "compiler/preprocessor/Macro.h"
|
||||
#include "compiler/preprocessor/SourceLocation.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
class Diagnostics;
|
||||
class DirectiveHandler;
|
||||
class Tokenizer;
|
||||
|
||||
class DirectiveParser : public Lexer
|
||||
{
|
||||
public:
|
||||
DirectiveParser(Tokenizer *tokenizer,
|
||||
MacroSet *macroSet,
|
||||
Diagnostics *diagnostics,
|
||||
DirectiveHandler *directiveHandler,
|
||||
int maxMacroExpansionDepth);
|
||||
|
||||
void lex(Token *token) override;
|
||||
|
||||
private:
|
||||
void parseDirective(Token *token);
|
||||
void parseDefine(Token *token);
|
||||
void parseUndef(Token *token);
|
||||
void parseIf(Token *token);
|
||||
void parseIfdef(Token *token);
|
||||
void parseIfndef(Token *token);
|
||||
void parseElse(Token *token);
|
||||
void parseElif(Token *token);
|
||||
void parseEndif(Token *token);
|
||||
void parseError(Token *token);
|
||||
void parsePragma(Token *token);
|
||||
void parseExtension(Token *token);
|
||||
void parseVersion(Token *token);
|
||||
void parseLine(Token *token);
|
||||
|
||||
bool skipping() const;
|
||||
void parseConditionalIf(Token *token);
|
||||
int parseExpressionIf(Token *token);
|
||||
int parseExpressionIfdef(Token *token);
|
||||
|
||||
struct ConditionalBlock
|
||||
{
|
||||
std::string type;
|
||||
SourceLocation location;
|
||||
bool skipBlock;
|
||||
bool skipGroup;
|
||||
bool foundValidGroup;
|
||||
bool foundElseGroup;
|
||||
|
||||
ConditionalBlock()
|
||||
: skipBlock(false), skipGroup(false), foundValidGroup(false), foundElseGroup(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
bool mPastFirstStatement;
|
||||
bool mSeenNonPreprocessorToken; // Tracks if a non-preprocessor token has been seen yet. Some
|
||||
// macros, such as
|
||||
// #extension must be declared before all shader code.
|
||||
std::vector<ConditionalBlock> mConditionalStack;
|
||||
Tokenizer *mTokenizer;
|
||||
MacroSet *mMacroSet;
|
||||
Diagnostics *mDiagnostics;
|
||||
DirectiveHandler *mDirectiveHandler;
|
||||
int mShaderVersion;
|
||||
int mMaxMacroExpansionDepth;
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,43 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2012 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 COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||
#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/preprocessor/DiagnosticsBase.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
class Lexer;
|
||||
struct Token;
|
||||
|
||||
class ExpressionParser : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
struct ErrorSettings
|
||||
{
|
||||
Diagnostics::ID unexpectedIdentifier;
|
||||
bool integerLiteralsMustFit32BitSignedRange;
|
||||
};
|
||||
|
||||
ExpressionParser(Lexer *lexer, Diagnostics *diagnostics);
|
||||
|
||||
bool parse(Token *token,
|
||||
int *result,
|
||||
bool parsePresetToken,
|
||||
const ErrorSettings &errorSettings,
|
||||
bool *valid);
|
||||
|
||||
private:
|
||||
Lexer *mLexer;
|
||||
Diagnostics *mDiagnostics;
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
|
||||
#endif // COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
|
|
@ -1,465 +0,0 @@
|
|||
/*
|
||||
//
|
||||
// Copyright (c) 2012 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.
|
||||
//
|
||||
|
||||
This file contains the Yacc grammar for GLSL ES preprocessor expression.
|
||||
|
||||
IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh,
|
||||
WHICH GENERATES THE GLSL ES preprocessor expression parser.
|
||||
*/
|
||||
|
||||
%{
|
||||
//
|
||||
// Copyright (c) 2012 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.
|
||||
//
|
||||
|
||||
// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// Triggered by the auto-generated pplval variable.
|
||||
#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#else
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(disable: 4065 4244 4701 4702)
|
||||
#endif
|
||||
|
||||
#include "ExpressionParser.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "DiagnosticsBase.h"
|
||||
#include "Lexer.h"
|
||||
#include "Token.h"
|
||||
#include "common/mathutil.h"
|
||||
|
||||
typedef int32_t YYSTYPE;
|
||||
typedef uint32_t UNSIGNED_TYPE;
|
||||
|
||||
#define YYENABLE_NLS 0
|
||||
#define YYLTYPE_IS_TRIVIAL 1
|
||||
#define YYSTYPE_IS_TRIVIAL 1
|
||||
#define YYSTYPE_IS_DECLARED 1
|
||||
|
||||
namespace {
|
||||
struct Context
|
||||
{
|
||||
pp::Diagnostics* diagnostics;
|
||||
pp::Lexer* lexer;
|
||||
pp::Token* token;
|
||||
int* result;
|
||||
bool parsePresetToken;
|
||||
|
||||
pp::ExpressionParser::ErrorSettings errorSettings;
|
||||
bool *valid;
|
||||
|
||||
void startIgnoreErrors() { ++ignoreErrors; }
|
||||
void endIgnoreErrors() { --ignoreErrors; }
|
||||
|
||||
bool isIgnoringErrors() { return ignoreErrors > 0; }
|
||||
|
||||
int ignoreErrors;
|
||||
};
|
||||
} // namespace
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
%name-prefix "pp"
|
||||
%parse-param {Context *context}
|
||||
%lex-param {Context *context}
|
||||
|
||||
%{
|
||||
static int yylex(YYSTYPE* lvalp, Context* context);
|
||||
static void yyerror(Context* context, const char* reason);
|
||||
%}
|
||||
|
||||
%token TOK_CONST_INT
|
||||
%token TOK_IDENTIFIER
|
||||
%left TOK_OP_OR
|
||||
%left TOK_OP_AND
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
%left TOK_OP_EQ TOK_OP_NE
|
||||
%left '<' '>' TOK_OP_LE TOK_OP_GE
|
||||
%left TOK_OP_LEFT TOK_OP_RIGHT
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%right TOK_UNARY
|
||||
|
||||
%%
|
||||
|
||||
input
|
||||
: expression {
|
||||
*(context->result) = static_cast<int>($1);
|
||||
YYACCEPT;
|
||||
}
|
||||
;
|
||||
|
||||
expression
|
||||
: TOK_CONST_INT
|
||||
| TOK_IDENTIFIER {
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
// This rule should be applied right after the token is lexed, so we can
|
||||
// refer to context->token in the error message.
|
||||
context->diagnostics->report(context->errorSettings.unexpectedIdentifier,
|
||||
context->token->location, context->token->text);
|
||||
*(context->valid) = false;
|
||||
}
|
||||
$$ = $1;
|
||||
}
|
||||
| expression TOK_OP_OR {
|
||||
if ($1 != 0)
|
||||
{
|
||||
// Ignore errors in the short-circuited part of the expression.
|
||||
// ESSL3.00 section 3.4:
|
||||
// If an operand is not evaluated, the presence of undefined identifiers
|
||||
// in the operand will not cause an error.
|
||||
// Unevaluated division by zero should not cause an error either.
|
||||
context->startIgnoreErrors();
|
||||
}
|
||||
} expression {
|
||||
if ($1 != 0)
|
||||
{
|
||||
context->endIgnoreErrors();
|
||||
$$ = static_cast<YYSTYPE>(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 || $4;
|
||||
}
|
||||
}
|
||||
| expression TOK_OP_AND {
|
||||
if ($1 == 0)
|
||||
{
|
||||
// Ignore errors in the short-circuited part of the expression.
|
||||
// ESSL3.00 section 3.4:
|
||||
// If an operand is not evaluated, the presence of undefined identifiers
|
||||
// in the operand will not cause an error.
|
||||
// Unevaluated division by zero should not cause an error either.
|
||||
context->startIgnoreErrors();
|
||||
}
|
||||
} expression {
|
||||
if ($1 == 0)
|
||||
{
|
||||
context->endIgnoreErrors();
|
||||
$$ = static_cast<YYSTYPE>(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 && $4;
|
||||
}
|
||||
}
|
||||
| expression '|' expression {
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
| expression '^' expression {
|
||||
$$ = $1 ^ $3;
|
||||
}
|
||||
| expression '&' expression {
|
||||
$$ = $1 & $3;
|
||||
}
|
||||
| expression TOK_OP_NE expression {
|
||||
$$ = $1 != $3;
|
||||
}
|
||||
| expression TOK_OP_EQ expression {
|
||||
$$ = $1 == $3;
|
||||
}
|
||||
| expression TOK_OP_GE expression {
|
||||
$$ = $1 >= $3;
|
||||
}
|
||||
| expression TOK_OP_LE expression {
|
||||
$$ = $1 <= $3;
|
||||
}
|
||||
| expression '>' expression {
|
||||
$$ = $1 > $3;
|
||||
}
|
||||
| expression '<' expression {
|
||||
$$ = $1 < $3;
|
||||
}
|
||||
| expression TOK_OP_RIGHT expression {
|
||||
if ($3 < 0 || $3 > 31)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << $1 << " >> " << $3;
|
||||
std::string text = stream.str();
|
||||
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
||||
context->token->location,
|
||||
text.c_str());
|
||||
*(context->valid) = false;
|
||||
}
|
||||
$$ = static_cast<YYSTYPE>(0);
|
||||
}
|
||||
else if ($1 < 0)
|
||||
{
|
||||
// Logical shift right.
|
||||
$$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 >> $3;
|
||||
}
|
||||
}
|
||||
| expression TOK_OP_LEFT expression {
|
||||
if ($3 < 0 || $3 > 31)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << $1 << " << " << $3;
|
||||
std::string text = stream.str();
|
||||
context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT,
|
||||
context->token->location,
|
||||
text.c_str());
|
||||
*(context->valid) = false;
|
||||
}
|
||||
$$ = static_cast<YYSTYPE>(0);
|
||||
}
|
||||
else if ($1 < 0)
|
||||
{
|
||||
// Logical shift left.
|
||||
$$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3);
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 << $3;
|
||||
}
|
||||
}
|
||||
| expression '-' expression {
|
||||
$$ = gl::WrappingDiff<YYSTYPE>($1, $3);
|
||||
}
|
||||
| expression '+' expression {
|
||||
$$ = gl::WrappingSum<YYSTYPE>($1, $3);
|
||||
}
|
||||
| expression '%' expression {
|
||||
if ($3 == 0)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << $1 << " % " << $3;
|
||||
std::string text = stream.str();
|
||||
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
|
||||
context->token->location,
|
||||
text.c_str());
|
||||
*(context->valid) = false;
|
||||
}
|
||||
$$ = static_cast<YYSTYPE>(0);
|
||||
}
|
||||
else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
|
||||
{
|
||||
// Check for the special case where the minimum representable number is
|
||||
// divided by -1. If left alone this has undefined results.
|
||||
$$ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 % $3;
|
||||
}
|
||||
}
|
||||
| expression '/' expression {
|
||||
if ($3 == 0)
|
||||
{
|
||||
if (!context->isIgnoringErrors())
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << $1 << " / " << $3;
|
||||
std::string text = stream.str();
|
||||
context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
|
||||
context->token->location,
|
||||
text.c_str());
|
||||
*(context->valid) = false;
|
||||
}
|
||||
$$ = static_cast<YYSTYPE>(0);
|
||||
}
|
||||
else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1))
|
||||
{
|
||||
// Check for the special case where the minimum representable number is
|
||||
// divided by -1. If left alone this leads to integer overflow in C++, which
|
||||
// has undefined results.
|
||||
$$ = std::numeric_limits<YYSTYPE>::max();
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = $1 / $3;
|
||||
}
|
||||
}
|
||||
| expression '*' expression {
|
||||
$$ = gl::WrappingMul($1, $3);
|
||||
}
|
||||
| '!' expression %prec TOK_UNARY {
|
||||
$$ = ! $2;
|
||||
}
|
||||
| '~' expression %prec TOK_UNARY {
|
||||
$$ = ~ $2;
|
||||
}
|
||||
| '-' expression %prec TOK_UNARY {
|
||||
// Check for negation of minimum representable integer to prevent undefined signed int
|
||||
// overflow.
|
||||
if ($2 == std::numeric_limits<YYSTYPE>::min())
|
||||
{
|
||||
$$ = std::numeric_limits<YYSTYPE>::min();
|
||||
}
|
||||
else
|
||||
{
|
||||
$$ = -$2;
|
||||
}
|
||||
}
|
||||
| '+' expression %prec TOK_UNARY {
|
||||
$$ = + $2;
|
||||
}
|
||||
| '(' expression ')' {
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
int yylex(YYSTYPE *lvalp, Context *context)
|
||||
{
|
||||
pp::Token *token = context->token;
|
||||
if (!context->parsePresetToken)
|
||||
{
|
||||
context->lexer->lex(token);
|
||||
}
|
||||
context->parsePresetToken = false;
|
||||
|
||||
int type = 0;
|
||||
|
||||
switch (token->type)
|
||||
{
|
||||
case pp::Token::CONST_INT: {
|
||||
unsigned int val = 0;
|
||||
int testVal = 0;
|
||||
if (!token->uValue(&val) || (!token->iValue(&testVal) &&
|
||||
context->errorSettings.integerLiteralsMustFit32BitSignedRange))
|
||||
{
|
||||
context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW,
|
||||
token->location, token->text);
|
||||
*(context->valid) = false;
|
||||
}
|
||||
*lvalp = static_cast<YYSTYPE>(val);
|
||||
type = TOK_CONST_INT;
|
||||
break;
|
||||
}
|
||||
case pp::Token::IDENTIFIER:
|
||||
*lvalp = static_cast<YYSTYPE>(-1);
|
||||
type = TOK_IDENTIFIER;
|
||||
break;
|
||||
case pp::Token::OP_OR:
|
||||
type = TOK_OP_OR;
|
||||
break;
|
||||
case pp::Token::OP_AND:
|
||||
type = TOK_OP_AND;
|
||||
break;
|
||||
case pp::Token::OP_NE:
|
||||
type = TOK_OP_NE;
|
||||
break;
|
||||
case pp::Token::OP_EQ:
|
||||
type = TOK_OP_EQ;
|
||||
break;
|
||||
case pp::Token::OP_GE:
|
||||
type = TOK_OP_GE;
|
||||
break;
|
||||
case pp::Token::OP_LE:
|
||||
type = TOK_OP_LE;
|
||||
break;
|
||||
case pp::Token::OP_RIGHT:
|
||||
type = TOK_OP_RIGHT;
|
||||
break;
|
||||
case pp::Token::OP_LEFT:
|
||||
type = TOK_OP_LEFT;
|
||||
break;
|
||||
case '|':
|
||||
case '^':
|
||||
case '&':
|
||||
case '>':
|
||||
case '<':
|
||||
case '-':
|
||||
case '+':
|
||||
case '%':
|
||||
case '/':
|
||||
case '*':
|
||||
case '!':
|
||||
case '~':
|
||||
case '(':
|
||||
case ')':
|
||||
type = token->type;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
void yyerror(Context *context, const char *reason)
|
||||
{
|
||||
context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION,
|
||||
context->token->location,
|
||||
reason);
|
||||
}
|
||||
|
||||
namespace pp {
|
||||
|
||||
ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics)
|
||||
: mLexer(lexer),
|
||||
mDiagnostics(diagnostics)
|
||||
{
|
||||
}
|
||||
|
||||
bool ExpressionParser::parse(Token *token,
|
||||
int *result,
|
||||
bool parsePresetToken,
|
||||
const ErrorSettings &errorSettings,
|
||||
bool *valid)
|
||||
{
|
||||
Context context;
|
||||
context.diagnostics = mDiagnostics;
|
||||
context.lexer = mLexer;
|
||||
context.token = token;
|
||||
context.result = result;
|
||||
context.ignoreErrors = 0;
|
||||
context.parsePresetToken = parsePresetToken;
|
||||
context.errorSettings = errorSettings;
|
||||
context.valid = valid;
|
||||
int ret = yyparse(&context);
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, "");
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, "");
|
||||
break;
|
||||
}
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
} // namespace pp
|
|
@ -1,115 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2011 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 "compiler/preprocessor/Input.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace pp
|
||||
{
|
||||
|
||||
Input::Input() : mCount(0), mString(0)
|
||||
{
|
||||
}
|
||||
|
||||
Input::Input(size_t count, const char *const string[], const int length[])
|
||||
: mCount(count), mString(string)
|
||||
{
|
||||
mLength.reserve(mCount);
|
||||
for (size_t i = 0; i < mCount; ++i)
|
||||
{
|
||||
int len = length ? length[i] : -1;
|
||||
mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);
|
||||
}
|
||||
}
|
||||
|
||||
const char *Input::skipChar()
|
||||
{
|
||||
// This function should only be called when there is a character to skip.
|
||||
ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
|
||||
++mReadLoc.cIndex;
|
||||
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
|
||||
{
|
||||
++mReadLoc.sIndex;
|
||||
mReadLoc.cIndex = 0;
|
||||
}
|
||||
if (mReadLoc.sIndex >= mCount)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return mString[mReadLoc.sIndex] + mReadLoc.cIndex;
|
||||
}
|
||||
|
||||
size_t Input::read(char *buf, size_t maxSize, int *lineNo)
|
||||
{
|
||||
size_t nRead = 0;
|
||||
// The previous call to read might have stopped copying the string when encountering a line
|
||||
// continuation. Check for this possibility first.
|
||||
if (mReadLoc.sIndex < mCount && maxSize > 0)
|
||||
{
|
||||
const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex;
|
||||
if ((*c) == '\\')
|
||||
{
|
||||
c = skipChar();
|
||||
if (c != nullptr && (*c) == '\n')
|
||||
{
|
||||
// Line continuation of backslash + newline.
|
||||
skipChar();
|
||||
++(*lineNo);
|
||||
}
|
||||
else if (c != nullptr && (*c) == '\r')
|
||||
{
|
||||
// Line continuation. Could be backslash + '\r\n' or just backslash + '\r'.
|
||||
c = skipChar();
|
||||
if (c != nullptr && (*c) == '\n')
|
||||
{
|
||||
skipChar();
|
||||
}
|
||||
++(*lineNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not line continuation, so write the skipped backslash to buf.
|
||||
*buf = '\\';
|
||||
++nRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t maxRead = maxSize;
|
||||
while ((nRead < maxRead) && (mReadLoc.sIndex < mCount))
|
||||
{
|
||||
size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
|
||||
size = std::min(size, maxSize);
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
// Stop if a possible line continuation is encountered.
|
||||
// It will be processed on the next call on input, which skips it
|
||||
// and increments line number if necessary.
|
||||
if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\')
|
||||
{
|
||||
size = i;
|
||||
maxRead = nRead + size; // Stop reading right before the backslash.
|
||||
}
|
||||
}
|
||||
std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
|
||||
nRead += size;
|
||||
mReadLoc.cIndex += size;
|
||||
|
||||
// Advance string if we reached the end of current string.
|
||||
if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
|
||||
{
|
||||
++mReadLoc.sIndex;
|
||||
mReadLoc.cIndex = 0;
|
||||
}
|
||||
}
|
||||
return nRead;
|
||||
}
|
||||
|
||||
} // namespace pp
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче