From 4a8f1839eafeaf107ea3b3f59c35137116e69712 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Dec 2016 17:36:38 +0100 Subject: [PATCH 01/16] 1.9: change to support .whl distribution (putting panda DLLs in panda3d/ dir) --- .../extensions_native/extension_native_helpers.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/direct/src/extensions_native/extension_native_helpers.py b/direct/src/extensions_native/extension_native_helpers.py index 20afc7ddef..e17457b872 100644 --- a/direct/src/extensions_native/extension_native_helpers.py +++ b/direct/src/extensions_native/extension_native_helpers.py @@ -50,9 +50,18 @@ if sys.platform == "win32": filename = "libpandaexpress%s%s" % (dll_suffix, dll_ext) for dir in sys.path + [sys.prefix]: lib = os.path.join(dir, filename) - if (os.path.exists(lib)): + if os.path.exists(lib): target = dir - if target == None: + + # Perhaps it is in the same directory as panda3d/core.pyd ? + if target is None: + for dir in sys.path: + lib = os.path.join(dir, 'panda3d', filename) + if os.path.exists(lib): + target = os.path.join(dir, 'panda3d') + break + + if target is None: message = "Cannot find %s" % (filename) raise ImportError(message) From 2b6e192e5aeb9c1b5078815c15735698f4ed1b6b Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 3 Dec 2016 01:04:35 +0100 Subject: [PATCH 02/16] Protect against overallocation when reading corrupt texture from bam --- panda/src/gobj/texture.cxx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index fa16fa7ab8..bcabaa7a8c 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -8271,6 +8271,14 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) { cdata->_simple_image_date_generated = scan.get_int32(); size_t u_size = scan.get_uint32(); + + // Protect against large allocation. + if (u_size > scan.get_remaining_size()) { + gobj_cat.error() + << "simple RAM image extends past end of datagram, is texture corrupt?\n"; + return; + } + PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type()); scan.extract_bytes(image.p(), u_size); @@ -8327,6 +8335,14 @@ do_fillin_rawdata(CData *cdata, DatagramIterator &scan, BamReader *manager) { // fill the cdata->_image buffer with image data size_t u_size = scan.get_uint32(); + + // Protect against large allocation. + if (u_size > scan.get_remaining_size()) { + gobj_cat.error() + << "RAM image " << n << " extends past end of datagram, is texture corrupt?\n"; + return; + } + PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type()); scan.extract_bytes(image.p(), u_size); From 84789ecdd18a3aadd3d6a8cb0ed17bd1acaea531 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 4 Dec 2016 21:28:52 +0100 Subject: [PATCH 03/16] Fix GL compile error on Mac OS X --- panda/src/glstuff/glGraphicsStateGuardian_src.h | 1 + 1 file changed, 1 insertion(+) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 8080670fc5..fe8cff8b59 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -247,6 +247,7 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VPROC) (GLuint index, const GLuin typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VPROC) (GLuint index, GLenum pname, GLuint64EXT *params); typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); #endif // OPENGLES #endif // __EDG__ From a056543d5a3863d930535b0f9ad27600f73c5cd6 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Dec 2016 02:02:25 +0100 Subject: [PATCH 04/16] Support push_macro and pop_macro in cppparser --- dtool/src/cppparser/cppPreprocessor.cxx | 33 ++++++++++++++++++++++++- dtool/src/cppparser/cppPreprocessor.h | 3 +++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/dtool/src/cppparser/cppPreprocessor.cxx b/dtool/src/cppparser/cppPreprocessor.cxx index 5df779fc1d..83050d3c41 100644 --- a/dtool/src/cppparser/cppPreprocessor.cxx +++ b/dtool/src/cppparser/cppPreprocessor.cxx @@ -1461,7 +1461,6 @@ handle_define_directive(const string &args, const YYLTYPE &loc) { CPPManifest *other = result.first->second; warning("redefinition of macro '" + manifest->_name + "'", loc); warning("previous definition is here", other->_loc); - delete other; result.first->second = manifest; } } @@ -1679,6 +1678,38 @@ handle_pragma_directive(const string &args, const YYLTYPE &loc) { assert(it != _parsed_files.end()); it->_pragma_once = true; } + + char macro[64]; + if (sscanf(args.c_str(), "push_macro ( \"%63[^\"]\" )", macro) == 1) { + // We just mark it as pushed for now, so that the next time someone tries + // to override it, we save the old value. + Manifests::iterator mi = _manifests.find(macro); + if (mi != _manifests.end()) { + _manifest_stack[macro].push_back(mi->second); + } else { + _manifest_stack[macro].push_back(NULL); + } + + } else if (sscanf(args.c_str(), "pop_macro ( \"%63[^\"]\" )", macro) == 1) { + ManifestStack &stack = _manifest_stack[macro]; + if (stack.size() > 0) { + CPPManifest *manifest = stack.back(); + stack.pop_back(); + Manifests::iterator mi = _manifests.find(macro); + if (manifest == NULL) { + // It was undefined when it was pushed, so make it undefined again. + if (mi != _manifests.end()) { + _manifests.erase(mi); + } + } else if (mi != _manifests.end()) { + mi->second = manifest; + } else { + _manifests.insert(Manifests::value_type(macro, manifest)); + } + } else { + warning("pop_macro without matching push_macro", loc); + } + } } /** diff --git a/dtool/src/cppparser/cppPreprocessor.h b/dtool/src/cppparser/cppPreprocessor.h index 74ff8edcf1..e375b259dd 100644 --- a/dtool/src/cppparser/cppPreprocessor.h +++ b/dtool/src/cppparser/cppPreprocessor.h @@ -72,6 +72,9 @@ public: typedef map Manifests; Manifests _manifests; + typedef pvector ManifestStack; + map _manifest_stack; + pvector _quote_include_kind; DSearchPath _quote_include_path; DSearchPath _angle_include_path; From 46c8990f40dd0d9e0fddb5a8c1e92acf4b7e0cae Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Dec 2016 12:55:13 -0500 Subject: [PATCH 05/16] Switch to clang by default on Mac; drop burden of supporting GCC 4.2 Also get rid of that annoying message about -pthread in clang. --- makepanda/makepanda.py | 9 ++++----- makepanda/makepandacore.py | 10 ++++++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index bade6c8288..6d0bd9638c 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1686,11 +1686,7 @@ def CompileLink(dll, obj, opts): if 'NOARCH:' + arch.upper() not in opts: cmd += " -arch %s" % arch - if "SYSROOT" in SDK: - cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"]) - - # Android-specific flags. - if GetTarget() == 'android': + elif GetTarget() == 'android': cmd += " -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now" if GetTargetArch() == 'armv7a': cmd += " -march=armv7-a -Wl,--fix-cortex-a8" @@ -1698,6 +1694,9 @@ def CompileLink(dll, obj, opts): else: cmd += " -pthread" + if "SYSROOT" in SDK: + cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"]) + if LDFLAGS != "": cmd += " " + LDFLAGS diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 2b9e9d4a32..b9899f6adb 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -396,10 +396,16 @@ def CrossCompiling(): return GetTarget() != GetHost() def GetCC(): - return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc') + if TARGET == 'darwin': + return os.environ.get('CC', TOOLCHAIN_PREFIX + 'clang') + else: + return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc') def GetCXX(): - return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++') + if TARGET == 'darwin': + return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'clang++') + else: + return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++') def GetStrip(): # Hack From 83507e413fa34d0edc4af6c4c1aa0d7b6f60220d Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Dec 2016 16:30:44 -0500 Subject: [PATCH 06/16] Fix Mac OS X Snow Leopard build --- direct/src/showbase/PythonUtil.py | 37 ++++++++++++++++++++++++++++++- makepanda/makepanda.py | 2 +- makepanda/makepandacore.py | 5 +++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index ebf8bce63f..0c850f51a0 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/direct/src/showbase/PythonUtil.py @@ -38,7 +38,6 @@ import os import sys import random import time -import importlib __report_indent = 3 @@ -61,6 +60,42 @@ def Functor(function, *args, **kArgs): return functor """ +try: + import importlib +except ImportError: + # Backward compatibility for Python 2.6. + def _resolve_name(name, package, level): + if not hasattr(package, 'rindex'): + raise ValueError("'package' not set to a string") + dot = len(package) + for x in xrange(level, 1, -1): + try: + dot = package.rindex('.', 0, dot) + except ValueError: + raise ValueError("attempted relative import beyond top-level " + "package") + return "%s.%s" % (package[:dot], name) + + def import_module(name, package=None): + if name.startswith('.'): + if not package: + raise TypeError("relative imports require the 'package' argument") + level = 0 + for character in name: + if character != '.': + break + level += 1 + name = _resolve_name(name[level:], package, level) + __import__(name) + return sys.modules[name] + + imp = import_module('imp') + importlib = imp.new_module("importlib") + importlib._resolve_name = _resolve_name + importlib.import_module = import_module + sys.modules['importlib'] = importlib + + class Functor: def __init__(self, function, *args, **kargs): assert callable(function), "function should be a callable obj" diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 6d0bd9638c..990c32f5e5 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -4599,7 +4599,7 @@ if (GetTarget() == 'darwin' and PkgSkip("COCOA")==0 and PkgSkip("GL")==0 and not if (PkgSkip('PANDAFX')==0): TargetAdd('libpandagl.dll', input='libpandafx.dll') TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS) - TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA']) + TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA', 'CARBON']) # # DIRECTORY: panda/src/osxdisplay/ diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index b9899f6adb..2eb4342b06 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -2002,6 +2002,11 @@ def SdkLocatePython(prefer_thirdparty_python=False): SDK["PYTHONVERSION"] = "python" + ver SDK["PYTHONEXEC"] = "/System/Library/Frameworks/Python.framework/Versions/" + ver + "/bin/python" + ver + # Avoid choosing the one in the thirdparty package dir. + PkgSetCustomLocation("PYTHON") + IncDirectory("PYTHON", py_fwx + "/include") + LibDirectory("PYTHON", "%s/usr/lib" % (SDK.get("MACOSX", ""))) + if sys.version[:3] != ver: print("Warning: building with Python %s instead of %s since you targeted a specific Mac OS X version." % (ver, sys.version[:3])) From c410d812ffed47dea8379db2340a8af7eaac9d6c Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Dec 2016 16:31:44 -0500 Subject: [PATCH 07/16] Remove some settings from dtool_config.h to prevent rebuilds: - HAVE_OPENCV - OPENCV_VER_23 - HAVE_FFMPEG - HAVE_SWSCALE - HAVE_SWRESAMPLE --- makepanda/makepanda.py | 30 ++++++++++++++++++-------- panda/src/ffmpeg/ffmpegAudioCursor.cxx | 2 -- panda/src/ffmpeg/ffmpegAudioCursor.h | 5 ----- panda/src/vision/openCVTexture.cxx | 16 ++++++++++++++ panda/src/vision/openCVTexture.h | 16 +------------- 5 files changed, 38 insertions(+), 31 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 990c32f5e5..2c26091ef4 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2236,11 +2236,7 @@ DTOOL_CONFIG=[ ("HAVE_CG", 'UNDEF', 'UNDEF'), ("HAVE_CGGL", 'UNDEF', 'UNDEF'), ("HAVE_CGDX9", 'UNDEF', 'UNDEF'), - ("HAVE_FFMPEG", 'UNDEF', 'UNDEF'), - ("HAVE_SWSCALE", 'UNDEF', 'UNDEF'), - ("HAVE_SWRESAMPLE", 'UNDEF', 'UNDEF'), ("HAVE_ARTOOLKIT", 'UNDEF', 'UNDEF'), - ("HAVE_OPENCV", 'UNDEF', 'UNDEF'), ("HAVE_DIRECTCAM", 'UNDEF', 'UNDEF'), ("HAVE_SQUISH", 'UNDEF', 'UNDEF'), ("HAVE_CARBON", 'UNDEF', 'UNDEF'), @@ -2295,9 +2291,6 @@ def WriteConfigSettings(): else: dtool_config["HAVE_"+x] = 'UNDEF' - if not PkgSkip("OPENCV"): - dtool_config["OPENCV_VER_23"] = '1' if OPENCV_VER_23 else 'UNDEF' - dtool_config["HAVE_NET"] = '1' if (PkgSkip("NVIDIACG")==0): @@ -4128,8 +4121,20 @@ if (not RUNTIME): # if (PkgSkip("VISION") == 0) and (not RUNTIME): + # We want to know whether we have ffmpeg so that we can override the .avi association. + if not PkgSkip("FFMPEG"): + DefSymbol("OPENCV", "HAVE_FFMPEG") + if not PkgSkip("OPENCV"): + DefSymbol("OPENCV", "HAVE_OPENCV") + if OPENCV_VER_23: + DefSymbol("OPENCV", "OPENCV_VER_23") + OPTS=['DIR:panda/src/vision', 'BUILDING:VISION', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS'] - TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx') + TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx', dep=[ + 'dtool_have_ffmpeg.dat', + 'dtool_have_opencv.dat', + 'dtool_have_directcam.dat', + ]) TargetAdd('libp3vision.dll', input='p3vision_composite1.obj') TargetAdd('libp3vision.dll', input=COMMON_PANDA_LIBS) @@ -4318,8 +4323,15 @@ if (PkgSkip("VRPN")==0 and not RUNTIME): # DIRECTORY: panda/src/ffmpeg # if PkgSkip("FFMPEG") == 0 and not RUNTIME: + if not PkgSkip("SWSCALE"): + DefSymbol("FFMPEG", "HAVE_SWSCALE") + if not PkgSkip("SWRESAMPLE"): + DefSymbol("FFMPEG", "HAVE_SWRESAMPLE") + OPTS=['DIR:panda/src/ffmpeg', 'BUILDING:FFMPEG', 'FFMPEG', 'SWSCALE', 'SWRESAMPLE'] - TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx') + TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx', dep=[ + 'dtool_have_swscale.dat', 'dtool_have_swresample.dat']) + TargetAdd('libp3ffmpeg.dll', input='p3ffmpeg_composite1.obj') TargetAdd('libp3ffmpeg.dll', input=COMMON_PANDA_LIBS) TargetAdd('libp3ffmpeg.dll', opts=OPTS) diff --git a/panda/src/ffmpeg/ffmpegAudioCursor.cxx b/panda/src/ffmpeg/ffmpegAudioCursor.cxx index 2f73cff60c..659925cce3 100644 --- a/panda/src/ffmpeg/ffmpegAudioCursor.cxx +++ b/panda/src/ffmpeg/ffmpegAudioCursor.cxx @@ -50,9 +50,7 @@ FfmpegAudioCursor(FfmpegAudio *src) : _packet_data(0), _format_ctx(0), _audio_ctx(0), -#ifdef HAVE_SWRESAMPLE _resample_ctx(0), -#endif _buffer(0), _buffer_alloc(0), _frame(0) diff --git a/panda/src/ffmpeg/ffmpegAudioCursor.h b/panda/src/ffmpeg/ffmpegAudioCursor.h index 21f79dc62d..ff37fa8bc6 100644 --- a/panda/src/ffmpeg/ffmpegAudioCursor.h +++ b/panda/src/ffmpeg/ffmpegAudioCursor.h @@ -31,10 +31,7 @@ struct AVFormatContext; struct AVCodecContext; struct AVStream; struct AVPacket; - -#ifdef HAVE_SWRESAMPLE struct SwrContext; -#endif /** * A stream that generates a sequence of audio samples. @@ -72,9 +69,7 @@ protected: int _buffer_head; int _buffer_tail; -#ifdef HAVE_SWRESAMPLE SwrContext *_resample_ctx; -#endif public: static TypeHandle get_class_type() { diff --git a/panda/src/vision/openCVTexture.cxx b/panda/src/vision/openCVTexture.cxx index 34c70284b1..7d09636b0c 100644 --- a/panda/src/vision/openCVTexture.cxx +++ b/panda/src/vision/openCVTexture.cxx @@ -21,6 +21,22 @@ #include "bamReader.h" #include "bamCacheRecord.h" +// This symbol is predefined by the Panda3D build system to select whether we +// are using the OpenCV 2.3 or later interface, or if it is not defined, we +// are using the original interface. +#ifdef OPENCV_VER_23 + +#include +// #include +#include + +#else +#include +#include +#include + +#endif // OPENCV_VER_23 + TypeHandle OpenCVTexture::_type_handle; /** diff --git a/panda/src/vision/openCVTexture.h b/panda/src/vision/openCVTexture.h index ad898e51a8..1ad8e11a7a 100644 --- a/panda/src/vision/openCVTexture.h +++ b/panda/src/vision/openCVTexture.h @@ -19,21 +19,7 @@ #include "videoTexture.h" -// This symbol is predefined by the Panda3D build system to select whether we -// are using the OpenCV 2.3 or later interface, or if it is not defined, we -// are using the original interface. -#ifdef OPENCV_VER_23 - -#include -// #include -#include - -#else -#include -#include -#include - -#endif // OPENCV_VER_23 +struct CvCapture; /** * A specialization on VideoTexture that takes its input using the CV library, From 6344c05b18b8f7f32d01e79cab2bd96914a6fd3d Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Dec 2016 17:21:09 -0500 Subject: [PATCH 08/16] Clean up dynamic loading of Win32 funcs, remove makepanda touchinput setting, remove checks for pre-WinXP --- makepanda/makepanda.py | 40 +---- panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 20 ++- panda/src/windisplay/winGraphicsPipe.cxx | 76 ++-------- panda/src/windisplay/winGraphicsPipe.h | 11 -- panda/src/windisplay/winGraphicsWindow.cxx | 162 ++++++++++----------- panda/src/windisplay/winGraphicsWindow.h | 23 ++- 6 files changed, 132 insertions(+), 200 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 2c26091ef4..956e8db52c 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -94,7 +94,6 @@ PkgListSet(["PYTHON", "DIRECT", # Python support "PANDAPARTICLESYSTEM", # Built in particle system "CONTRIB", # Experimental "SSE2", "NEON", # Compiler features - "TOUCHINPUT", # Touchinput interface (requires Windows 7) ]) CheckPandaSourceTree() @@ -170,7 +169,8 @@ def parseopts(args): "version=","lzma","no-python","threads=","outputdir=","override=", "static","host=","debversion=","rpmrelease=","p3dsuffix=","rtdist-version=", "directx-sdk=", "windows-sdk=", "msvc-version=", "clean", "use-icl", - "universal", "target=", "arch=", "git-commit="] + "universal", "target=", "arch=", "git-commit=", + "use-touchinput", "no-touchinput"] anything = 0 optimize = "" target = None @@ -316,18 +316,6 @@ def parseopts(args): print("No Windows SDK version specified. Defaulting to '7.1'.") WINDOWS_SDK = '7.1' - is_win7 = False - if sys.platform == 'win32': - # Note: not available in cygwin. - winver = sys.getwindowsversion() - if winver[0] >= 6 and winver[1] >= 1: - is_win7 = True - - if RUNTIME or not is_win7: - PkgDisable("TOUCHINPUT") - else: - PkgDisable("TOUCHINPUT") - if clean_build and os.path.isdir(GetOutputDir()): print("Deleting %s" % (GetOutputDir())) shutil.rmtree(GetOutputDir()) @@ -1055,14 +1043,11 @@ def CompileCxx(obj,src,opts): cmd += "/favor:blend " cmd += "/wd4996 /wd4275 /wd4273 " - # Enable Windows 7 interfaces if we need Touchinput. - if PkgSkip("TOUCHINPUT") == 0: - cmd += "/DWINVER=0x601 " - else: - cmd += "/DWINVER=0x501 " - # Work around a WinXP/2003 bug when using VS 2015+. - if SDK.get("VISUALSTUDIO_VERSION") == '14.0': - cmd += "/Zc:threadSafeInit- " + # We still target Windows XP. + cmd += "/DWINVER=0x501 " + # Work around a WinXP/2003 bug when using VS 2015+. + if SDK.get("VISUALSTUDIO_VERSION") == '14.0': + cmd += "/Zc:threadSafeInit- " cmd += "/Fo" + obj + " /nologo /c" if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts): @@ -1113,12 +1098,7 @@ def CompileCxx(obj,src,opts): if GetTargetArch() == 'x64': cmd += "/favor:blend " cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 " - - # Enable Windows 7 interfaces if we need Touchinput. - if PkgSkip("TOUCHINPUT") == 0: - cmd += "/DWINVER=0x601 " - else: - cmd += "/DWINVER=0x501 " + cmd += "/DWINVER=0x501 " cmd += "/Fo" + obj + " /c" for x in ipath: cmd += " /I" + x for (opt,dir) in INCDIRECTORIES: @@ -2129,7 +2109,6 @@ DTOOL_CONFIG=[ ("REPORT_OPENSSL_ERRORS", '1', '1'), ("USE_PANDAFILESTREAM", '1', '1'), ("USE_DELETED_CHAIN", '1', '1'), - ("HAVE_WIN_TOUCHINPUT", 'UNDEF', 'UNDEF'), ("HAVE_GLX", 'UNDEF', '1'), ("HAVE_WGL", '1', 'UNDEF'), ("HAVE_DX9", 'UNDEF', 'UNDEF'), @@ -2347,9 +2326,6 @@ def WriteConfigSettings(): if (PkgSkip("PYTHON") != 0): dtool_config["HAVE_ROCKET_PYTHON"] = 'UNDEF' - if (PkgSkip("TOUCHINPUT") == 0 and GetTarget() == "windows"): - dtool_config["HAVE_WIN_TOUCHINPUT"] = '1' - if (GetOptimize() <= 3): dtool_config["HAVE_ROCKET_DEBUGGER"] = '1' diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 8174105f39..c3c0ee0099 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -19,6 +19,16 @@ TypeHandle wdxGraphicsPipe9::_type_handle; +static bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName) { + *pFn = (FARPROC) GetProcAddress(hDLL, szExportedFnName); + if (*pFn == NULL) { + wdxdisplay9_cat.error() + << "GetProcAddr failed for " << szExportedFnName << ", error=" << GetLastError() < 1MB, card is lying and I cant tell what it is #define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF @@ -154,7 +164,10 @@ make_output(const string &name, */ bool wdxGraphicsPipe9:: init() { - if (!MyLoadLib(_hDDrawDLL, "ddraw.dll")) { + _hDDrawDLL = LoadLibrary("ddraw.dll"); + if (_hDDrawDLL == NULL) { + wdxdisplay9_cat.error() + << "LoadLibrary failed for ddraw.dll, error=" << GetLastError() <_physical_memory = memory_status.ullTotalPhys; - display_information->_available_physical_memory = memory_status.ullAvailPhys; - display_information->_page_file_size = memory_status.ullTotalPageFile; - display_information->_available_page_file_size = memory_status.ullAvailPageFile; - display_information->_process_virtual_memory = memory_status.ullTotalVirtual; - display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual; - display_information->_memory_load = memory_status.dwMemoryLoad; - } - } else { - MEMORYSTATUS memory_status; - - memory_status.dwLength = sizeof(MEMORYSTATUS); - GlobalMemoryStatus (&memory_status); - - display_information->_physical_memory = memory_status.dwTotalPhys; - display_information->_available_physical_memory = memory_status.dwAvailPhys; - display_information->_page_file_size = memory_status.dwTotalPageFile; - display_information->_available_page_file_size = memory_status.dwAvailPageFile; - display_information->_process_virtual_memory = memory_status.dwTotalVirtual; - display_information->_available_process_virtual_memory = memory_status.dwAvailVirtual; + memory_status.dwLength = sizeof(MEMORYSTATUSEX); + if (GlobalMemoryStatusEx(&memory_status)) { + display_information->_physical_memory = memory_status.ullTotalPhys; + display_information->_available_physical_memory = memory_status.ullAvailPhys; + display_information->_page_file_size = memory_status.ullTotalPageFile; + display_information->_available_page_file_size = memory_status.ullAvailPageFile; + display_information->_process_virtual_memory = memory_status.ullTotalVirtual; + display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual; display_information->_memory_load = memory_status.dwMemoryLoad; } @@ -687,19 +664,12 @@ WinGraphicsPipe() { _supported_types = OT_window | OT_fullscreen_window; - // these fns arent defined on win95, so get dynamic ptrs to them to avoid - // ugly DLL loader failures on w95 - _pfnTrackMouseEvent = NULL; - - _hUser32 = (HINSTANCE)LoadLibrary("user32.dll"); - if (_hUser32 != NULL) { - _pfnTrackMouseEvent = - (PFN_TRACKMOUSEEVENT)GetProcAddress(_hUser32, "TrackMouseEvent"); - + HMODULE user32 = GetModuleHandleA("user32.dll"); + if (user32 != NULL) { if (dpi_aware) { typedef HRESULT (WINAPI *PFN_SETPROCESSDPIAWARENESS)(Process_DPI_Awareness); PFN_SETPROCESSDPIAWARENESS pfnSetProcessDpiAwareness = - (PFN_SETPROCESSDPIAWARENESS)GetProcAddress(_hUser32, "SetProcessDpiAwarenessInternal"); + (PFN_SETPROCESSDPIAWARENESS)GetProcAddress(user32, "SetProcessDpiAwarenessInternal"); if (pfnSetProcessDpiAwareness == NULL) { if (windisplay_cat.is_debug()) { @@ -908,26 +878,4 @@ lookup_cpu_data() { */ WinGraphicsPipe:: ~WinGraphicsPipe() { - if (_hUser32 != NULL) { - FreeLibrary(_hUser32); - _hUser32 = NULL; - } -} - -bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName) { - *pFn = (FARPROC) GetProcAddress(hDLL, szExportedFnName); - if (*pFn == NULL) { - windisplay_cat.error() << "GetProcAddr failed for " << szExportedFnName << ", error=" << GetLastError() < 1)) { + if (_input_devices.size() > 1) { RAWINPUTDEVICE Rid; Rid.usUsagePage = 0x01; Rid.usUsage = 0x02; Rid.dwFlags = 0;// RIDEV_NOLEGACY; // adds HID mouse and also ignores legacy mouse messages Rid.hwndTarget = _hWnd; - pRegisterRawInputDevices(&Rid, 1, sizeof (Rid)); + RegisterRawInputDevices(&Rid, 1, sizeof (Rid)); } // Create a WindowHandle for ourselves @@ -535,10 +537,23 @@ open_window() { // set us as the focus window for keyboard input set_focus(); + // Try initializing the touch function pointers. + static bool initialized = false; + if (!initialized) { + initialized = true; + HMODULE user32 = GetModuleHandleA("user32.dll"); + if (user32) { + // Introduced in Windows 7. + pRegisterTouchWindow = (PFN_REGISTERTOUCHWINDOW)GetProcAddress(user32, "RegisterTouchWindow"); + pGetTouchInputInfo = (PFN_GETTOUCHINPUTINFO)GetProcAddress(user32, "GetTouchInputInfo"); + pCloseTouchInputHandle = (PFN_CLOSETOUCHINPUTHANDLE)GetProcAddress(user32, "CloseTouchInputHandle"); + } + } + // Register for Win7 touch events. -#ifdef HAVE_WIN_TOUCHINPUT - RegisterTouchWindow(_hWnd, 0); -#endif + if (pRegisterTouchWindow != NULL) { + pRegisterTouchWindow(_hWnd, 0); + } return true; } @@ -563,45 +578,35 @@ initialize_input_devices() { GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse"); add_input_device(device); - // Try initializing the Raw Input function pointers. - if (pRegisterRawInputDevices==0) { - HMODULE user32 = LoadLibrary("user32.dll"); - if (user32) { - pRegisterRawInputDevices = (tRegisterRawInputDevices)GetProcAddress(user32,"RegisterRawInputDevices"); - pGetRawInputDeviceList = (tGetRawInputDeviceList) GetProcAddress(user32,"GetRawInputDeviceList"); - pGetRawInputDeviceInfoA = (tGetRawInputDeviceInfoA) GetProcAddress(user32,"GetRawInputDeviceInfoA"); - pGetRawInputData = (tGetRawInputData) GetProcAddress(user32,"GetRawInputData"); - } - } - - if (pRegisterRawInputDevices==0) return; - if (pGetRawInputDeviceList==0) return; - if (pGetRawInputDeviceInfoA==0) return; - if (pGetRawInputData==0) return; - // Get the number of devices. - if (pGetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) + if (GetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) { return; + } // Allocate the array to hold the DeviceList pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(sizeof(RAWINPUTDEVICELIST) * nInputDevices); - if (pRawInputDeviceList==0) return; + if (pRawInputDeviceList==0) { + return; + } // Fill the Array - if (pGetRawInputDeviceList(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1) + if (GetRawInputDeviceList(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1) { return; + } // Loop through all raw devices and find the raw mice for (int i = 0; i < (int)nInputDevices; i++) { if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) { // Fetch information about specified mouse device. UINT nSize; - if (pGetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0) + if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0) { return; + } char *psName = (char*)alloca(sizeof(TCHAR) * nSize); if (psName == 0) return; - if (pGetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0) + if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0) { return; + } // If it's not an RDP mouse, add it to the list of raw mice. if (strncmp(psName,"\\??\\Root#RDP_MOU#0000#",22)!=0) { @@ -1215,31 +1220,25 @@ adjust_z_order(WindowProperties::ZOrder last_z_order, */ void WinGraphicsWindow:: track_mouse_leaving(HWND hwnd) { - // Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which - // emulates TrackMouseEvent on w95, but that requires another 500K of memory - // to hold that DLL, which is lame just to support w95, which probably has - // other issues anyway WinGraphicsPipe *winpipe; DCAST_INTO_V(winpipe, _pipe); - if (winpipe->_pfnTrackMouseEvent != NULL) { - TRACKMOUSEEVENT tme = { - sizeof(TRACKMOUSEEVENT), - TME_LEAVE, - hwnd, - 0 - }; + TRACKMOUSEEVENT tme = { + sizeof(TRACKMOUSEEVENT), + TME_LEAVE, + hwnd, + 0 + }; - // tell win32 to post WM_MOUSELEAVE msgs - BOOL bSucceeded = winpipe->_pfnTrackMouseEvent(&tme); + // tell win32 to post WM_MOUSELEAVE msgs + BOOL bSucceeded = TrackMouseEvent(&tme); - if ((!bSucceeded) && windisplay_cat.is_debug()) { - windisplay_cat.debug() - << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; - } - - _tracking_mouse_leaving = true; + if (!bSucceeded && windisplay_cat.is_debug()) { + windisplay_cat.debug() + << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; } + + _tracking_mouse_leaving = true; } /** @@ -2067,15 +2066,16 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { } break; -#ifdef HAVE_WIN_TOUCHINPUT case WM_TOUCH: - _numTouches = LOWORD(wparam); - if(_numTouches > MAX_TOUCHES) - _numTouches = MAX_TOUCHES; - GetTouchInputInfo((HTOUCHINPUT)lparam, _numTouches, _touches, sizeof(TOUCHINPUT)); - CloseTouchInputHandle((HTOUCHINPUT)lparam); + _num_touches = LOWORD(wparam); + if (_num_touches > MAX_TOUCHES) { + _num_touches = MAX_TOUCHES; + } + if (pGetTouchInputInfo != 0) { + pGetTouchInputInfo((HTOUCHINPUT)lparam, _num_touches, _touches, sizeof(TOUCHINPUT)); + pCloseTouchInputHandle((HTOUCHINPUT)lparam); + } break; -#endif } // do custom messages processing if any has been set @@ -2607,7 +2607,7 @@ handle_raw_input(HRAWINPUT hraw) { if (hraw == 0) { return; } - if (pGetRawInputData(hraw, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) { + if (GetRawInputData(hraw, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) { return; } @@ -2616,7 +2616,7 @@ handle_raw_input(HRAWINPUT hraw) { return; } - if (pGetRawInputData(hraw, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) { + if (GetRawInputData(hraw, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) { return; } @@ -2973,12 +2973,8 @@ bool WinGraphicsWindow::supports_window_procs() const{ * */ bool WinGraphicsWindow:: -is_touch_event(GraphicsWindowProcCallbackData* callbackData){ -#ifdef HAVE_WIN_TOUCHINPUT +is_touch_event(GraphicsWindowProcCallbackData *callbackData) { return callbackData->get_msg() == WM_TOUCH; -#else - return false; -#endif } /** @@ -2987,11 +2983,7 @@ is_touch_event(GraphicsWindowProcCallbackData* callbackData){ */ int WinGraphicsWindow:: get_num_touches(){ -#ifdef HAVE_WIN_TOUCHINPUT - return _numTouches; -#else - return 0; -#endif + return _num_touches; } /** @@ -2999,8 +2991,9 @@ get_num_touches(){ * */ TouchInfo WinGraphicsWindow:: -get_touch_info(int index){ -#ifdef HAVE_WIN_TOUCHINPUT +get_touch_info(int index) { + nassertr(index >= 0 && index < MAX_TOUCHES, TouchInfo()); + TOUCHINPUT ti = _touches[index]; POINT point; point.x = TOUCH_COORD_TO_PIXEL(ti.x); @@ -3013,7 +3006,4 @@ get_touch_info(int index){ ret.set_id(ti.dwID); ret.set_flags(ti.dwFlags); return ret; -#else - return TouchInfo(); -#endif } diff --git a/panda/src/windisplay/winGraphicsWindow.h b/panda/src/windisplay/winGraphicsWindow.h index 798218052a..ec7e1217ff 100644 --- a/panda/src/windisplay/winGraphicsWindow.h +++ b/panda/src/windisplay/winGraphicsWindow.h @@ -34,8 +34,23 @@ typedef struct { int y; int width; int height; -} -WINDOW_METRICS; +} WINDOW_METRICS; + +#if WINVER < 0x0601 +// Not used on Windows XP, but we still need to define it. +typedef struct tagTOUCHINPUT { + LONG x; + LONG y; + HANDLE hSource; + DWORD dwID; + DWORD dwFlags; + DWORD dwMask; + DWORD dwTime; + ULONG_PTR dwExtraInfo; + DWORD cxContact; + DWORD cyContact; +} TOUCHINPUT, *PTOUCHINPUT; +#endif /** * An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in @@ -177,10 +192,8 @@ private: typedef pset WinProcClasses; WinProcClasses _window_proc_classes; -#ifdef HAVE_WIN_TOUCHINPUT - UINT _numTouches; + UINT _num_touches; TOUCHINPUT _touches[MAX_TOUCHES]; -#endif private: // We need this map to support per-window calls to window_proc(). From b182224463b153420ac4eb1a4ea6c9f86dae7ad5 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Dec 2016 17:22:24 -0500 Subject: [PATCH 09/16] interrogate: fix issues with abstract classes and covariance (fixes EggPolygon constructor) --- dtool/src/cppparser/cppFunctionType.cxx | 9 +++-- dtool/src/cppparser/cppFunctionType.h | 2 +- dtool/src/cppparser/cppStructType.cxx | 54 ++++++++----------------- 3 files changed, 24 insertions(+), 41 deletions(-) diff --git a/dtool/src/cppparser/cppFunctionType.cxx b/dtool/src/cppparser/cppFunctionType.cxx index 371b714c2d..1872ea11f5 100644 --- a/dtool/src/cppparser/cppFunctionType.cxx +++ b/dtool/src/cppparser/cppFunctionType.cxx @@ -326,14 +326,17 @@ as_function_type() { * This is similar to is_equal(), except it is more forgiving: it considers * the functions to be equivalent only if the return type and the types of all * parameters match. + * + * Note that this isn't symmetric to account for covariant return types. */ bool CPPFunctionType:: -is_equivalent_function(const CPPFunctionType &other) const { - if (!_return_type->is_equivalent(*other._return_type)) { +match_virtual_override(const CPPFunctionType &other) const { + if (!_return_type->is_equivalent(*other._return_type) && + !_return_type->is_convertible_to(other._return_type)) { return false; } - if (_flags != other._flags) { + if (((_flags ^ other._flags) & ~(F_override | F_final)) != 0) { return false; } diff --git a/dtool/src/cppparser/cppFunctionType.h b/dtool/src/cppparser/cppFunctionType.h index f08de51e45..1e44681f13 100644 --- a/dtool/src/cppparser/cppFunctionType.h +++ b/dtool/src/cppparser/cppFunctionType.h @@ -84,7 +84,7 @@ public: virtual CPPFunctionType *as_function_type(); - bool is_equivalent_function(const CPPFunctionType &other) const; + bool match_virtual_override(const CPPFunctionType &other) const; CPPIdentifier *_class_owner; diff --git a/dtool/src/cppparser/cppStructType.cxx b/dtool/src/cppparser/cppStructType.cxx index 73712c66ad..afb03dd463 100644 --- a/dtool/src/cppparser/cppStructType.cxx +++ b/dtool/src/cppparser/cppStructType.cxx @@ -378,6 +378,10 @@ is_constructible(const CPPType *given_type) const { } } + if (is_abstract()) { + return false; + } + // Check for a different constructor. CPPFunctionGroup *fgroup = get_constructor(); if (fgroup != (CPPFunctionGroup *)NULL) { @@ -444,6 +448,10 @@ is_destructible() const { */ bool CPPStructType:: is_default_constructible(CPPVisibility min_vis) const { + if (is_abstract()) { + return false; + } + CPPInstance *constructor = get_default_constructor(); if (constructor != (CPPInstance *)NULL) { // It has a default constructor. @@ -498,24 +506,6 @@ is_default_constructible(CPPVisibility min_vis) const { } } - // Check that we don't have pure virtual methods. - CPPScope::Functions::const_iterator fi; - for (fi = _scope->_functions.begin(); - fi != _scope->_functions.end(); - ++fi) { - CPPFunctionGroup *fgroup = (*fi).second; - CPPFunctionGroup::Instances::const_iterator ii; - for (ii = fgroup->_instances.begin(); - ii != fgroup->_instances.end(); - ++ii) { - CPPInstance *inst = (*ii); - if (inst->_storage_class & CPPInstance::SC_pure_virtual) { - // Here's a pure virtual function. - return false; - } - } - } - return true; } @@ -524,6 +514,10 @@ is_default_constructible(CPPVisibility min_vis) const { */ bool CPPStructType:: is_copy_constructible(CPPVisibility min_vis) const { + if (is_abstract()) { + return false; + } + CPPInstance *constructor = get_copy_constructor(); if (constructor != (CPPInstance *)NULL) { // It has a copy constructor. @@ -581,24 +575,6 @@ is_copy_constructible(CPPVisibility min_vis) const { } } - // Check that we don't have pure virtual methods. - CPPScope::Functions::const_iterator fi; - for (fi = _scope->_functions.begin(); - fi != _scope->_functions.end(); - ++fi) { - CPPFunctionGroup *fgroup = (*fi).second; - CPPFunctionGroup::Instances::const_iterator ii; - for (ii = fgroup->_instances.begin(); - ii != fgroup->_instances.end(); - ++ii) { - CPPInstance *inst = (*ii); - if (inst->_storage_class & CPPInstance::SC_pure_virtual) { - // Here's a pure virtual function. - return false; - } - } - } - return true; } @@ -620,6 +596,10 @@ is_move_constructible(CPPVisibility min_vis) const { return false; } + if (is_abstract()) { + return false; + } + return true; } @@ -1214,7 +1194,7 @@ get_virtual_funcs(VFunctions &funcs) const { CPPFunctionType *new_ftype = new_inst->_type->as_function_type(); assert(new_ftype != (CPPFunctionType *)NULL); - if (new_ftype->is_equivalent_function(*base_ftype)) { + if (new_ftype->match_virtual_override(*base_ftype)) { // It's a match! We now know it's virtual. Erase this function // from the list, so we can add it back in below. funcs.erase(vfi); From 3fa5b6b4ee569425ab99e16e4e1aa55273abc0f4 Mon Sep 17 00:00:00 2001 From: tobspr Date: Tue, 6 Dec 2016 18:42:08 +0100 Subject: [PATCH 10/16] Add prc variable to force image bindings as writeonly (#131) --- panda/src/glstuff/glShaderContext_src.cxx | 5 ++++- panda/src/glstuff/glmisc_src.cxx | 5 +++++ panda/src/glstuff/glmisc_src.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index b02ec341df..528b98804c 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -2486,7 +2486,10 @@ update_shader_texture_bindings(ShaderContext *prev) { bool has_write = param->has_write_access(); input._writable = has_write; - if (has_read && has_write) { + if (gl_force_image_bindings_writeonly) { + access = GL_WRITE_ONLY; + + } else if (has_read && has_write) { access = GL_READ_WRITE; } else if (has_read) { diff --git a/panda/src/glstuff/glmisc_src.cxx b/panda/src/glstuff/glmisc_src.cxx index c44a36aaf6..544a5c2c79 100644 --- a/panda/src/glstuff/glmisc_src.cxx +++ b/panda/src/glstuff/glmisc_src.cxx @@ -299,6 +299,11 @@ ConfigVariableBool gl_support_shadow_filter "cards suffered from a broken implementation of the " "shadow map filtering features.")); +ConfigVariableBool gl_force_image_bindings_writeonly + ("gl-force-image-bindings-writeonly", false, + PRC_DESC("Forces all image inputs (not textures!) to be bound as writeonly, " + "to read from an image, rebind it as sampler.")); + ConfigVariableEnum gl_coordinate_system ("gl-coordinate-system", CS_yup_right, PRC_DESC("Which coordinate system to use as the internal " diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index b008aeb8d3..fb8040828f 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -80,6 +80,7 @@ extern ConfigVariableBool gl_fixed_vertex_attrib_locations; extern ConfigVariableBool gl_support_primitive_restart_index; extern ConfigVariableBool gl_support_sampler_objects; extern ConfigVariableBool gl_support_shadow_filter; +extern ConfigVariableBool gl_force_image_bindings_writeonly; extern ConfigVariableEnum gl_coordinate_system; extern EXPCL_GL void CLP(init_classes)(); From e778c529b2afb94024c2aa01912b15c0d93fe83c Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Dec 2016 00:42:44 +0100 Subject: [PATCH 11/16] Implement Python 3.6 fspath protocol; allow passing a pathlib.Path wherever Filename is expected The Python 3.6 fspath protocol allows passing Filename objects into any Python standard library calls that take a path. --- dtool/src/dtoolutil/filename.I | 25 +++--- dtool/src/dtoolutil/filename.h | 13 ++-- panda/src/express/filename_ext.cxx | 119 +++++++++++++++++++++++++++++ panda/src/express/filename_ext.h | 3 + 4 files changed, 145 insertions(+), 15 deletions(-) diff --git a/dtool/src/dtoolutil/filename.I b/dtool/src/dtoolutil/filename.I index 9ab46bf501..9bc23dfca3 100644 --- a/dtool/src/dtoolutil/filename.I +++ b/dtool/src/dtoolutil/filename.I @@ -38,7 +38,6 @@ Filename(const char *filename) { (*this) = filename; } - /** * */ @@ -84,6 +83,20 @@ Filename(Filename &&from) NOEXCEPT : } #endif // USE_MOVE_SEMANTICS +/** + * Creates an empty Filename. + */ +INLINE Filename:: +Filename() : + _dirname_end(0), + _basename_start(0), + _basename_end(string::npos), + _extension_start(string::npos), + _hash_start(string::npos), + _hash_end(string::npos), + _flags(0) { +} + /** * */ @@ -155,14 +168,6 @@ pattern_filename(const string &filename) { return result; } -/** - * - */ -INLINE Filename:: -~Filename() { -} - - /** * */ @@ -233,7 +238,7 @@ operator = (string &&filename) NOEXCEPT { */ INLINE Filename &Filename:: operator = (Filename &&from) NOEXCEPT { - _filename = MOVE(from._filename); + _filename = move(from._filename); _dirname_end = from._dirname_end; _basename_start = from._basename_start; _basename_end = from._basename_end; diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 378bf4fe1c..e0c4b8c414 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -55,20 +55,22 @@ public: }; INLINE Filename(const char *filename); - -PUBLISHED: - INLINE Filename(const string &filename = ""); + INLINE Filename(const string &filename); INLINE Filename(const wstring &filename); INLINE Filename(const Filename ©); - Filename(const Filename &dirname, const Filename &basename); - INLINE ~Filename(); #ifdef USE_MOVE_SEMANTICS INLINE Filename(string &&filename) NOEXCEPT; INLINE Filename(Filename &&from) NOEXCEPT; #endif +PUBLISHED: + INLINE Filename(); + Filename(const Filename &dirname, const Filename &basename); + #ifdef HAVE_PYTHON + EXTENSION(Filename(PyObject *path)); + EXTENSION(PyObject *__reduce__(PyObject *self) const); #endif @@ -118,6 +120,7 @@ PUBLISHED: INLINE char operator [] (size_t n) const; EXTENSION(PyObject *__repr__() const); + EXTENSION(PyObject *__fspath__() const); INLINE string substr(size_t begin) const; INLINE string substr(size_t begin, size_t end) const; diff --git a/panda/src/express/filename_ext.cxx b/panda/src/express/filename_ext.cxx index 70afd0d07d..1c9bf78e7e 100644 --- a/panda/src/express/filename_ext.cxx +++ b/panda/src/express/filename_ext.cxx @@ -14,6 +14,115 @@ #include "filename_ext.h" #ifdef HAVE_PYTHON + +#ifndef CPPPARSER +extern Dtool_PyTypedObject Dtool_Filename; +#endif // CPPPARSER + +/** + * Constructs a Filename object from a str, bytes object, or os.PathLike. + */ +void Extension:: +__init__(PyObject *path) { + nassertv(path != NULL); + nassertv(_this != NULL); + + Py_ssize_t length; + + if (PyUnicode_CheckExact(path)) { + wchar_t *data; +#if PY_VERSION_HEX >= 0x03020000 + data = PyUnicode_AsWideCharString(path, &length); +#else + length = PyUnicode_GET_SIZE(path); + data = (wchar_t *)alloca(sizeof(wchar_t) * (length + 1)); + PyUnicode_AsWideChar((PyUnicodeObject *)path, data, length); +#endif + (*_this) = wstring(data, length); + +#if PY_VERSION_HEX >= 0x03020000 + PyMem_Free(data); +#endif + return; + } + + if (PyBytes_CheckExact(path)) { + char *data; + PyBytes_AsStringAndSize(path, &data, &length); + (*_this) = string(data, length); + return; + } + + if (Py_TYPE(path) == &Dtool_Filename._PyType) { + // Copy constructor. + (*_this) = *((Filename *)((Dtool_PyInstDef *)path)->_ptr_to_object); + return; + } + + PyObject *path_str; + +#if PY_VERSION_HEX >= 0x03060000 + // It must be an os.PathLike object. Check for an __fspath__ method. + PyObject *fspath = PyObject_GetAttrString((PyObject *)Py_TYPE(path), "__fspath__"); + if (fspath == NULL) { + PyErr_Format(PyExc_TypeError, "expected str, bytes or os.PathLike object, not %s", Py_TYPE(path)->tp_name); + return; + } + + path_str = PyObject_CallFunctionObjArgs(fspath, path, NULL); + Py_DECREF(fspath); +#else + // There is no standard path protocol before Python 3.6, but let's try and + // support taking pathlib paths anyway. We don't version check this to + // allow people to use backports of the pathlib module. + if (PyObject_HasAttrString(path, "_format_parsed_parts")) { + path_str = PyObject_Str(path); + } else { +#if PY_VERSION_HEX >= 0x03040000 + PyErr_Format(PyExc_TypeError, "expected str, bytes, Path or Filename object, not %s", Py_TYPE(path)->tp_name); +#elif PY_MAJOR_VERSION >= 3 + PyErr_Format(PyExc_TypeError, "expected str, bytes or Filename object, not %s", Py_TYPE(path)->tp_name); +#else + PyErr_Format(PyExc_TypeError, "expected str or unicode object, not %s", Py_TYPE(path)->tp_name); +#endif + return; + } +#endif + + if (path_str == NULL) { + return; + } + + if (PyUnicode_CheckExact(path_str)) { + wchar_t *data; +#if PY_VERSION_HEX >= 0x03020000 + data = PyUnicode_AsWideCharString(path_str, &length); +#else + length = PyUnicode_GET_SIZE(path_str); + data = (wchar_t *)alloca(sizeof(wchar_t) * (length + 1)); + PyUnicode_AsWideChar((PyUnicodeObject *)path_str, data, length); +#endif + (*_this) = Filename::from_os_specific_w(wstring(data, length)); + +#if PY_VERSION_HEX >= 0x03020000 + PyMem_Free(data); +#endif + + } else if (PyBytes_CheckExact(path_str)) { + char *data; + PyBytes_AsStringAndSize(path_str, &data, &length); + (*_this) = Filename::from_os_specific(string(data, length)); + + } else { +#if PY_MAJOR_VERSION >= 3 + PyErr_Format(PyExc_TypeError, "expected str or bytes object, not %s", Py_TYPE(path_str)->tp_name); +#else + PyErr_Format(PyExc_TypeError, "expected str or unicode object, not %s", Py_TYPE(path_str)->tp_name); +#endif + } + Py_DECREF(path_str); +} + /** * This special Python method is implement to provide support for the pickle * module. @@ -62,6 +171,16 @@ __repr__() const { return result; } +/** + * Allows a Filename object to be passed to any Python function that accepts + * an os.PathLike object. + */ +PyObject *Extension:: +__fspath__() const { + wstring filename = _this->to_os_specific_w(); + return PyUnicode_FromWideChar(filename.data(), (Py_ssize_t)filename.size()); +} + /** * This variant on scan_directory returns a Python list of strings on success, * or None on failure. diff --git a/panda/src/express/filename_ext.h b/panda/src/express/filename_ext.h index c1d5869ec7..1ebeaacc52 100644 --- a/panda/src/express/filename_ext.h +++ b/panda/src/express/filename_ext.h @@ -29,8 +29,11 @@ template<> class Extension : public ExtensionBase { public: + void __init__(PyObject *path); + PyObject *__reduce__(PyObject *self) const; PyObject *__repr__() const; + PyObject *__fspath__() const; PyObject *scan_directory() const; }; From ceee5e9df95d3301ed9d329491737f0e39321a86 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Dec 2016 19:32:01 +0100 Subject: [PATCH 12/16] Show texture names in glBindTexture() calls in spam output --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index dc2c0c45e6..8c355cbb03 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -6188,7 +6188,7 @@ framebuffer_copy_to_texture(Texture *tex, int view, int z, if (GLCAT.is_spam()) { GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n"; + << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n"; } } @@ -11365,7 +11365,7 @@ apply_texture(CLP(TextureContext) *gtc) { glBindTexture(target, gtc->_index); if (GLCAT.is_spam()) { GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n"; + << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *gtc->get_texture() << "\n"; } report_my_gl_errors(); @@ -11663,7 +11663,7 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) { if (GLCAT.is_spam()) { GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n"; + << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n"; } } @@ -12636,14 +12636,14 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { } #endif + Texture *tex = gtc->get_texture(); + glBindTexture(target, gtc->_index); if (GLCAT.is_spam()) { GLCAT.spam() - << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n"; + << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n"; } - Texture *tex = gtc->get_texture(); - GLint wrap_u, wrap_v, wrap_w; GLint minfilter, magfilter; GLfloat border_color[4]; From b1d61b7b10117f8ee0fec99027f57240af39c046 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Dec 2016 19:32:44 +0100 Subject: [PATCH 13/16] Fix back-to-front sorting with gl-coordinate-system set to a custom value --- panda/src/display/graphicsStateGuardian.cxx | 4 ++++ panda/src/display/graphicsStateGuardian.h | 2 +- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 10 ---------- panda/src/glstuff/glGraphicsStateGuardian_src.h | 2 -- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 67fbdb2f6c..fee041f57a 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -147,6 +147,10 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, _coordinate_system = CS_invalid; _internal_transform = TransformState::make_identity(); + if (_internal_coordinate_system == CS_default) { + _internal_coordinate_system = get_default_coordinate_system(); + } + set_coordinate_system(get_default_coordinate_system()); _data_reader = (GeomVertexDataPipelineReader *)NULL; diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 825b03286d..f8c9dabe6b 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -322,7 +322,7 @@ public: virtual void set_state_and_transform(const RenderState *state, const TransformState *transform); - virtual PN_stdfloat compute_distance_to(const LPoint3 &point) const; + PN_stdfloat compute_distance_to(const LPoint3 &point) const; virtual void clear(DrawableRegion *clearable); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 8c355cbb03..80719c2e69 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -6024,16 +6024,6 @@ make_geom_munger(const RenderState *state, Thread *current_thread) { return GeomMunger::register_munger(munger, current_thread); } -/** - * This function will compute the distance to the indicated point, assumed to - * be in eye coordinates, from the camera plane. The point is assumed to be - * in the GSG's internal coordinate system. - */ -PN_stdfloat CLP(GraphicsStateGuardian):: -compute_distance_to(const LPoint3 &point) const { - return -point[2]; -} - /** * Copy the pixels within the indicated display region from the framebuffer * into texture memory. diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index fe8cff8b59..7659ee13e5 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -358,8 +358,6 @@ public: virtual PT(GeomMunger) make_geom_munger(const RenderState *state, Thread *current_thread); - virtual PN_stdfloat compute_distance_to(const LPoint3 &point) const; - virtual void clear(DrawableRegion *region); virtual bool framebuffer_copy_to_texture From 83d54bcdafc9ba5ed9108e8f0619544f4d275c75 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Dec 2016 22:57:53 +0100 Subject: [PATCH 14/16] Try to preserve refresh rate when switching display mode on Windows --- doc/ReleaseNotes | 1 + panda/src/windisplay/winGraphicsWindow.cxx | 27 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index b7462a97d6..a288196f72 100644 --- a/doc/ReleaseNotes +++ b/doc/ReleaseNotes @@ -48,6 +48,7 @@ This issue fixes several bugs that were still found in 1.9.2. * Fix exception when trying to pickle NodePathCollection objects * Fix error when trying to raise vectors to a power * GLSL: fix error when legacy matrix generator inputs are mat3 +* Now tries to preserve refresh rate when switching fullscreen on Windows ------------------------ RELEASE 1.9.2 ------------------------ diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index f270a70f61..0f7e33dc75 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -2357,7 +2357,15 @@ hide_or_show_cursor(bool hide_cursor) { bool WinGraphicsWindow:: find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp, DEVMODE &dm) { + + // Get the current mode. We'll try to match the refresh rate. + DEVMODE cur_dm; + ZeroMemory(&cur_dm, sizeof(cur_dm)); + cur_dm.dmSize = sizeof(cur_dm); + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &cur_dm); + int modenum = 0; + int saved_modenum = -1; while (1) { ZeroMemory(&dm, sizeof(dm)); @@ -2369,11 +2377,28 @@ find_acceptable_display_mode(DWORD dwWidth, DWORD dwHeight, DWORD bpp, if ((dm.dmPelsWidth == dwWidth) && (dm.dmPelsHeight == dwHeight) && (dm.dmBitsPerPel == bpp)) { - return true; + // If this also matches in refresh rate, we're done here. Otherwise, + // save this as a second choice for later. + if (dm.dmDisplayFrequency == cur_dm.dmDisplayFrequency) { + return true; + } else if (saved_modenum == -1) { + saved_modenum = modenum; + } } modenum++; } + // Failed to find an exact match, but we do have a match that didn't match + // the refresh rate. + if (saved_modenum != -1) { + ZeroMemory(&dm, sizeof(dm)); + dm.dmSize = sizeof(dm); + + if (EnumDisplaySettings(NULL, saved_modenum, &dm)) { + return true; + } + } + return false; } From a1338b9ac6171b2fc37f088b8130e5d22b378b54 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Dec 2016 23:00:06 +0100 Subject: [PATCH 15/16] Backport to 1.9: fix for distance sorting with gl-coordinate-system changed --- doc/ReleaseNotes | 1 + panda/src/display/graphicsStateGuardian.cxx | 4 ++++ panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 13 ------------- panda/src/glstuff/glGraphicsStateGuardian_src.h | 2 -- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index a288196f72..03d2dcf92a 100644 --- a/doc/ReleaseNotes +++ b/doc/ReleaseNotes @@ -49,6 +49,7 @@ This issue fixes several bugs that were still found in 1.9.2. * Fix error when trying to raise vectors to a power * GLSL: fix error when legacy matrix generator inputs are mat3 * Now tries to preserve refresh rate when switching fullscreen on Windows +* Fix back-to-front sorting when gl-coordinate-system is changed ------------------------ RELEASE 1.9.2 ------------------------ diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 0a2ae03c1e..d3557fa390 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -148,6 +148,10 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, _coordinate_system = CS_invalid; _internal_transform = TransformState::make_identity(); + if (internal_coordinate_system == CS_default) { + _internal_coordinate_system = get_default_coordinate_system(); + } + set_coordinate_system(get_default_coordinate_system()); _data_reader = (GeomVertexDataPipelineReader *)NULL; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index b70552a032..575d6e202c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -5485,19 +5485,6 @@ make_geom_munger(const RenderState *state, Thread *current_thread) { return GeomMunger::register_munger(munger, current_thread); } -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::compute_distance_to -// Access: Public, Virtual -// Description: This function will compute the distance to the -// indicated point, assumed to be in eye coordinates, -// from the camera plane. The point is assumed to be -// in the GSG's internal coordinate system. -//////////////////////////////////////////////////////////////////// -PN_stdfloat CLP(GraphicsStateGuardian):: -compute_distance_to(const LPoint3 &point) const { - return -point[2]; -} - //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::framebuffer_copy_to_texture // Access: Public, Virtual diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index f8ec534eb2..27fd475724 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -336,8 +336,6 @@ public: virtual PT(GeomMunger) make_geom_munger(const RenderState *state, Thread *current_thread); - virtual PN_stdfloat compute_distance_to(const LPoint3 &point) const; - virtual void clear(DrawableRegion *region); virtual bool framebuffer_copy_to_texture From 32377cb618207f5a5a294934d9c2310d6fb8635e Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Dec 2016 23:04:15 +0100 Subject: [PATCH 16/16] interrogate: fix to allow pointers to forcetyped classes --- dtool/src/interrogate/interfaceMakerPythonNative.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index d4eea3fdff..a844771fa6 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -6142,7 +6142,7 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap, write_python_instance(out, indent_level, return_expr, owns_memory, itype, is_const); } - } else if (TypeManager::is_struct(orig_type->as_pointer_type()->_pointing_at)) { + } else if (TypeManager::is_struct(orig_type->remove_pointer())) { TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)),false); const InterrogateType &itype = idb->get_type(type_index); @@ -6749,6 +6749,8 @@ is_cpp_type_legal(CPPType *in_ctype) { return true; } else if (TypeManager::is_pointer_to_simple(type)) { return true; + } else if (builder.in_forcetype(type->get_local_name(&parser))) { + return true; } else if (TypeManager::is_exported(type)) { return true; } else if (TypeManager::is_pointer_to_PyObject(in_ctype)) {