Browse Source

Merge branch 'master' into shaderpipeline

rdb 5 years ago
parent
commit
9b01e4b052
51 changed files with 891 additions and 587 deletions
  1. 1 1
      .editorconfig
  2. 1 1
      .github/codecov.yml
  3. 2 0
      direct/src/dcparser/dcClass.cxx
  4. 3 2
      direct/src/dcparser/dcClass.h
  5. 3 0
      direct/src/dcparser/dcLexer.cxx.prebuilt
  6. 3 1
      direct/src/dcparser/dcLexer.lxx
  7. 2 0
      direct/src/dcparser/dcbase.h
  8. 0 5
      direct/src/dist/commands.py
  9. 0 1
      direct/src/showbase/ProfileSession.py
  10. 1 1
      dtool/Package.cmake
  11. 432 353
      dtool/src/cppparser/cppBison.cxx.prebuilt
  12. 6 2
      dtool/src/cppparser/cppBison.h.prebuilt
  13. 13 37
      dtool/src/cppparser/cppBison.yxx
  14. 47 9
      dtool/src/cppparser/cppExpression.cxx
  15. 3 1
      dtool/src/cppparser/cppExpression.h
  16. 11 1
      dtool/src/cppparser/cppInstance.cxx
  17. 1 1
      dtool/src/cppparser/cppInstanceIdentifier.cxx
  18. 2 2
      dtool/src/cppparser/cppInstanceIdentifier.h
  19. 15 11
      dtool/src/parser-inc/map
  20. 2 0
      dtool/src/parser-inc/ostream
  21. 9 8
      dtool/src/parser-inc/string
  22. 10 6
      dtool/src/parser-inc/vector
  23. 28 4
      makepanda/makepanda.py
  24. 16 3
      panda/metalibs/pandagl/pandagl.cxx
  25. 2 1
      panda/src/collide/collisionPolygon.h
  26. 1 1
      panda/src/display/frameBufferProperties.cxx
  27. 3 3
      panda/src/downloader/httpClient.I
  28. 7 3
      panda/src/egldisplay/config_egldisplay.cxx
  29. 6 4
      panda/src/egldisplay/config_egldisplay.h
  30. 5 3
      panda/src/egldisplay/eglGraphicsBuffer.cxx
  31. 8 0
      panda/src/egldisplay/eglGraphicsPipe.I
  32. 44 3
      panda/src/egldisplay/eglGraphicsPipe.cxx
  33. 20 10
      panda/src/egldisplay/eglGraphicsPipe.h
  34. 9 4
      panda/src/egldisplay/eglGraphicsPixmap.cxx
  35. 4 0
      panda/src/egldisplay/eglGraphicsPixmap.h
  36. 63 62
      panda/src/egldisplay/eglGraphicsStateGuardian.cxx
  37. 19 20
      panda/src/egldisplay/eglGraphicsStateGuardian.h
  38. 8 3
      panda/src/egldisplay/eglGraphicsWindow.cxx
  39. 4 0
      panda/src/egldisplay/eglGraphicsWindow.h
  40. 8 0
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx
  41. 1 0
      panda/src/glstuff/glGraphicsStateGuardian_src.h
  42. 4 4
      panda/src/grutil/meshDrawer2D.I
  43. 2 2
      panda/src/grutil/meshDrawer2D.h
  44. 12 4
      panda/src/nativenet/buffered_datagramconnection.h
  45. 7 5
      panda/src/pgraph/geomNode.cxx
  46. 6 0
      panda/src/pgraph/pandaNode_ext.cxx
  47. 3 0
      pandatool/src/deploy-stub/deploy-stub.c
  48. 0 1
      samples/fireflies/light.sha
  49. 29 0
      tests/pgraph/test_nodepath.py
  50. 3 2
      tests/putil/test_bitarray.py
  51. 2 2
      tests/putil/test_clockobject.py

+ 1 - 1
.editorconfig

@@ -10,7 +10,7 @@ insert_final_newline = true
 indent_style = space
 indent_style = space
 indent_size = 4
 indent_size = 4
 
 
-[*.{h,c,cxx,cpp,I}]
+[*.{h,c,cxx,cpp,I,T}]
 indent_style = space
 indent_style = space
 indent_size = 2
 indent_size = 2
 
 

+ 1 - 1
.github/codecov.yml

@@ -5,7 +5,7 @@ coverage:
         threshold: 0.1
         threshold: 0.1
     patch:
     patch:
       default:
       default:
-        threshold: 0.1
+        target: 0%
 codecov:
 codecov:
   require_ci_to_pass: true
   require_ci_to_pass: true
   notify:
   notify:

+ 2 - 0
direct/src/dcparser/dcClass.cxx

@@ -77,7 +77,9 @@ DCClass(DCFile *dc_file, const string &name, bool is_struct, bool bogus_class) :
   _number = -1;
   _number = -1;
   _constructor = nullptr;
   _constructor = nullptr;
 
 
+#ifdef WITHIN_PANDA
   _python_class_defs = nullptr;
   _python_class_defs = nullptr;
+#endif
 }
 }
 
 
 /**
 /**

+ 3 - 2
direct/src/dcparser/dcClass.h

@@ -172,6 +172,9 @@ private:
   typedef pmap<int, DCField *> FieldsByIndex;
   typedef pmap<int, DCField *> FieldsByIndex;
   FieldsByIndex _fields_by_index;
   FieldsByIndex _fields_by_index;
 
 
+  friend class DCField;
+
+#ifdef WITHIN_PANDA
   // See pandaNode.h for an explanation of this trick
   // See pandaNode.h for an explanation of this trick
   class PythonClassDefs : public ReferenceCount {
   class PythonClassDefs : public ReferenceCount {
   public:
   public:
@@ -179,8 +182,6 @@ private:
   };
   };
   PT(PythonClassDefs) _python_class_defs;
   PT(PythonClassDefs) _python_class_defs;
 
 
-  friend class DCField;
-#ifdef WITHIN_PANDA
   friend class Extension<DCClass>;
   friend class Extension<DCClass>;
 #endif
 #endif
 };
 };

+ 3 - 0
direct/src/dcparser/dcLexer.cxx.prebuilt

@@ -599,7 +599,10 @@ char *dcyytext;
 #include "dcParser.h"
 #include "dcParser.h"
 #include "dcFile.h"
 #include "dcFile.h"
 #include "dcindent.h"
 #include "dcindent.h"
+
+#ifdef WITHIN_PANDA
 #include "pstrtod.h"
 #include "pstrtod.h"
+#endif
 
 
 
 
 static int yyinput(void);        // declared by flex.
 static int yyinput(void);        // declared by flex.

+ 3 - 1
direct/src/dcparser/dcLexer.lxx

@@ -11,8 +11,10 @@
 #include "dcParser.h"
 #include "dcParser.h"
 #include "dcFile.h"
 #include "dcFile.h"
 #include "dcindent.h"
 #include "dcindent.h"
-#include "pstrtod.h"
 
 
+#ifdef WITHIN_PANDA
+#include "pstrtod.h"
+#endif
 
 
 static int yyinput(void);        // declared by flex.
 static int yyinput(void);        // declared by flex.
 extern "C" int dcyywrap();
 extern "C" int dcyywrap();

+ 2 - 0
direct/src/dcparser/dcbase.h

@@ -70,6 +70,7 @@
 #define BEGIN_PUBLISH
 #define BEGIN_PUBLISH
 #define END_PUBLISH
 #define END_PUBLISH
 #define BLOCKING
 #define BLOCKING
+#define EXTENSION(x)
 
 
 // These control the declspec(dllexport/dllimport) on Windows.  When compiling
 // These control the declspec(dllexport/dllimport) on Windows.  When compiling
 // outside of Panda, we assume we aren't part of a DLL.
 // outside of Panda, we assume we aren't part of a DLL.
@@ -100,6 +101,7 @@ typedef std::string Filename;
 #define pmap std::map
 #define pmap std::map
 #define pset std::set
 #define pset std::set
 #define vector_uchar std::vector<unsigned char>
 #define vector_uchar std::vector<unsigned char>
+#define patof(x) atof(x)
 
 
 #include <stdint.h>
 #include <stdint.h>
 #include <string.h>
 #include <string.h>

+ 0 - 5
direct/src/dist/commands.py

@@ -4,8 +4,6 @@ See the :ref:`distribution` section of the programming manual for information
 on how to use these commands.
 on how to use these commands.
 """
 """
 
 
-from __future__ import print_function
-
 import collections
 import collections
 import os
 import os
 import plistlib
 import plistlib
@@ -31,9 +29,6 @@ import panda3d.core as p3d
 
 
 
 
 if sys.version_info < (3, 0):
 if sys.version_info < (3, 0):
-    # Python 3 defines these subtypes of IOError, but Python 2 doesn't.
-    FileNotFoundError = IOError
-
     # Warn the user.  They might be using Python 2 by accident.
     # Warn the user.  They might be using Python 2 by accident.
     print("=================================================================")
     print("=================================================================")
     print("WARNING: You are using Python 2, which has reached the end of its")
     print("WARNING: You are using Python 2, which has reached the end of its")

+ 0 - 1
direct/src/showbase/ProfileSession.py

@@ -1,4 +1,3 @@
-from __future__ import print_function
 from panda3d.core import TrueClock
 from panda3d.core import TrueClock
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.PythonUtil import (
 from direct.showbase.PythonUtil import (

+ 1 - 1
dtool/Package.cmake

@@ -390,7 +390,7 @@ package_status(SQUISH "libsquish")
 #
 #
 
 
 # Assimp
 # Assimp
-find_package(Assimp QUIET)
+find_package(Assimp QUIET MODULE)
 
 
 package_option(Assimp
 package_option(Assimp
   "Build pandatool with support for loading 3D assets supported by Assimp.")
   "Build pandatool with support for loading 3D assets supported by Assimp.")

File diff suppressed because it is too large
+ 432 - 353
dtool/src/cppparser/cppBison.cxx.prebuilt


+ 6 - 2
dtool/src/cppparser/cppBison.h.prebuilt

@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.5.  */
+/* A Bison parser, made by GNU Bison 3.5.3.  */
 
 
 /* Bison interface for Yacc-like parsers in C
 /* Bison interface for Yacc-like parsers in C
 
 
-   Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
+   Inc.
 
 
    This program is free software: you can redistribute it and/or modify
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
    version 2.2 of Bison.  */
 
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
 #ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
 # define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
 # define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
 /* Debug traces.  */
 /* Debug traces.  */

+ 13 - 37
dtool/src/cppparser/cppBison.yxx

@@ -1891,7 +1891,7 @@ instance_identifier_and_maybe_trailing_return_type:
   }
   }
   $$ = $1;
   $$ = $1;
 }
 }
-        | instance_identifier ':' INTEGER
+        | instance_identifier ':' const_expr
 {
 {
   // Bitfield definition.
   // Bitfield definition.
   $1->_bit_width = $3;
   $1->_bit_width = $3;
@@ -3278,17 +3278,9 @@ no_angle_bracket_const_expr:
 {
 {
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
 }
 }
-        | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
+        | KW_SIZEOF no_angle_bracket_const_expr %prec UNARY
 {
 {
-  CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
-  if (arg == nullptr) {
-    yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
-  } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
-    CPPInstance *inst = arg->as_instance();
-    $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
-  } else {
-    $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
-  }
+  $$ = new CPPExpression(CPPExpression::sizeof_func($2));
 }
 }
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
 {
 {
@@ -3402,9 +3394,9 @@ no_angle_bracket_const_expr:
 {
 {
   $$ = new CPPExpression('f', $1);
   $$ = new CPPExpression('f', $1);
 }
 }
-        | no_angle_bracket_const_expr '.' no_angle_bracket_const_expr
+        | no_angle_bracket_const_expr '.' name
 {
 {
-  $$ = new CPPExpression('.', $1, $3);
+  $$ = new CPPExpression('.', $1, new CPPExpression($3, current_scope, global_scope, current_lexer));
 }
 }
         | no_angle_bracket_const_expr POINTSAT no_angle_bracket_const_expr
         | no_angle_bracket_const_expr POINTSAT no_angle_bracket_const_expr
 {
 {
@@ -3542,17 +3534,9 @@ const_expr:
 {
 {
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
 }
 }
-        | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
+        | KW_SIZEOF const_expr %prec UNARY
 {
 {
-  CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
-  if (arg == nullptr) {
-    yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
-  } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
-    CPPInstance *inst = arg->as_instance();
-    $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
-  } else {
-    $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
-  }
+  $$ = new CPPExpression(CPPExpression::sizeof_func($2));
 }
 }
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
 {
 {
@@ -3704,9 +3688,9 @@ const_expr:
 {
 {
   $$ = new CPPExpression('f', $1);
   $$ = new CPPExpression('f', $1);
 }
 }
-        | const_expr '.' const_expr
+        | const_expr '.' name
 {
 {
-  $$ = new CPPExpression('.', $1, $3);
+  $$ = new CPPExpression('.', $1, new CPPExpression($3, current_scope, global_scope, current_lexer));
 }
 }
         | const_expr POINTSAT const_expr
         | const_expr POINTSAT const_expr
 {
 {
@@ -3886,17 +3870,9 @@ formal_const_expr:
 {
 {
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
   $$ = new CPPExpression(CPPExpression::sizeof_func($3));
 }
 }
-        | KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
+        | KW_SIZEOF formal_const_expr %prec UNARY
 {
 {
-  CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
-  if (arg == nullptr) {
-    yyerror("undefined sizeof argument: " + $3->get_fully_scoped_name(), @3);
-  } else if (arg->get_subtype() == CPPDeclaration::ST_instance) {
-    CPPInstance *inst = arg->as_instance();
-    $$ = new CPPExpression(CPPExpression::sizeof_func(inst->_type));
-  } else {
-    $$ = new CPPExpression(CPPExpression::sizeof_func(arg->as_type()));
-  }
+  $$ = new CPPExpression(CPPExpression::sizeof_func($2));
 }
 }
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
         | KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
 {
 {
@@ -4044,9 +4020,9 @@ formal_const_expr:
 {
 {
   $$ = new CPPExpression('f', $1);
   $$ = new CPPExpression('f', $1);
 }
 }
-        | formal_const_expr '.' const_expr
+        | formal_const_expr '.' name
 {
 {
-  $$ = new CPPExpression('.', $1, $3);
+  $$ = new CPPExpression('.', $1, new CPPExpression($3, current_scope, global_scope, current_lexer));
 }
 }
         | formal_const_expr POINTSAT const_expr
         | formal_const_expr POINTSAT const_expr
 {
 {

+ 47 - 9
dtool/src/cppparser/cppExpression.cxx

@@ -429,12 +429,24 @@ type_trait(int trait, CPPType *type, CPPType *arg) {
 CPPExpression CPPExpression::
 CPPExpression CPPExpression::
 sizeof_func(CPPType *type) {
 sizeof_func(CPPType *type) {
   CPPExpression expr(0);
   CPPExpression expr(0);
-  expr._type = T_sizeof;
+  expr._type = T_sizeof_type;
   expr._u._typecast._to = type;
   expr._u._typecast._to = type;
   expr._u._typecast._op1 = nullptr;
   expr._u._typecast._op1 = nullptr;
   return expr;
   return expr;
 }
 }
 
 
+/**
+ *
+ */
+CPPExpression CPPExpression::
+sizeof_func(CPPExpression *op1) {
+  CPPExpression expr(0);
+  expr._type = T_sizeof_expr;
+  expr._u._typecast._to = nullptr;
+  expr._u._typecast._op1 = op1;
+  return expr;
+}
+
 /**
 /**
  *
  *
  */
  */
@@ -629,7 +641,8 @@ evaluate() const {
   case T_empty_aggregate_init:
   case T_empty_aggregate_init:
   case T_new:
   case T_new:
   case T_default_new:
   case T_default_new:
-  case T_sizeof:
+  case T_sizeof_type:
+  case T_sizeof_expr:
   case T_sizeof_ellipsis:
   case T_sizeof_ellipsis:
     return Result();
     return Result();
 
 
@@ -1058,7 +1071,8 @@ determine_type() const {
   case T_default_new:
   case T_default_new:
     return CPPType::new_type(new CPPPointerType(_u._typecast._to));
     return CPPType::new_type(new CPPPointerType(_u._typecast._to));
 
 
-  case T_sizeof:
+  case T_sizeof_type:
+  case T_sizeof_expr:
   case T_sizeof_ellipsis:
   case T_sizeof_ellipsis:
   case T_alignof:
   case T_alignof:
     // Note: this should actually be size_t, but that is defined as a typedef
     // Note: this should actually be size_t, but that is defined as a typedef
@@ -1334,10 +1348,13 @@ is_fully_specified() const {
   case T_default_construct:
   case T_default_construct:
   case T_empty_aggregate_init:
   case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
-  case T_sizeof:
+  case T_sizeof_type:
   case T_alignof:
   case T_alignof:
     return _u._typecast._to->is_fully_specified();
     return _u._typecast._to->is_fully_specified();
 
 
+  case T_sizeof_expr:
+    return _u._typecast._op1->is_fully_specified();
+
   case T_sizeof_ellipsis:
   case T_sizeof_ellipsis:
     return _u._ident->is_fully_specified();
     return _u._ident->is_fully_specified();
 
 
@@ -1469,7 +1486,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
   case T_default_construct:
   case T_default_construct:
   case T_empty_aggregate_init:
   case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
-  case T_sizeof:
+  case T_sizeof_type:
   case T_alignof:
   case T_alignof:
     rep->_u._typecast._to =
     rep->_u._typecast._to =
       _u._typecast._to->substitute_decl(subst, current_scope, global_scope)
       _u._typecast._to->substitute_decl(subst, current_scope, global_scope)
@@ -1477,6 +1494,13 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
     any_changed = any_changed || (rep->_u._typecast._to != _u._typecast._to);
     any_changed = any_changed || (rep->_u._typecast._to != _u._typecast._to);
     break;
     break;
 
 
+  case T_sizeof_expr:
+    rep->_u._typecast._op1 =
+      _u._typecast._op1->substitute_decl(subst, current_scope, global_scope)
+      ->as_expression();
+    any_changed = any_changed || (rep->_u._typecast._op1 != _u._typecast._op1);
+    break;
+
   case T_trinary_operation:
   case T_trinary_operation:
     rep->_u._op._op3 =
     rep->_u._op._op3 =
       _u._op._op3->substitute_decl(subst, current_scope, global_scope)
       _u._op._op3->substitute_decl(subst, current_scope, global_scope)
@@ -1567,10 +1591,13 @@ is_tbd() const {
   case T_new:
   case T_new:
   case T_default_construct:
   case T_default_construct:
   case T_default_new:
   case T_default_new:
-  case T_sizeof:
+  case T_sizeof_type:
   case T_alignof:
   case T_alignof:
     return _u._typecast._to->is_tbd();
     return _u._typecast._to->is_tbd();
 
 
+  case T_sizeof_expr:
+    return _u._typecast._op1->is_tbd();
+
   case T_trinary_operation:
   case T_trinary_operation:
     if (_u._op._op3->is_tbd()) {
     if (_u._op._op3->is_tbd()) {
       return true;
       return true;
@@ -1807,12 +1834,17 @@ output(std::ostream &out, int indent_level, CPPScope *scope, bool) const {
     out << "())";
     out << "())";
     break;
     break;
 
 
-  case T_sizeof:
+  case T_sizeof_type:
     out << "sizeof(";
     out << "sizeof(";
     _u._typecast._to->output(out, indent_level, scope, false);
     _u._typecast._to->output(out, indent_level, scope, false);
     out << ")";
     out << ")";
     break;
     break;
 
 
+  case T_sizeof_expr:
+    out << "sizeof ";
+    _u._typecast._op1->output(out, indent_level, scope, false);
+    break;
+
   case T_sizeof_ellipsis:
   case T_sizeof_ellipsis:
     out << "sizeof...(";
     out << "sizeof...(";
     _u._ident->output(out, scope);
     _u._ident->output(out, scope);
@@ -2222,10 +2254,13 @@ is_equal(const CPPDeclaration *other) const {
   case T_default_construct:
   case T_default_construct:
   case T_empty_aggregate_init:
   case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
-  case T_sizeof:
+  case T_sizeof_type:
   case T_alignof:
   case T_alignof:
     return _u._typecast._to == ot->_u._typecast._to;
     return _u._typecast._to == ot->_u._typecast._to;
 
 
+  case T_sizeof_expr:
+    return _u._typecast._op1 == ot->_u._typecast._op1;
+
   case T_unary_operation:
   case T_unary_operation:
     return *_u._op._op1 == *ot->_u._op._op1;
     return *_u._op._op1 == *ot->_u._op._op1;
 
 
@@ -2324,10 +2359,13 @@ is_less(const CPPDeclaration *other) const {
   case T_default_construct:
   case T_default_construct:
   case T_empty_aggregate_init:
   case T_empty_aggregate_init:
   case T_default_new:
   case T_default_new:
-  case T_sizeof:
+  case T_sizeof_type:
   case T_alignof:
   case T_alignof:
     return _u._typecast._to < ot->_u._typecast._to;
     return _u._typecast._to < ot->_u._typecast._to;
 
 
+  case T_sizeof_expr:
+    return _u._typecast._op1 < ot->_u._typecast._op1;
+
   case T_trinary_operation:
   case T_trinary_operation:
     if (*_u._op._op3 != *ot->_u._op._op3) {
     if (*_u._op._op3 != *ot->_u._op._op3) {
       return *_u._op._op3 < *ot->_u._op._op3;
       return *_u._op._op3 < *ot->_u._op._op3;

+ 3 - 1
dtool/src/cppparser/cppExpression.h

@@ -52,7 +52,8 @@ public:
     T_empty_aggregate_init,
     T_empty_aggregate_init,
     T_new,
     T_new,
     T_default_new,
     T_default_new,
-    T_sizeof,
+    T_sizeof_type,
+    T_sizeof_expr,
     T_sizeof_ellipsis,
     T_sizeof_ellipsis,
     T_alignof,
     T_alignof,
     T_unary_operation,
     T_unary_operation,
@@ -89,6 +90,7 @@ public:
   static CPPExpression typeid_op(CPPExpression *op1, CPPType *std_type_info);
   static CPPExpression typeid_op(CPPExpression *op1, CPPType *std_type_info);
   static CPPExpression type_trait(int trait, CPPType *type, CPPType *arg = nullptr);
   static CPPExpression type_trait(int trait, CPPType *type, CPPType *arg = nullptr);
   static CPPExpression sizeof_func(CPPType *type);
   static CPPExpression sizeof_func(CPPType *type);
+  static CPPExpression sizeof_func(CPPExpression *op1);
   static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
   static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
   static CPPExpression alignof_func(CPPType *type);
   static CPPExpression alignof_func(CPPType *type);
   static CPPExpression lambda(CPPClosureType *type);
   static CPPExpression lambda(CPPClosureType *type);

+ 11 - 1
dtool/src/cppparser/cppInstance.cxx

@@ -74,7 +74,17 @@ CPPInstance(CPPType *type, CPPInstanceIdentifier *ii, int storage_class,
   ii->_ident = nullptr;
   ii->_ident = nullptr;
   _storage_class = storage_class;
   _storage_class = storage_class;
   _initializer = nullptr;
   _initializer = nullptr;
-  _bit_width = ii->_bit_width;
+
+  if (ii->_bit_width != nullptr) {
+    CPPExpression::Result result = ii->_bit_width->evaluate();
+    if (result._type != CPPExpression::RT_error) {
+      _bit_width = ii->_bit_width->evaluate().as_integer();
+    } else {
+      _bit_width = -1;
+    }
+  } else {
+    _bit_width = -1;
+  }
 
 
   CPPParameterList *params = ii->get_initializer();
   CPPParameterList *params = ii->get_initializer();
   if (params != nullptr) {
   if (params != nullptr) {

+ 1 - 1
dtool/src/cppparser/cppInstanceIdentifier.cxx

@@ -82,7 +82,7 @@ initializer_type(CPPParameterList *params) {
 CPPInstanceIdentifier::
 CPPInstanceIdentifier::
 CPPInstanceIdentifier(CPPIdentifier *ident) :
 CPPInstanceIdentifier(CPPIdentifier *ident) :
   _ident(ident),
   _ident(ident),
-  _bit_width(-1),
+  _bit_width(nullptr),
   _packed(false) {
   _packed(false) {
 }
 }
 
 

+ 2 - 2
dtool/src/cppparser/cppInstanceIdentifier.h

@@ -86,8 +86,8 @@ public:
   typedef std::vector<Modifier> Modifiers;
   typedef std::vector<Modifier> Modifiers;
   Modifiers _modifiers;
   Modifiers _modifiers;
 
 
-  // If not -1, indicates a bitfield
-  int _bit_width;
+  // If not null, indicates a bitfield
+  CPPExpression *_bit_width;
 
 
   // Indicates a parameter pack
   // Indicates a parameter pack
   bool _packed;
   bool _packed;

+ 15 - 11
dtool/src/parser-inc/map

@@ -24,19 +24,23 @@
 #include <stdcompare.h>
 #include <stdcompare.h>
 #include <pair>
 #include <pair>
 
 
-template<class key, class element, class compare = less<key> >
+namespace std {
+  template<class T> class allocator;
+}
+
+template<class Key, class Element, class Compare = less<Key>, class Allocator = std::allocator<pair<const Key, T> > >
 class map {
 class map {
 public:
 public:
-  typedef key key_type;
-  typedef element data_type;
-  typedef element mapped_type;
-  typedef pair<const key, element> value_type;
-  typedef compare key_compare;
-
-  typedef element *pointer;
-  typedef const element *const_pointer;
-  typedef element &reference;
-  typedef const element &const_reference;
+  typedef Key key_type;
+  typedef Element data_type;
+  typedef Element mapped_type;
+  typedef pair<const Key, Element> value_type;
+  typedef Compare key_compare;
+
+  typedef Element *pointer;
+  typedef const Element *const_pointer;
+  typedef Element &reference;
+  typedef const Element &const_reference;
 
 
   class iterator;
   class iterator;
   class const_iterator;
   class const_iterator;

+ 2 - 0
dtool/src/parser-inc/ostream

@@ -1,5 +1,7 @@
 #pragma once
 #pragma once
 
 
+#include <iosfwd>
+
 namespace std {
 namespace std {
   template<class CharT, class Traits>
   template<class CharT, class Traits>
   std::basic_ostream<CharT, Traits> &ends(std::basic_ostream<CharT, Traits> &os);
   std::basic_ostream<CharT, Traits> &ends(std::basic_ostream<CharT, Traits> &os);

+ 9 - 8
dtool/src/parser-inc/string

@@ -26,6 +26,7 @@
 
 
 namespace std {
 namespace std {
   template<class charT> struct char_traits;
   template<class charT> struct char_traits;
+  template<class T> class allocator;
 
 
   template<> struct char_traits<char> {
   template<> struct char_traits<char> {
     using char_type = char;
     using char_type = char;
@@ -51,7 +52,7 @@ namespace std {
     using state_type = mbstate_t;
     using state_type = mbstate_t;
   };
   };
 
 
-  template<class ctype>
+  template<class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> >
   class basic_string {
   class basic_string {
   public:
   public:
     struct iterator;
     struct iterator;
@@ -63,17 +64,17 @@ namespace std {
     static const size_t npos = -1;
     static const size_t npos = -1;
 
 
     basic_string();
     basic_string();
-    basic_string(const basic_string<ctype> &copy);
-    void operator = (const basic_string<ctype> &copy);
-    basic_string(const ctype *string);
+    basic_string(const basic_string<CharT> &copy);
+    void operator = (const basic_string<CharT> &copy);
+    basic_string(const CharT *string);
     ~basic_string();
     ~basic_string();
 
 
-    const ctype *c_str() const;
+    const CharT *c_str() const;
     size_t length() const;
     size_t length() const;
 
 
-    ctype at(size_t pos) const;
-    ctype operator[](size_t pos) const;
-    ctype &operator[](size_t pos);
+    CharT at(size_t pos) const;
+    CharT operator[](size_t pos) const;
+    CharT &operator[](size_t pos);
   };
   };
 
 
   typedef basic_string<char> string;
   typedef basic_string<char> string;

+ 10 - 6
dtool/src/parser-inc/vector

@@ -22,17 +22,21 @@
 
 
 #include <stdtypedefs.h>
 #include <stdtypedefs.h>
 
 
+namespace std {
+  template<class T> class allocator;
+}
+
 inline namespace std {
 inline namespace std {
 
 
-template<class element>
+template<class T, class Allocator = std::allocator<T> >
 class vector {
 class vector {
 public:
 public:
-  typedef element value_type;
+  typedef T value_type;
 
 
-  typedef element *pointer;
-  typedef const element *const_pointer;
-  typedef element &reference;
-  typedef const element &const_reference;
+  typedef T *pointer;
+  typedef const T *const_pointer;
+  typedef T &reference;
+  typedef const T &const_reference;
 
 
   typedef pointer iterator;
   typedef pointer iterator;
   typedef const_pointer const_iterator;
   typedef const_pointer const_iterator;

+ 28 - 4
makepanda/makepanda.py

@@ -2390,6 +2390,9 @@ def WriteConfigSettings():
         if int(platform.mac_ver()[0][3]) <= 4:
         if int(platform.mac_ver()[0][3]) <= 4:
             dtool_config["PHAVE_UCONTEXT_H"] = 'UNDEF'
             dtool_config["PHAVE_UCONTEXT_H"] = 'UNDEF'
 
 
+    if PkgSkip("X11"):
+        dtool_config["HAVE_GLX"] = 'UNDEF'
+
     if (GetTarget() == "freebsd"):
     if (GetTarget() == "freebsd"):
         dtool_config["IS_LINUX"] = 'UNDEF'
         dtool_config["IS_LINUX"] = 'UNDEF'
         dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
         dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
@@ -4546,13 +4549,33 @@ if (GetTarget() == 'windows' and PkgSkip("GL")==0):
 # DIRECTORY: panda/src/egldisplay/
 # DIRECTORY: panda/src/egldisplay/
 #
 #
 
 
-if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and PkgSkip("X11")==0):
+# If we're not compiling with any windowing system at all, but we do have EGL,
+# we can use that to create a headless libpandagl instead.
+if not PkgSkip("EGL") and not PkgSkip("GL") and PkgSkip("X11") and GetTarget() not in ('windows', 'darwin'):
+  DefSymbol('EGL', 'HAVE_EGL', '')
+  OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGL', 'GL', 'EGL']
+  TargetAdd('pandagl_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
+  OPTS=['DIR:panda/metalibs/pandagl', 'BUILDING:PANDAGL', 'GL', 'EGL']
+  TargetAdd('pandagl_pandagl.obj', opts=OPTS, input='pandagl.cxx')
+  TargetAdd('libpandagl.dll', input='pandagl_pandagl.obj')
+  TargetAdd('libpandagl.dll', input='p3glgsg_config_glgsg.obj')
+  TargetAdd('libpandagl.dll', input='p3glgsg_glgsg.obj')
+  TargetAdd('libpandagl.dll', input='pandagl_egldisplay_composite1.obj')
+  TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
+  TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'EGL', 'CGGL'])
+
+#
+# DIRECTORY: panda/src/egldisplay/
+#
+
+if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0):
   DefSymbol('GLES', 'OPENGLES_1', '')
   DefSymbol('GLES', 'OPENGLES_1', '')
   OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES',  'GLES', 'EGL']
   OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES',  'GLES', 'EGL']
   TargetAdd('pandagles_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
   TargetAdd('pandagles_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
   OPTS=['DIR:panda/metalibs/pandagles', 'BUILDING:PANDAGLES', 'GLES', 'EGL']
   OPTS=['DIR:panda/metalibs/pandagles', 'BUILDING:PANDAGLES', 'GLES', 'EGL']
   TargetAdd('pandagles_pandagles.obj', opts=OPTS, input='pandagles.cxx')
   TargetAdd('pandagles_pandagles.obj', opts=OPTS, input='pandagles.cxx')
-  TargetAdd('libpandagles.dll', input='p3x11display_composite1.obj')
+  if not PkgSkip("X11"):
+    TargetAdd('libpandagles.dll', input='p3x11display_composite1.obj')
   TargetAdd('libpandagles.dll', input='pandagles_pandagles.obj')
   TargetAdd('libpandagles.dll', input='pandagles_pandagles.obj')
   TargetAdd('libpandagles.dll', input='p3glesgsg_config_glesgsg.obj')
   TargetAdd('libpandagles.dll', input='p3glesgsg_config_glesgsg.obj')
   TargetAdd('libpandagles.dll', input='p3glesgsg_glesgsg.obj')
   TargetAdd('libpandagles.dll', input='p3glesgsg_glesgsg.obj')
@@ -4564,13 +4587,14 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0 and PkgSkip("X11")==0):
 # DIRECTORY: panda/src/egldisplay/
 # DIRECTORY: panda/src/egldisplay/
 #
 #
 
 
-if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0 and PkgSkip("X11")==0):
+if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0):
   DefSymbol('GLES2', 'OPENGLES_2', '')
   DefSymbol('GLES2', 'OPENGLES_2', '')
   OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES2',  'GLES2', 'EGL']
   OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES2',  'GLES2', 'EGL']
   TargetAdd('pandagles2_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
   TargetAdd('pandagles2_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx')
   OPTS=['DIR:panda/metalibs/pandagles2', 'BUILDING:PANDAGLES2', 'GLES2', 'EGL']
   OPTS=['DIR:panda/metalibs/pandagles2', 'BUILDING:PANDAGLES2', 'GLES2', 'EGL']
   TargetAdd('pandagles2_pandagles2.obj', opts=OPTS, input='pandagles2.cxx')
   TargetAdd('pandagles2_pandagles2.obj', opts=OPTS, input='pandagles2.cxx')
-  TargetAdd('libpandagles2.dll', input='p3x11display_composite1.obj')
+  if not PkgSkip("X11"):
+    TargetAdd('libpandagles2.dll', input='p3x11display_composite1.obj')
   TargetAdd('libpandagles2.dll', input='pandagles2_pandagles2.obj')
   TargetAdd('libpandagles2.dll', input='pandagles2_pandagles2.obj')
   TargetAdd('libpandagles2.dll', input='p3gles2gsg_config_gles2gsg.obj')
   TargetAdd('libpandagles2.dll', input='p3gles2gsg_config_gles2gsg.obj')
   TargetAdd('libpandagles2.dll', input='p3gles2gsg_gles2gsg.obj')
   TargetAdd('libpandagles2.dll', input='p3gles2gsg_gles2gsg.obj')

+ 16 - 3
panda/metalibs/pandagl/pandagl.cxx

@@ -23,8 +23,13 @@
 #include "glxGraphicsPipe.h"
 #include "glxGraphicsPipe.h"
 #endif
 #endif
 
 
-#if !defined(HAVE_WGL) && !defined(HAVE_COCOA) && !defined(HAVE_GLX)
-#error One of HAVE_WGL, HAVE_COCOA or HAVE_GLX must be defined when compiling pandagl!
+#if defined(HAVE_EGL) && !defined(HAVE_X11)
+#include "config_egldisplay.h"
+#include "eglGraphicsPipe.h"
+#endif
+
+#if !defined(HAVE_WGL) && !defined(HAVE_COCOA) && !defined(HAVE_GLX) && !defined(HAVE_EGL)
+#error One of HAVE_WGL, HAVE_COCOA, HAVE_GLX or HAVE_EGL must be defined when compiling pandagl!
 #endif
 #endif
 
 
 /**
 /**
@@ -45,9 +50,13 @@ init_libpandagl() {
   init_libcocoadisplay();
   init_libcocoadisplay();
 #endif
 #endif
 
 
-#ifdef IS_LINUX
+#ifdef HAVE_GLX
   init_libglxdisplay();
   init_libglxdisplay();
 #endif
 #endif
+
+#if defined(HAVE_EGL) && !defined(HAVE_X11)
+  init_libegldisplay();
+#endif
 }
 }
 
 
 /**
 /**
@@ -68,5 +77,9 @@ get_pipe_type_pandagl() {
   return glxGraphicsPipe::get_class_type().get_index();
   return glxGraphicsPipe::get_class_type().get_index();
 #endif
 #endif
 
 
+#if defined(HAVE_EGL) && !defined(HAVE_X11)
+  return eglGraphicsPipe::get_class_type().get_index();
+#endif
+
   return 0;
   return 0;
 }
 }

+ 2 - 1
panda/src/collide/collisionPolygon.h

@@ -42,6 +42,8 @@ public:
 
 
   virtual CollisionSolid *make_copy();
   virtual CollisionSolid *make_copy();
 
 
+  static bool verify_points(const LPoint3 *begin, const LPoint3 *end);
+
 PUBLISHED:
 PUBLISHED:
   virtual LPoint3 get_collision_origin() const;
   virtual LPoint3 get_collision_origin() const;
 
 
@@ -53,7 +55,6 @@ PUBLISHED:
   INLINE static bool verify_points(const LPoint3 &a, const LPoint3 &b,
   INLINE static bool verify_points(const LPoint3 &a, const LPoint3 &b,
                                    const LPoint3 &c, const LPoint3 &d);
                                    const LPoint3 &c, const LPoint3 &d);
   static bool verify_points(const LPoint3 &a, const LPoint3 &b, const LPoint3 &c);
   static bool verify_points(const LPoint3 &a, const LPoint3 &b, const LPoint3 &c);
-  static bool verify_points(const LPoint3 *begin, const LPoint3 *end);
 
 
   bool is_valid() const;
   bool is_valid() const;
   bool is_concave() const;
   bool is_concave() const;

+ 1 - 1
panda/src/display/frameBufferProperties.cxx

@@ -605,7 +605,7 @@ verify_hardware_software(const FrameBufferProperties &props, const std::string &
 
 
   if (get_force_hardware() < props.get_force_hardware()) {
   if (get_force_hardware() < props.get_force_hardware()) {
     display_cat.error()
     display_cat.error()
-      << "The application requested harware acceleration, but your OpenGL\n";
+      << "The application requested hardware acceleration, but your OpenGL\n";
     display_cat.error()
     display_cat.error()
       << "driver, " << renderer << ", only supports software rendering.\n";
       << "driver, " << renderer << ", only supports software rendering.\n";
     display_cat.error()
     display_cat.error()

+ 3 - 3
panda/src/downloader/httpClient.I

@@ -111,9 +111,9 @@ get_verify_ssl() const {
  * Specifies the set of ciphers that are to be made available for SSL
  * Specifies the set of ciphers that are to be made available for SSL
  * connections.  This is a string as described in the ciphers(1) man page of
  * connections.  This is a string as described in the ciphers(1) man page of
  * the OpenSSL documentation (or see
  * the OpenSSL documentation (or see
- * https://www.openssl.org/docs/apps/ciphers.html ).  If this isn't specified,
- * the default is provided by the Config file.  You may also specify "DEFAULT"
- * to use the built-in OpenSSL default value.
+ * https://www.openssl.org/docs/man1.1.1/man1/ciphers.html ).  If this isn't
+ * specified, the default is provided by the Config file.  You may also specify
+ * "DEFAULT" to use the built-in OpenSSL default value.
  */
  */
 INLINE void HTTPClient::
 INLINE void HTTPClient::
 set_cipher_list(const std::string &cipher_list) {
 set_cipher_list(const std::string &cipher_list) {

+ 7 - 3
panda/src/egldisplay/config_egldisplay.cxx

@@ -19,8 +19,8 @@
 #include "dconfig.h"
 #include "dconfig.h"
 #include "pandaSystem.h"
 #include "pandaSystem.h"
 
 
-#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDAGLES) && !defined(BUILDING_PANDAGLES2)
-  #error Buildsystem error: BUILDING_PANDAGLES(2) not defined
+#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDAGLES) && !defined(BUILDING_PANDAGLES2) && !defined(BUILDING_PANDAGL)
+  #error Buildsystem error: BUILDING_PANDAGL(ES(2)) not defined
 #endif
 #endif
 
 
 Configure(config_egldisplay);
 Configure(config_egldisplay);
@@ -45,7 +45,9 @@ init_libegldisplay() {
   initialized = true;
   initialized = true;
 
 
   eglGraphicsPipe::init_type();
   eglGraphicsPipe::init_type();
+#ifdef HAVE_X11
   eglGraphicsWindow::init_type();
   eglGraphicsWindow::init_type();
+#endif
   eglGraphicsStateGuardian::init_type();
   eglGraphicsStateGuardian::init_type();
 
 
   GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
   GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
@@ -55,8 +57,10 @@ init_libegldisplay() {
   PandaSystem *ps = PandaSystem::get_global_ptr();
   PandaSystem *ps = PandaSystem::get_global_ptr();
 #ifdef OPENGLES_2
 #ifdef OPENGLES_2
   ps->set_system_tag("OpenGL ES 2", "window_system", "EGL");
   ps->set_system_tag("OpenGL ES 2", "window_system", "EGL");
-#else
+#elif defined(OPENGLES_1)
   ps->set_system_tag("OpenGL ES", "window_system", "EGL");
   ps->set_system_tag("OpenGL ES", "window_system", "EGL");
+#else
+  ps->set_system_tag("OpenGL", "window_system", "EGL");
 #endif
 #endif
 }
 }
 
 

+ 6 - 4
panda/src/egldisplay/config_egldisplay.h

@@ -23,20 +23,22 @@
 #if defined(OPENGLES_1) && defined(OPENGLES_2)
 #if defined(OPENGLES_1) && defined(OPENGLES_2)
   #error OPENGLES_1 and OPENGLES_2 cannot be defined at the same time!
   #error OPENGLES_1 and OPENGLES_2 cannot be defined at the same time!
 #endif
 #endif
-#if !defined(OPENGLES_1) && !defined(OPENGLES_2)
-  #error Either OPENGLES_1 or OPENGLES_2 must be defined when compiling egldisplay!
-#endif
 
 
 #ifdef OPENGLES_2
 #ifdef OPENGLES_2
   NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES2, EXPTP_PANDAGLES2);
   NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES2, EXPTP_PANDAGLES2);
 
 
   extern EXPCL_PANDAGLES2 void init_libegldisplay();
   extern EXPCL_PANDAGLES2 void init_libegldisplay();
   extern EXPCL_PANDAGLES2 const std::string get_egl_error_string(int error);
   extern EXPCL_PANDAGLES2 const std::string get_egl_error_string(int error);
-#else
+#elif defined(OPENGLES_1)
   NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES, EXPTP_PANDAGLES);
   NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES, EXPTP_PANDAGLES);
 
 
   extern EXPCL_PANDAGLES void init_libegldisplay();
   extern EXPCL_PANDAGLES void init_libegldisplay();
   extern EXPCL_PANDAGLES const std::string get_egl_error_string(int error);
   extern EXPCL_PANDAGLES const std::string get_egl_error_string(int error);
+#else
+  NotifyCategoryDecl(egldisplay, EXPCL_PANDAGL, EXPTP_PANDAGL);
+
+  extern EXPCL_PANDAGL void init_libegldisplay();
+  extern EXPCL_PANDAGL const std::string get_egl_error_string(int error);
 #endif
 #endif
 
 
 #endif
 #endif

+ 5 - 3
panda/src/egldisplay/eglGraphicsBuffer.cxx

@@ -127,7 +127,7 @@ close_buffer() {
   if (_gsg != nullptr) {
   if (_gsg != nullptr) {
     eglGraphicsStateGuardian *eglgsg;
     eglGraphicsStateGuardian *eglgsg;
     DCAST_INTO_V(eglgsg, _gsg);
     DCAST_INTO_V(eglgsg, _gsg);
-    if (!eglMakeCurrent(eglgsg->_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
+    if (!eglMakeCurrent(_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
       egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
       egldisplay_cat.error() << "Failed to call eglMakeCurrent: "
         << get_egl_error_string(eglGetError()) << "\n";
         << get_egl_error_string(eglGetError()) << "\n";
     }
     }
@@ -159,7 +159,7 @@ open_buffer() {
   if (_gsg == 0) {
   if (_gsg == 0) {
     // There is no old gsg.  Create a new one.
     // There is no old gsg.  Create a new one.
     eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
     eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
-    eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
+    eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, true, false);
     _gsg = eglgsg;
     _gsg = eglgsg;
   } else {
   } else {
     // If the old gsg has the wrong pixel format, create a new one that shares
     // If the old gsg has the wrong pixel format, create a new one that shares
@@ -167,7 +167,7 @@ open_buffer() {
     DCAST_INTO_R(eglgsg, _gsg, false);
     DCAST_INTO_R(eglgsg, _gsg, false);
     if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
     if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
       eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
       eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
-      eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), true, false);
+      eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, true, false);
       _gsg = eglgsg;
       _gsg = eglgsg;
     }
     }
   }
   }
@@ -178,6 +178,8 @@ open_buffer() {
     return false;
     return false;
   }
   }
 
 
+  _egl_display = eglgsg->_egl_display;
+
   int attrib_list[] = {
   int attrib_list[] = {
     EGL_WIDTH, _size.get_x(),
     EGL_WIDTH, _size.get_x(),
     EGL_HEIGHT, _size.get_y(),
     EGL_HEIGHT, _size.get_y(),

+ 8 - 0
panda/src/egldisplay/eglGraphicsPipe.I

@@ -10,3 +10,11 @@
  * @author rdb
  * @author rdb
  * @date 2009-05-21
  * @date 2009-05-21
  */
  */
+
+/**
+ *
+ */
+INLINE EGLDisplay eglGraphicsPipe::
+get_egl_display() const {
+  return _egl_display;
+}

+ 44 - 3
panda/src/egldisplay/eglGraphicsPipe.cxx

@@ -25,19 +25,39 @@ TypeHandle eglGraphicsPipe::_type_handle;
  *
  *
  */
  */
 eglGraphicsPipe::
 eglGraphicsPipe::
-eglGraphicsPipe(const std::string &display) : x11GraphicsPipe(display) {
+eglGraphicsPipe() {
+  //NB. if the X11 display failed to open, _display will be 0, which is a valid
+  // input to eglGetDisplay - it means to open the default display.
+#ifdef HAVE_X11
   _egl_display = eglGetDisplay((NativeDisplayType) _display);
   _egl_display = eglGetDisplay((NativeDisplayType) _display);
+#else
+  _egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+#endif
   if (!eglInitialize(_egl_display, nullptr, nullptr)) {
   if (!eglInitialize(_egl_display, nullptr, nullptr)) {
     egldisplay_cat.error()
     egldisplay_cat.error()
       << "Couldn't initialize the EGL display: "
       << "Couldn't initialize the EGL display: "
       << get_egl_error_string(eglGetError()) << "\n";
       << get_egl_error_string(eglGetError()) << "\n";
+    _is_valid = false;
+    return;
   }
   }
 
 
+#if defined(OPENGLES_1) || defined(OPENGLES_2)
   if (!eglBindAPI(EGL_OPENGL_ES_API)) {
   if (!eglBindAPI(EGL_OPENGL_ES_API)) {
     egldisplay_cat.error()
     egldisplay_cat.error()
       << "Couldn't bind EGL to the OpenGL ES API: "
       << "Couldn't bind EGL to the OpenGL ES API: "
       << get_egl_error_string(eglGetError()) << "\n";
       << get_egl_error_string(eglGetError()) << "\n";
+#else
+  if (!eglBindAPI(EGL_OPENGL_API)) {
+    egldisplay_cat.error()
+      << "Couldn't bind EGL to the OpenGL API: "
+      << get_egl_error_string(eglGetError()) << "\n";
+#endif
+    _is_valid = false;
+    return;
   }
   }
+
+  // Even if we don't have an X11 display, we can still render headless.
+  _is_valid = true;
 }
 }
 
 
 /**
 /**
@@ -61,7 +81,11 @@ eglGraphicsPipe::
  */
  */
 std::string eglGraphicsPipe::
 std::string eglGraphicsPipe::
 get_interface_name() const {
 get_interface_name() const {
+#if defined(OPENGLES_1) || defined(OPENGLES_2)
   return "OpenGL ES";
   return "OpenGL ES";
+#else
+  return "OpenGL";
+#endif
 }
 }
 
 
 /**
 /**
@@ -110,6 +134,10 @@ make_output(const std::string &name,
   // First thing to try: an eglGraphicsWindow
   // First thing to try: an eglGraphicsWindow
 
 
   if (retry == 0) {
   if (retry == 0) {
+#ifdef HAVE_X11
+    if (!_display) {
+      return nullptr;
+    }
     if (((flags&BF_require_parasite)!=0)||
     if (((flags&BF_require_parasite)!=0)||
         ((flags&BF_refuse_window)!=0)||
         ((flags&BF_refuse_window)!=0)||
         ((flags&BF_resizeable)!=0)||
         ((flags&BF_resizeable)!=0)||
@@ -121,9 +149,12 @@ make_output(const std::string &name,
     }
     }
     return new eglGraphicsWindow(engine, this, name, fb_prop, win_prop,
     return new eglGraphicsWindow(engine, this, name, fb_prop, win_prop,
                                  flags, gsg, host);
                                  flags, gsg, host);
+#else
+    return nullptr;
+#endif
   }
   }
 
 
-  // Second thing to try: a GLES(2)GraphicsBuffer
+  // Second thing to try: a GL(ES(2))GraphicsBuffer
   if (retry == 1) {
   if (retry == 1) {
     if ((host==0)||
     if ((host==0)||
   // (!gl_support_fbo)||
   // (!gl_support_fbo)||
@@ -154,9 +185,12 @@ make_output(const std::string &name,
 #ifdef OPENGLES_2
 #ifdef OPENGLES_2
     return new GLES2GraphicsBuffer(engine, this, name, fb_prop, win_prop,
     return new GLES2GraphicsBuffer(engine, this, name, fb_prop, win_prop,
                                   flags, gsg, host);
                                   flags, gsg, host);
-#else
+#elif defined(OPENGLES_1)
     return new GLESGraphicsBuffer(engine, this, name, fb_prop, win_prop,
     return new GLESGraphicsBuffer(engine, this, name, fb_prop, win_prop,
                                   flags, gsg, host);
                                   flags, gsg, host);
+#else
+    return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop,
+                                flags, gsg, host);
 #endif
 #endif
   }
   }
 
 
@@ -184,6 +218,10 @@ make_output(const std::string &name,
 
 
   // Fourth thing to try: an eglGraphicsPixmap.
   // Fourth thing to try: an eglGraphicsPixmap.
   if (retry == 3) {
   if (retry == 3) {
+#ifdef HAVE_X11
+    if (!_display) {
+      return nullptr;
+    }
     if (((flags&BF_require_parasite)!=0)||
     if (((flags&BF_require_parasite)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_require_window)!=0)||
         ((flags&BF_resizeable)!=0)||
         ((flags&BF_resizeable)!=0)||
@@ -198,6 +236,9 @@ make_output(const std::string &name,
 
 
     return new eglGraphicsPixmap(engine, this, name, fb_prop, win_prop,
     return new eglGraphicsPixmap(engine, this, name, fb_prop, win_prop,
                                  flags, gsg, host);
                                  flags, gsg, host);
+#else
+    return nullptr;
+#endif
   }
   }
 
 
   // Nothing else left to try.
   // Nothing else left to try.

+ 20 - 10
panda/src/egldisplay/eglGraphicsPipe.h

@@ -15,7 +15,14 @@
 #define EGLGRAPHICSPIPE_H
 #define EGLGRAPHICSPIPE_H
 
 
 #include "pandabase.h"
 #include "pandabase.h"
+
+#ifdef HAVE_X11
 #include "x11GraphicsPipe.h"
 #include "x11GraphicsPipe.h"
+typedef x11GraphicsPipe BaseGraphicsPipe;
+#else
+#include "graphicsPipe.h"
+typedef GraphicsPipe BaseGraphicsPipe;
+#endif
 
 
 #ifdef OPENGLES_2
 #ifdef OPENGLES_2
   #include "gles2gsg.h"
   #include "gles2gsg.h"
@@ -25,11 +32,16 @@
   #define NativeDisplayType EGLNativeDisplayType
   #define NativeDisplayType EGLNativeDisplayType
   #define NativePixmapType EGLNativePixmapType
   #define NativePixmapType EGLNativePixmapType
   #define NativeWindowType EGLNativeWindowType
   #define NativeWindowType EGLNativeWindowType
-#else
+#elif defined(OPENGLES_1)
   #include "glesgsg.h"
   #include "glesgsg.h"
   #include "pre_x11_include.h"
   #include "pre_x11_include.h"
   #include <GLES/egl.h>
   #include <GLES/egl.h>
   #include "post_x11_include.h"
   #include "post_x11_include.h"
+#else
+  #include "glgsg.h"
+  #include "pre_x11_include.h"
+  #include <EGL/egl.h>
+  #include "post_x11_include.h"
 #endif
 #endif
 
 
 class FrameBufferProperties;
 class FrameBufferProperties;
@@ -42,14 +54,16 @@ class eglGraphicsWindow;
  * This graphics pipe represents the interface for creating OpenGL ES graphics
  * This graphics pipe represents the interface for creating OpenGL ES graphics
  * windows on an X-based (e.g.  Unix) client.
  * windows on an X-based (e.g.  Unix) client.
  */
  */
-class eglGraphicsPipe : public x11GraphicsPipe {
+class eglGraphicsPipe : public BaseGraphicsPipe {
 public:
 public:
-  eglGraphicsPipe(const std::string &display = std::string());
+  eglGraphicsPipe();
   virtual ~eglGraphicsPipe();
   virtual ~eglGraphicsPipe();
 
 
   virtual std::string get_interface_name() const;
   virtual std::string get_interface_name() const;
   static PT(GraphicsPipe) pipe_constructor();
   static PT(GraphicsPipe) pipe_constructor();
 
 
+  INLINE EGLDisplay get_egl_display() const;
+
 protected:
 protected:
   virtual PT(GraphicsOutput) make_output(const std::string &name,
   virtual PT(GraphicsOutput) make_output(const std::string &name,
                                          const FrameBufferProperties &fb_prop,
                                          const FrameBufferProperties &fb_prop,
@@ -62,16 +76,16 @@ protected:
                                          bool &precertify);
                                          bool &precertify);
 
 
 private:
 private:
-  EGLDisplay _egl_display;
+  EGLDisplay _egl_display = 0;
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
     return _type_handle;
     return _type_handle;
   }
   }
   static void init_type() {
   static void init_type() {
-    x11GraphicsPipe::init_type();
+    BaseGraphicsPipe::init_type();
     register_type(_type_handle, "eglGraphicsPipe",
     register_type(_type_handle, "eglGraphicsPipe",
-                  x11GraphicsPipe::get_class_type());
+                  BaseGraphicsPipe::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
     return get_class_type();
     return get_class_type();
@@ -80,10 +94,6 @@ public:
 
 
 private:
 private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
-
-  friend class eglGraphicsBuffer;
-  friend class eglGraphicsPixmap;
-  friend class eglGraphicsWindow;
 };
 };
 
 
 #include "eglGraphicsPipe.I"
 #include "eglGraphicsPipe.I"

+ 9 - 4
panda/src/egldisplay/eglGraphicsPixmap.cxx

@@ -12,6 +12,9 @@
  */
  */
 
 
 #include "eglGraphicsPixmap.h"
 #include "eglGraphicsPixmap.h"
+
+#ifdef HAVE_X11
+
 #include "eglGraphicsWindow.h"
 #include "eglGraphicsWindow.h"
 #include "eglGraphicsStateGuardian.h"
 #include "eglGraphicsStateGuardian.h"
 #include "config_egldisplay.h"
 #include "config_egldisplay.h"
@@ -37,8 +40,7 @@ eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
 {
 {
   eglGraphicsPipe *egl_pipe;
   eglGraphicsPipe *egl_pipe;
   DCAST_INTO_V(egl_pipe, _pipe);
   DCAST_INTO_V(egl_pipe, _pipe);
-  _display = egl_pipe->get_display();
-  _egl_display = egl_pipe->_egl_display;
+  _egl_display = egl_pipe->get_egl_display();
   _drawable = None;
   _drawable = None;
   _x_pixmap = None;
   _x_pixmap = None;
   _egl_surface = EGL_NO_SURFACE;
   _egl_surface = EGL_NO_SURFACE;
@@ -167,7 +169,7 @@ open_buffer() {
   if (_gsg == 0) {
   if (_gsg == 0) {
     // There is no old gsg.  Create a new one.
     // There is no old gsg.  Create a new one.
     eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
     eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
-    eglgsg->choose_pixel_format(_fb_properties, _display, egl_pipe->get_screen(), false, true);
+    eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, false, true);
     _gsg = eglgsg;
     _gsg = eglgsg;
   } else {
   } else {
     // If the old gsg has the wrong pixel format, create a new one that shares
     // If the old gsg has the wrong pixel format, create a new one that shares
@@ -175,7 +177,7 @@ open_buffer() {
     DCAST_INTO_R(eglgsg, _gsg, false);
     DCAST_INTO_R(eglgsg, _gsg, false);
     if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
     if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
       eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
       eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
-      eglgsg->choose_pixel_format(_fb_properties, _display, egl_pipe->get_screen(), false, true);
+      eglgsg->choose_pixel_format(_fb_properties, egl_pipe, false, false, true);
       _gsg = eglgsg;
       _gsg = eglgsg;
     }
     }
   }
   }
@@ -194,6 +196,7 @@ open_buffer() {
     return false;
     return false;
   }
   }
 
 
+  _display = egl_pipe->get_display();
   _drawable = egl_pipe->get_root();
   _drawable = egl_pipe->get_root();
   if (_host != nullptr) {
   if (_host != nullptr) {
     if (_host->is_of_type(eglGraphicsWindow::get_class_type())) {
     if (_host->is_of_type(eglGraphicsWindow::get_class_type())) {
@@ -241,3 +244,5 @@ open_buffer() {
   _is_valid = true;
   _is_valid = true;
   return true;
   return true;
 }
 }
+
+#endif  // HAVE_X11

+ 4 - 0
panda/src/egldisplay/eglGraphicsPixmap.h

@@ -16,6 +16,8 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 
 
+#ifdef HAVE_X11
+
 #include "eglGraphicsPipe.h"
 #include "eglGraphicsPipe.h"
 #include "graphicsBuffer.h"
 #include "graphicsBuffer.h"
 
 
@@ -67,4 +69,6 @@ private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
 };
 };
 
 
+#endif  // HAVE_X11
+
 #endif
 #endif

+ 63 - 62
panda/src/egldisplay/eglGraphicsStateGuardian.cxx

@@ -25,19 +25,11 @@ TypeHandle eglGraphicsStateGuardian::_type_handle;
 eglGraphicsStateGuardian::
 eglGraphicsStateGuardian::
 eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
 eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
        eglGraphicsStateGuardian *share_with) :
        eglGraphicsStateGuardian *share_with) :
-#ifdef OPENGLES_2
-  GLES2GraphicsStateGuardian(engine, pipe)
-#else
-  GLESGraphicsStateGuardian(engine, pipe)
-#endif
+  BaseGraphicsStateGuardian(engine, pipe)
 {
 {
   _share_context=0;
   _share_context=0;
   _context=0;
   _context=0;
-  _display=0;
   _egl_display=0;
   _egl_display=0;
-  _screen=0;
-  _visual=0;
-  _visuals=0;
   _fbconfig=0;
   _fbconfig=0;
 
 
   if (share_with != nullptr) {
   if (share_with != nullptr) {
@@ -51,9 +43,6 @@ eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
  */
  */
 eglGraphicsStateGuardian::
 eglGraphicsStateGuardian::
 ~eglGraphicsStateGuardian() {
 ~eglGraphicsStateGuardian() {
-  if (_visuals != nullptr) {
-    XFree(_visuals);
-  }
   if (_context != (EGLContext)nullptr) {
   if (_context != (EGLContext)nullptr) {
     if (!eglDestroyContext(_egl_display, _context)) {
     if (!eglDestroyContext(_egl_display, _context)) {
       egldisplay_cat.error() << "Failed to destroy EGL context: "
       egldisplay_cat.error() << "Failed to destroy EGL context: "
@@ -108,11 +97,6 @@ get_properties(FrameBufferProperties &properties,
     slow = true;
     slow = true;
   }
   }
 
 
-  if ((surface_type & EGL_WINDOW_BIT)==0) {
-    // We insist on having a context that will support an onscreen window.
-    return;
-  }
-
   properties.set_back_buffers(1);
   properties.set_back_buffers(1);
   properties.set_rgb_color(1);
   properties.set_rgb_color(1);
   properties.set_rgba_bits(red_size, green_size, blue_size, alpha_size);
   properties.set_rgba_bits(red_size, green_size, blue_size, alpha_size);
@@ -131,26 +115,23 @@ get_properties(FrameBufferProperties &properties,
  */
  */
 void eglGraphicsStateGuardian::
 void eglGraphicsStateGuardian::
 choose_pixel_format(const FrameBufferProperties &properties,
 choose_pixel_format(const FrameBufferProperties &properties,
-        X11_Display *display,
-        int screen, bool need_pbuffer, bool need_pixmap) {
+                    eglGraphicsPipe *egl_pipe, bool need_window,
+                    bool need_pbuffer, bool need_pixmap) {
 
 
-  _display = display;
-  _egl_display = eglGetDisplay((NativeDisplayType) display);
-  _screen = screen;
+  _egl_display = egl_pipe->get_egl_display();
   _context = 0;
   _context = 0;
   _fbconfig = 0;
   _fbconfig = 0;
-  _visual = 0;
-  _visuals = 0;
   _fbprops.clear();
   _fbprops.clear();
 
 
   int attrib_list[] = {
   int attrib_list[] = {
-#ifdef OPENGLES_1
+#if defined(OPENGLES_1)
     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
-#endif
-#ifdef OPENGLES_2
+#elif defined(OPENGLES_2)
     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#else
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
 #endif
 #endif
-    EGL_SURFACE_TYPE, EGL_DONT_CARE,
+    EGL_SURFACE_TYPE, need_window ? EGL_WINDOW_BIT : EGL_DONT_CARE,
     EGL_NONE
     EGL_NONE
   };
   };
 
 
@@ -206,23 +187,56 @@ choose_pixel_format(const FrameBufferProperties &properties,
       best_props = fbprops;
       best_props = fbprops;
     }
     }
   }
   }
-  int depth = DefaultDepth(_display, _screen);
-  _visual = new XVisualInfo;
-  XMatchVisualInfo(_display, _screen, depth, TrueColor, _visual);
+#ifdef HAVE_X11
+  X11_Display *display = egl_pipe->get_display();
+  if (display) {
+    int screen = egl_pipe->get_screen();
+    int depth = DefaultDepth(display, screen);
+    _visual = new XVisualInfo;
+    XMatchVisualInfo(display, screen, depth, TrueColor, _visual);
+  }
+#endif
 
 
   if (best_quality > 0) {
   if (best_quality > 0) {
     egldisplay_cat.debug()
     egldisplay_cat.debug()
       << "Chosen config " << best_result << ": " << best_props << "\n";
       << "Chosen config " << best_result << ": " << best_props << "\n";
     _fbconfig = configs[best_result];
     _fbconfig = configs[best_result];
+
+    EGLint attribs[32];
+    int n = 0;
+
 #ifdef OPENGLES_2
 #ifdef OPENGLES_2
-    EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
-    _context = eglCreateContext(_egl_display, _fbconfig, _share_context, context_attribs);
-#else
-    _context = eglCreateContext(_egl_display, _fbconfig, _share_context, nullptr);
+    attribs[n++] = EGL_CONTEXT_CLIENT_VERSION;
+    attribs[n++] = 2;
+#elif defined(OPENGLES_1)
+#else  // Regular OpenGL
+    if (gl_version.get_num_words() > 0) {
+      attribs[n++] = EGL_CONTEXT_MAJOR_VERSION;
+      attribs[n++] = gl_version[0];
+      if (gl_version.get_num_words() > 1) {
+        attribs[n++] = EGL_CONTEXT_MINOR_VERSION;
+        attribs[n++] = gl_version[1];
+      }
+    }
+    if (gl_debug) {
+      attribs[n++] = EGL_CONTEXT_OPENGL_DEBUG;
+      attribs[n++] = EGL_TRUE;
+    }
+    if (gl_forward_compatible) {
+      attribs[n++] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE;
+      attribs[n++] = EGL_TRUE;
+    }
 #endif
 #endif
+    attribs[n] = EGL_NONE;
+
+    _context = eglCreateContext(_egl_display, _fbconfig, _share_context, (n > 0) ? attribs : nullptr);
+
     int err = eglGetError();
     int err = eglGetError();
     if (_context && err == EGL_SUCCESS) {
     if (_context && err == EGL_SUCCESS) {
-      if (_visual) {
+#ifdef HAVE_X11
+      if (!display || _visual)
+#endif
+      {
         _fbprops = best_props;
         _fbprops = best_props;
         delete[] configs;
         delete[] configs;
         return;
         return;
@@ -234,8 +248,9 @@ choose_pixel_format(const FrameBufferProperties &properties,
       << get_egl_error_string(err) << "\n";
       << get_egl_error_string(err) << "\n";
     _fbconfig = 0;
     _fbconfig = 0;
     _context = 0;
     _context = 0;
+#ifdef HAVE_X11
     _visual = 0;
     _visual = 0;
-    _visuals = 0;
+#endif
   }
   }
 
 
   egldisplay_cat.error() <<
   egldisplay_cat.error() <<
@@ -249,18 +264,9 @@ choose_pixel_format(const FrameBufferProperties &properties,
  */
  */
 void eglGraphicsStateGuardian::
 void eglGraphicsStateGuardian::
 reset() {
 reset() {
-#ifdef OPENGLES_2
-  GLES2GraphicsStateGuardian::reset();
-#else
-  GLESGraphicsStateGuardian::reset();
-#endif
+  BaseGraphicsStateGuardian::reset();
 
 
-  // If "Mesa" is present, assume software.  However, if "Mesa DRI" is found,
-  // it's actually a Mesa-based OpenGL layer running over a hardware driver.
-  if (_gl_renderer == "Software Rasterizer" ||
-      (_gl_renderer.find("Mesa") != std::string::npos &&
-       _gl_renderer.find("Mesa DRI") == std::string::npos)) {
-    // It's Mesa, therefore probably a software context.
+  if (_gl_renderer == "Software Rasterizer") {
     _fbprops.set_force_software(1);
     _fbprops.set_force_software(1);
     _fbprops.set_force_hardware(0);
     _fbprops.set_force_hardware(0);
   } else {
   } else {
@@ -289,13 +295,11 @@ egl_is_at_least_version(int major_version, int minor_version) const {
  */
  */
 void eglGraphicsStateGuardian::
 void eglGraphicsStateGuardian::
 gl_flush() const {
 gl_flush() const {
+#ifdef HAVE_X11
   // This call requires synchronization with X.
   // This call requires synchronization with X.
   LightReMutexHolder holder(eglGraphicsPipe::_x_mutex);
   LightReMutexHolder holder(eglGraphicsPipe::_x_mutex);
-#ifdef OPENGLES_2
-  GLES2GraphicsStateGuardian::gl_flush();
-#else
-  GLESGraphicsStateGuardian::gl_flush();
 #endif
 #endif
+  BaseGraphicsStateGuardian::gl_flush();
 }
 }
 
 
 /**
 /**
@@ -303,13 +307,11 @@ gl_flush() const {
  */
  */
 GLenum eglGraphicsStateGuardian::
 GLenum eglGraphicsStateGuardian::
 gl_get_error() const {
 gl_get_error() const {
+#ifdef HAVE_X11
   // This call requires synchronization with X.
   // This call requires synchronization with X.
   LightReMutexHolder holder(eglGraphicsPipe::_x_mutex);
   LightReMutexHolder holder(eglGraphicsPipe::_x_mutex);
-#ifdef OPENGLES_2
-  return GLES2GraphicsStateGuardian::gl_get_error();
-#else
-  return GLESGraphicsStateGuardian::gl_get_error();
 #endif
 #endif
+  return BaseGraphicsStateGuardian::gl_get_error();
 }
 }
 
 
 /**
 /**
@@ -317,11 +319,7 @@ gl_get_error() const {
  */
  */
 void eglGraphicsStateGuardian::
 void eglGraphicsStateGuardian::
 query_gl_version() {
 query_gl_version() {
-#ifdef OPENGLES_2
-  GLES2GraphicsStateGuardian::query_gl_version();
-#else
-  GLESGraphicsStateGuardian::query_gl_version();
-#endif
+  BaseGraphicsStateGuardian::query_gl_version();
 
 
   // Calling eglInitialize on an already-initialized display will just provide
   // Calling eglInitialize on an already-initialized display will just provide
   // us the version numbers.
   // us the version numbers.
@@ -336,9 +334,12 @@ query_gl_version() {
 #ifdef OPENGLES_2
 #ifdef OPENGLES_2
   if (gles2gsg_cat.is_debug()) {
   if (gles2gsg_cat.is_debug()) {
     gles2gsg_cat.debug()
     gles2gsg_cat.debug()
-#else
+#elif defined(OPENGLES_1)
   if (glesgsg_cat.is_debug()) {
   if (glesgsg_cat.is_debug()) {
     glesgsg_cat.debug()
     glesgsg_cat.debug()
+#else
+  if (glgsg_cat.is_debug()) {
+    glgsg_cat.debug()
 #endif
 #endif
       << "EGL_VERSION = " << _egl_version_major << "." << _egl_version_minor
       << "EGL_VERSION = " << _egl_version_major << "." << _egl_version_minor
       << "\n";
       << "\n";

+ 19 - 20
panda/src/egldisplay/eglGraphicsStateGuardian.h

@@ -16,26 +16,32 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 #include "eglGraphicsPipe.h"
 #include "eglGraphicsPipe.h"
+
+#ifdef HAVE_X11
 #include "get_x11.h"
 #include "get_x11.h"
+#endif
+
+#ifdef OPENGLES_2
+typedef GLES2GraphicsStateGuardian BaseGraphicsStateGuardian;
+#elif defined(OPENGLES_1)
+typedef GLESGraphicsStateGuardian BaseGraphicsStateGuardian;
+#else
+typedef GLGraphicsStateGuardian BaseGraphicsStateGuardian;
+#endif
 
 
 /**
 /**
  * A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific
  * A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific
  * information.
  * information.
  */
  */
-#ifdef OPENGLES_2
-class eglGraphicsStateGuardian : public GLES2GraphicsStateGuardian {
-#else
-class eglGraphicsStateGuardian : public GLESGraphicsStateGuardian {
-#endif
+class eglGraphicsStateGuardian : public BaseGraphicsStateGuardian {
 public:
 public:
   INLINE const FrameBufferProperties &get_fb_properties() const;
   INLINE const FrameBufferProperties &get_fb_properties() const;
   void get_properties(FrameBufferProperties &properties,
   void get_properties(FrameBufferProperties &properties,
              bool &pbuffer_supported, bool &pixmap_supported,
              bool &pbuffer_supported, bool &pixmap_supported,
                                bool &slow, EGLConfig config);
                                bool &slow, EGLConfig config);
   void choose_pixel_format(const FrameBufferProperties &properties,
   void choose_pixel_format(const FrameBufferProperties &properties,
-         X11_Display *_display,
-         int _screen,
-         bool need_pbuffer, bool need_pixmap);
+                           eglGraphicsPipe *egl_pipe, bool need_window,
+                           bool need_pbuffer, bool need_pixmap);
 
 
   eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
   eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
          eglGraphicsStateGuardian *share_with);
          eglGraphicsStateGuardian *share_with);
@@ -49,10 +55,9 @@ public:
   EGLContext _share_context;
   EGLContext _share_context;
   EGLContext _context;
   EGLContext _context;
   EGLDisplay _egl_display;
   EGLDisplay _egl_display;
-  X11_Display *_display;
-  int _screen;
-  XVisualInfo *_visual;
-  XVisualInfo *_visuals;
+#ifdef HAVE_X11
+  XVisualInfo *_visual = nullptr;
+#endif
   EGLConfig _fbconfig;
   EGLConfig _fbconfig;
   FrameBufferProperties _fbprops;
   FrameBufferProperties _fbprops;
 
 
@@ -72,15 +77,9 @@ public:
     return _type_handle;
     return _type_handle;
   }
   }
   static void init_type() {
   static void init_type() {
-#ifdef OPENGLES_2
-    GLES2GraphicsStateGuardian::init_type();
+    BaseGraphicsStateGuardian::init_type();
     register_type(_type_handle, "eglGraphicsStateGuardian",
     register_type(_type_handle, "eglGraphicsStateGuardian",
-                  GLES2GraphicsStateGuardian::get_class_type());
-#else
-    GLESGraphicsStateGuardian::init_type();
-    register_type(_type_handle, "eglGraphicsStateGuardian",
-                  GLESGraphicsStateGuardian::get_class_type());
-#endif
+                  BaseGraphicsStateGuardian::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
     return get_class_type();
     return get_class_type();

+ 8 - 3
panda/src/egldisplay/eglGraphicsWindow.cxx

@@ -12,6 +12,9 @@
  */
  */
 
 
 #include "eglGraphicsWindow.h"
 #include "eglGraphicsWindow.h"
+
+#ifdef HAVE_X11
+
 #include "eglGraphicsStateGuardian.h"
 #include "eglGraphicsStateGuardian.h"
 #include "config_egldisplay.h"
 #include "config_egldisplay.h"
 #include "eglGraphicsPipe.h"
 #include "eglGraphicsPipe.h"
@@ -44,7 +47,7 @@ eglGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
 {
 {
   eglGraphicsPipe *egl_pipe;
   eglGraphicsPipe *egl_pipe;
   DCAST_INTO_V(egl_pipe, _pipe);
   DCAST_INTO_V(egl_pipe, _pipe);
-  _egl_display = egl_pipe->_egl_display;
+  _egl_display = egl_pipe->get_egl_display();
   _egl_surface = 0;
   _egl_surface = 0;
 }
 }
 
 
@@ -206,7 +209,7 @@ open_window() {
   if (_gsg == 0) {
   if (_gsg == 0) {
     // There is no old gsg.  Create a new one.
     // There is no old gsg.  Create a new one.
     eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
     eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, nullptr);
-    eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), false, false);
+    eglgsg->choose_pixel_format(_fb_properties, egl_pipe, true, false, false);
     _gsg = eglgsg;
     _gsg = eglgsg;
   } else {
   } else {
     // If the old gsg has the wrong pixel format, create a new one that shares
     // If the old gsg has the wrong pixel format, create a new one that shares
@@ -214,7 +217,7 @@ open_window() {
     DCAST_INTO_R(eglgsg, _gsg, false);
     DCAST_INTO_R(eglgsg, _gsg, false);
     if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
     if (!eglgsg->get_fb_properties().subsumes(_fb_properties)) {
       eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
       eglgsg = new eglGraphicsStateGuardian(_engine, _pipe, eglgsg);
-      eglgsg->choose_pixel_format(_fb_properties, egl_pipe->get_display(), egl_pipe->get_screen(), false, false);
+      eglgsg->choose_pixel_format(_fb_properties, egl_pipe, true, false, false);
       _gsg = eglgsg;
       _gsg = eglgsg;
     }
     }
   }
   }
@@ -258,3 +261,5 @@ open_window() {
 
 
   return true;
   return true;
 }
 }
+
+#endif  // HAVE_X11

+ 4 - 0
panda/src/egldisplay/eglGraphicsWindow.h

@@ -16,6 +16,8 @@
 
 
 #include "pandabase.h"
 #include "pandabase.h"
 
 
+#ifdef HAVE_X11
+
 #include "eglGraphicsPipe.h"
 #include "eglGraphicsPipe.h"
 #include "x11GraphicsWindow.h"
 #include "x11GraphicsWindow.h"
 
 
@@ -65,4 +67,6 @@ private:
 
 
 #include "eglGraphicsWindow.I"
 #include "eglGraphicsWindow.I"
 
 
+#endif  // HAVE_X11
+
 #endif
 #endif

+ 8 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1283,10 +1283,12 @@ reset() {
   // Note that these extensions only offer support for GL_BGRA, not GL_BGR.
   // Note that these extensions only offer support for GL_BGRA, not GL_BGR.
   _supports_bgr = has_extension("GL_EXT_texture_format_BGRA8888") ||
   _supports_bgr = has_extension("GL_EXT_texture_format_BGRA8888") ||
                   has_extension("GL_APPLE_texture_format_BGRA8888");
                   has_extension("GL_APPLE_texture_format_BGRA8888");
+  _supports_bgra_read = has_extension("GL_EXT_read_format_bgra");
 #else
 #else
   // In regular OpenGL, we have both GL_BGRA and GL_BGR.
   // In regular OpenGL, we have both GL_BGRA and GL_BGR.
   _supports_bgr =
   _supports_bgr =
     is_at_least_gl_version(1, 2) || has_extension("GL_EXT_bgra");
     is_at_least_gl_version(1, 2) || has_extension("GL_EXT_bgra");
+  _supports_bgra_read = _supports_bgr;
 #endif
 #endif
 
 
 #ifdef SUPPORT_FIXED_FUNCTION
 #ifdef SUPPORT_FIXED_FUNCTION
@@ -7436,6 +7438,12 @@ framebuffer_copy_to_ram(Texture *tex, int view, int z,
 
 
   GLenum external_format = get_external_image_format(tex);
   GLenum external_format = get_external_image_format(tex);
 
 
+  // OpenGL ES implementations may support BGRA, but that doesn't imply they
+  // also support it for glReadPixels specifically.
+  if (!_supports_bgra_read && external_format == GL_BGRA) {
+    external_format = GL_RGBA;
+  }
+
   if (GLCAT.is_spam()) {
   if (GLCAT.is_spam()) {
     GLCAT.spam()
     GLCAT.spam()
       << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
       << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";

+ 1 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -815,6 +815,7 @@ public:
   PFNGLGETCOMPRESSEDTEXIMAGEPROC _glGetCompressedTexImage;
   PFNGLGETCOMPRESSEDTEXIMAGEPROC _glGetCompressedTexImage;
 
 
   bool _supports_bgr;
   bool _supports_bgr;
+  bool _supports_bgra_read;
   bool _supports_packed_dabc;
   bool _supports_packed_dabc;
   bool _supports_packed_ufloat;
   bool _supports_packed_ufloat;
 
 

+ 4 - 4
panda/src/grutil/meshDrawer2D.I

@@ -60,7 +60,7 @@ set_budget(int total_budget) {
 }
 }
 
 
 /**
 /**
- * Gets the total triangle budget of the drawer
+ * Gets the total triangle budget of the drawer.
  */
  */
 INLINE int MeshDrawer2D::
 INLINE int MeshDrawer2D::
 get_budget() {
 get_budget() {
@@ -68,7 +68,7 @@ get_budget() {
 }
 }
 
 
 /**
 /**
- * Sets clipping rectangle
+ * Sets the clipping rectangle.
  */
  */
 INLINE void MeshDrawer2D::
 INLINE void MeshDrawer2D::
 set_clip(PN_stdfloat x, PN_stdfloat y, PN_stdfloat w, PN_stdfloat h) {
 set_clip(PN_stdfloat x, PN_stdfloat y, PN_stdfloat w, PN_stdfloat h) {
@@ -79,7 +79,7 @@ set_clip(PN_stdfloat x, PN_stdfloat y, PN_stdfloat w, PN_stdfloat h) {
 }
 }
 
 
 /**
 /**
- * Draws a 2d rectangle.  Ignores the cliping rectangle
+ * Draws a 2D rectangle.  Ignores the clipping rectangle.
  */
  */
 INLINE void MeshDrawer2D::
 INLINE void MeshDrawer2D::
 quad_raw(const LVector3 &v1, const LVector4 &c1, const LVector2 &uv1,
 quad_raw(const LVector3 &v1, const LVector4 &c1, const LVector2 &uv1,
@@ -125,7 +125,7 @@ rectangle_raw(PN_stdfloat x, PN_stdfloat y, PN_stdfloat w, PN_stdfloat h,
 }
 }
 
 
 /**
 /**
- * Draws a 2d rectangle, that can be cliped
+ * Draws a 2D rectangle which can be clipped.
  */
  */
 INLINE void MeshDrawer2D::
 INLINE void MeshDrawer2D::
 rectangle(PN_stdfloat x, PN_stdfloat y, PN_stdfloat w, PN_stdfloat h,
 rectangle(PN_stdfloat x, PN_stdfloat y, PN_stdfloat w, PN_stdfloat h,

+ 2 - 2
panda/src/grutil/meshDrawer2D.h

@@ -39,8 +39,8 @@
 #include "nodePath.h"
 #include "nodePath.h"
 
 
 /**
 /**
- * This class allows the drawing of 2d objects - mainly based on quads and
- * rectangles.  Allows clipping and serverl high level UI theme functions.
+ * This class allows the drawing of 2D objects - mainly based on quads and
+ * rectangles.  It allows clipping and several high level UI theme functions.
  */
  */
 class EXPCL_PANDA_GRUTIL MeshDrawer2D : public TypedObject {
 class EXPCL_PANDA_GRUTIL MeshDrawer2D : public TypedObject {
 PUBLISHED:
 PUBLISHED:

+ 12 - 4
panda/src/nativenet/buffered_datagramconnection.h

@@ -136,7 +136,10 @@ private:
  * used to do a full reset of buffers
  * used to do a full reset of buffers
  */
  */
 inline void Buffered_DatagramConnection::ClearAll(void) {
 inline void Buffered_DatagramConnection::ClearAll(void) {
-  nativenet_cat.error() << "Buffered_DatagramConnection::ClearAll Starting Auto Reset\n";
+  if (nativenet_cat.is_debug()) {
+    nativenet_cat.debug()
+      << "Buffered_DatagramConnection::ClearAll Starting Auto Reset\n";
+  }
   Close();
   Close();
   _Writer.ReSet();
   _Writer.ReSet();
   _Reader.ReSet();
   _Reader.ReSet();
@@ -215,8 +218,11 @@ inline Buffered_DatagramConnection::~Buffered_DatagramConnection(void)
 inline Buffered_DatagramConnection::Buffered_DatagramConnection(int rbufsize, int wbufsize, int write_flush_point)
 inline Buffered_DatagramConnection::Buffered_DatagramConnection(int rbufsize, int wbufsize, int write_flush_point)
     :  _Writer(wbufsize,write_flush_point) , _Reader(rbufsize)
     :  _Writer(wbufsize,write_flush_point) , _Reader(rbufsize)
 {
 {
-  nativenet_cat.error() << "Buffered_DatagramConnection Constructor rbufsize = " << rbufsize
-                        << " wbufsize = " << wbufsize << " write_flush_point = " << write_flush_point << "\n";
+  if (nativenet_cat.is_debug()) {
+    nativenet_cat.debug()
+      << "Buffered_DatagramConnection Constructor rbufsize = " << rbufsize
+      << " wbufsize = " << wbufsize << " write_flush_point = " << write_flush_point << "\n";
+  }
 }
 }
 
 
 inline bool  Buffered_DatagramConnection::SendMessageBufferOnly(Datagram &msg)
 inline bool  Buffered_DatagramConnection::SendMessageBufferOnly(Datagram &msg)
@@ -289,7 +295,9 @@ bool Buffered_DatagramConnection::Flush(void)
  * Reset
  * Reset
  */
  */
 inline void Buffered_DatagramConnection::Reset() {
 inline void Buffered_DatagramConnection::Reset() {
-  nativenet_cat.error() << "Buffered_DatagramConnection::Reset()\n";
+  if (nativenet_cat.is_debug()) {
+    nativenet_cat.debug() << "Buffered_DatagramConnection::Reset()\n";
+  }
   ClearAll();
   ClearAll();
 }
 }
 
 

+ 7 - 5
panda/src/pgraph/geomNode.cxx

@@ -507,8 +507,10 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
       << " draw_mask = " << data._draw_mask << "\n";
       << " draw_mask = " << data._draw_mask << "\n";
   }
   }
 
 
+  Thread *current_thread = trav->get_current_thread();
+
   // Get all the Geoms, with no decalling.
   // Get all the Geoms, with no decalling.
-  Geoms geoms = get_geoms(trav->get_current_thread());
+  Geoms geoms = get_geoms(current_thread);
   int num_geoms = geoms.get_num_geoms();
   int num_geoms = geoms.get_num_geoms();
   trav->_geoms_pcollector.add_level(num_geoms);
   trav->_geoms_pcollector.add_level(num_geoms);
   CPT(TransformState) internal_transform = data.get_internal_transform(trav);
   CPT(TransformState) internal_transform = data.get_internal_transform(trav);
@@ -532,9 +534,9 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
     if (num_geoms > 1) {
     if (num_geoms > 1) {
       if (data._view_frustum != nullptr) {
       if (data._view_frustum != nullptr) {
         // Cull the individual Geom against the view frustum.
         // Cull the individual Geom against the view frustum.
-        CPT(BoundingVolume) geom_volume = geom->get_bounds();
+        CPT(BoundingVolume) geom_volume = geom->get_bounds(current_thread);
         const GeometricBoundingVolume *geom_gbv =
         const GeometricBoundingVolume *geom_gbv =
-          DCAST(GeometricBoundingVolume, geom_volume);
+          geom_volume->as_geometric_bounding_volume();
 
 
         int result = data._view_frustum->contains(geom_gbv);
         int result = data._view_frustum->contains(geom_gbv);
         if (result == BoundingVolume::IF_no_intersection) {
         if (result == BoundingVolume::IF_no_intersection) {
@@ -544,9 +546,9 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
       }
       }
       if (!data._cull_planes->is_empty()) {
       if (!data._cull_planes->is_empty()) {
         // Also cull the Geom against the cull planes.
         // Also cull the Geom against the cull planes.
-        CPT(BoundingVolume) geom_volume = geom->get_bounds();
+        CPT(BoundingVolume) geom_volume = geom->get_bounds(current_thread);
         const GeometricBoundingVolume *geom_gbv =
         const GeometricBoundingVolume *geom_gbv =
-          DCAST(GeometricBoundingVolume, geom_volume);
+          geom_volume->as_geometric_bounding_volume();
         int result;
         int result;
         data._cull_planes->do_cull(result, state, geom_gbv);
         data._cull_planes->do_cull(result, state, geom_gbv);
         if (result == BoundingVolume::IF_no_intersection) {
         if (result == BoundingVolume::IF_no_intersection) {

+ 6 - 0
panda/src/pgraph/pandaNode_ext.cxx

@@ -165,6 +165,12 @@ clear_python_tag(PyObject *key) {
   if (PyDict_GetItem(dict, key) != nullptr) {
   if (PyDict_GetItem(dict, key) != nullptr) {
     PyDict_DelItem(dict, key);
     PyDict_DelItem(dict, key);
   }
   }
+
+  if (PyDict_Size(dict) == 0 && Py_REFCNT(dict) == 1) {
+    // This was the last tag, and do_get_python_tags() made sure we have a
+    // unique reference to the tags, so clear the tag object.
+    _this->_python_tag_data.clear();
+  }
 }
 }
 
 
 /**
 /**

+ 3 - 0
pandatool/src/deploy-stub/deploy-stub.c

@@ -655,6 +655,9 @@ int main(int argc, char *argv[]) {
   PyImport_FrozenModules = blobinfo.pointers[0];
   PyImport_FrozenModules = blobinfo.pointers[0];
   retval = Py_FrozenMain(argc, argv);
   retval = Py_FrozenMain(argc, argv);
 
 
+  fflush(stdout);
+  fflush(stderr);
+
   unmap_blob(blob);
   unmap_blob(blob);
   return retval;
   return retval;
 }
 }

+ 0 - 1
samples/fireflies/light.sha

@@ -14,7 +14,6 @@ void vshader(float4 vtx_position : POSITION,
 }
 }
 
 
 void fshader(float4 l_pos: TEXCOORD0,
 void fshader(float4 l_pos: TEXCOORD0,
-             float4 l_scale: TEXCOORD1,
              uniform sampler2D k_texnormal : TEXUNIT0,
              uniform sampler2D k_texnormal : TEXUNIT0,
              uniform sampler2D k_texalbedo : TEXUNIT1,
              uniform sampler2D k_texalbedo : TEXUNIT1,
              uniform sampler2D k_texdepth  : TEXUNIT2,
              uniform sampler2D k_texdepth  : TEXUNIT2,

+ 29 - 0
tests/pgraph/test_nodepath.py

@@ -194,6 +194,35 @@ def test_nodepath_python_tags():
     assert rc1 == rc2
     assert rc1 == rc2
 
 
 
 
+def test_nodepath_clear_python_tag():
+    from panda3d.core import NodePath
+
+    path = NodePath("node")
+    assert not path.has_python_tag("a")
+    assert not path.has_python_tag("b")
+    assert not path.node().has_tags()
+
+    path.set_python_tag("a", "value")
+    assert path.has_python_tag("a")
+    assert not path.has_python_tag("b")
+    assert path.node().has_tags()
+
+    path.set_python_tag("b", "value")
+    assert path.has_python_tag("a")
+    assert path.has_python_tag("b")
+    assert path.node().has_tags()
+
+    path.clear_python_tag("a")
+    assert not path.has_python_tag("a")
+    assert path.has_python_tag("b")
+    assert path.node().has_tags()
+
+    path.clear_python_tag("b")
+    assert not path.has_python_tag("a")
+    assert not path.has_python_tag("b")
+    assert not path.node().has_tags()
+
+
 def test_nodepath_replace_texture():
 def test_nodepath_replace_texture():
     from panda3d.core import NodePath, Texture
     from panda3d.core import NodePath, Texture
 
 

+ 3 - 2
tests/putil/test_bitarray.py

@@ -129,12 +129,13 @@ def test_bitarray_has_any_of():
     ba = BitArray()
     ba = BitArray()
     assert not ba.has_any_of(100, 200)
     assert not ba.has_any_of(100, 200)
 
 
-    ba = BitArray(0x001fffffffffffff)
+    ba = BitArray()
+    ba.set_range(0, 53)
     assert ba.has_any_of(52, 1)
     assert ba.has_any_of(52, 1)
     assert ba.has_any_of(52, 100)
     assert ba.has_any_of(52, 100)
     assert not ba.has_any_of(53, 45)
     assert not ba.has_any_of(53, 45)
 
 
-    ba = BitArray(0)
+    ba = BitArray()
     ba.invert_in_place()
     ba.invert_in_place()
     assert ba.has_any_of(0, 1)
     assert ba.has_any_of(0, 1)
     assert ba.has_any_of(53, 45)
     assert ba.has_any_of(53, 45)

+ 2 - 2
tests/putil/test_clockobject.py

@@ -16,13 +16,13 @@ def test_clock_jump_frame_time(clockobj):
 def test_clock_get_real_time(clockobj):
 def test_clock_get_real_time(clockobj):
     current_time = clockobj.get_real_time()
     current_time = clockobj.get_real_time()
     time.sleep(0.4)
     time.sleep(0.4)
-    assert clockobj.get_real_time() - current_time >= 0.4
+    assert clockobj.get_real_time() - current_time >= 0.39
 
 
 
 
 def test_clock_get_long_time(clockobj):
 def test_clock_get_long_time(clockobj):
     current_time = clockobj.get_long_time()
     current_time = clockobj.get_long_time()
     time.sleep(0.4)
     time.sleep(0.4)
-    assert clockobj.get_long_time() - current_time >= 0.4
+    assert clockobj.get_long_time() - current_time >= 0.39
 
 
 
 
 def test_clock_get_dt(clockobj):
 def test_clock_get_dt(clockobj):

Some files were not shown because too many files changed in this diff