Merge branch 'master' into deploy-ng
This commit is contained in:
commit
3cb24fba91
14
README.md
14
README.md
|
|
@ -31,8 +31,8 @@ are included as part of the Windows 7.1 SDK.
|
|||
You will also need to have the third-party dependency libraries available for
|
||||
the build scripts to use. These are available from one of these two URLs,
|
||||
depending on whether you are on a 32-bit or 64-bit system:
|
||||
https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win32.zip
|
||||
https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win64.zip
|
||||
https://www.panda3d.org/download/panda3d-1.9.3/panda3d-1.9.3-tools-win32.zip
|
||||
https://www.panda3d.org/download/panda3d-1.9.3/panda3d-1.9.3-tools-win64.zip
|
||||
|
||||
After acquiring these dependencies, you may simply build Panda3D from the
|
||||
command prompt using the following command:
|
||||
|
|
@ -93,11 +93,11 @@ may have to use the installpanda.py script instead, which will directly copy the
|
|||
files into the appropriate locations on your computer. You may have to run the
|
||||
`ldconfig` tool in order to update your library cache after installing Panda3D.
|
||||
|
||||
Mac OS X
|
||||
--------
|
||||
macOS
|
||||
-----
|
||||
|
||||
On Mac OS X, you will need to download a set of precompiled thirdparty packages in order to
|
||||
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-mac.tar.gz).
|
||||
On macOS, you will need to download a set of precompiled thirdparty packages in order to
|
||||
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.3/panda3d-1.9.3-tools-mac.tar.gz).
|
||||
|
||||
After placing the thirdparty directory inside the panda3d source directory,
|
||||
you may build Panda3D using a command like the following:
|
||||
|
|
@ -107,7 +107,7 @@ python makepanda/makepanda.py --everything --installer
|
|||
```
|
||||
|
||||
In order to make a universal build, pass the --universal flag. You may also
|
||||
target a specific minimum Mac OS X version using the --osxtarget flag followed
|
||||
target a specific minimum macOS version using the --osxtarget flag followed
|
||||
by the release number, eg. 10.6 or 10.7.
|
||||
|
||||
If the build was successful, makepanda will have generated a .dmg file in
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ class DirectCameraControl(DirectObject):
|
|||
np = NodePath('temp')
|
||||
np.setPos(base.direct.camera, hitPt)
|
||||
self.coaMarkerPos = np.getPos()
|
||||
np.remove()
|
||||
np.removeNode()
|
||||
self.coaMarker.setPos(self.coaMarkerPos)
|
||||
|
||||
iRay.collisionNodePath.removeNode()
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ class DirectManipulationControl(DirectObject):
|
|||
|
||||
def drawMarquee(self, startX, startY):
|
||||
if self.marquee:
|
||||
self.marquee.remove()
|
||||
self.marquee.removeNode()
|
||||
self.marquee = None
|
||||
|
||||
if base.direct.cameraControl.useMayaCamControls and base.direct.fAlt:
|
||||
|
|
@ -228,7 +228,7 @@ class DirectManipulationControl(DirectObject):
|
|||
skipFlags |= SKIP_CAMERA * (1 - base.getControl())
|
||||
|
||||
if self.marquee:
|
||||
self.marquee.remove()
|
||||
self.marquee.removeNode()
|
||||
self.marquee = None
|
||||
base.direct.deselectAll()
|
||||
|
||||
|
|
@ -1691,7 +1691,7 @@ class ObjectHandles(NodePath, DirectObject):
|
|||
np.setPos(base.direct.camera, hitPt)
|
||||
resultPt = Point3(0)
|
||||
resultPt.assign(np.getPos())
|
||||
np.remove()
|
||||
np.removeNode()
|
||||
del iRay
|
||||
return resultPt
|
||||
|
||||
|
|
|
|||
|
|
@ -900,7 +900,7 @@ class DirectSession(DirectObject):
|
|||
# If nothing specified, try selected node path
|
||||
nodePath = self.selected.last
|
||||
if nodePath:
|
||||
nodePath.remove()
|
||||
nodePath.removeNode()
|
||||
|
||||
def removeAllSelected(self):
|
||||
self.selected.removeAll()
|
||||
|
|
|
|||
|
|
@ -177,8 +177,8 @@ class DirectSessionPanel(AppShell):
|
|||
sgeFrame, nodePath = render,
|
||||
scrolledCanvas_hull_width = 250,
|
||||
scrolledCanvas_hull_height = 300)
|
||||
self.SGE.pack(fill = BOTH, expand = 0)
|
||||
sgeFrame.pack(side = LEFT, fill = 'both', expand = 0)
|
||||
self.SGE.pack(fill = BOTH, expand = 1)
|
||||
sgeFrame.pack(side = LEFT, fill = 'both', expand = 1)
|
||||
|
||||
# Create the notebook pages
|
||||
notebook = Pmw.NoteBook(notebookFrame)
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ class MemoryExplorerItem:
|
|||
def getNumChildren(self):
|
||||
return len(self.children)
|
||||
|
||||
def getChildrenAsList(self):
|
||||
def getChildren(self):
|
||||
return self.children
|
||||
|
||||
def getName(self):
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -89,103 +89,105 @@ extern int cppyydebug;
|
|||
XOREQUAL = 299,
|
||||
LSHIFTEQUAL = 300,
|
||||
RSHIFTEQUAL = 301,
|
||||
KW_ALIGNAS = 302,
|
||||
KW_ALIGNOF = 303,
|
||||
KW_AUTO = 304,
|
||||
KW_BEGIN_PUBLISH = 305,
|
||||
KW_BLOCKING = 306,
|
||||
KW_BOOL = 307,
|
||||
KW_CATCH = 308,
|
||||
KW_CHAR = 309,
|
||||
KW_CHAR16_T = 310,
|
||||
KW_CHAR32_T = 311,
|
||||
KW_CLASS = 312,
|
||||
KW_CONST = 313,
|
||||
KW_CONSTEXPR = 314,
|
||||
KW_CONST_CAST = 315,
|
||||
KW_DECLTYPE = 316,
|
||||
KW_DEFAULT = 317,
|
||||
KW_DELETE = 318,
|
||||
KW_DOUBLE = 319,
|
||||
KW_DYNAMIC_CAST = 320,
|
||||
KW_ELSE = 321,
|
||||
KW_END_PUBLISH = 322,
|
||||
KW_ENUM = 323,
|
||||
KW_EXTENSION = 324,
|
||||
KW_EXTERN = 325,
|
||||
KW_EXPLICIT = 326,
|
||||
KW_PUBLISHED = 327,
|
||||
KW_FALSE = 328,
|
||||
KW_FINAL = 329,
|
||||
KW_FLOAT = 330,
|
||||
KW_FRIEND = 331,
|
||||
KW_FOR = 332,
|
||||
KW_GOTO = 333,
|
||||
KW_HAS_VIRTUAL_DESTRUCTOR = 334,
|
||||
KW_IF = 335,
|
||||
KW_INLINE = 336,
|
||||
KW_INT = 337,
|
||||
KW_IS_ABSTRACT = 338,
|
||||
KW_IS_BASE_OF = 339,
|
||||
KW_IS_CLASS = 340,
|
||||
KW_IS_CONSTRUCTIBLE = 341,
|
||||
KW_IS_CONVERTIBLE_TO = 342,
|
||||
KW_IS_DESTRUCTIBLE = 343,
|
||||
KW_IS_EMPTY = 344,
|
||||
KW_IS_ENUM = 345,
|
||||
KW_IS_FINAL = 346,
|
||||
KW_IS_FUNDAMENTAL = 347,
|
||||
KW_IS_POD = 348,
|
||||
KW_IS_POLYMORPHIC = 349,
|
||||
KW_IS_STANDARD_LAYOUT = 350,
|
||||
KW_IS_TRIVIAL = 351,
|
||||
KW_IS_UNION = 352,
|
||||
KW_LONG = 353,
|
||||
KW_MAKE_MAP_PROPERTY = 354,
|
||||
KW_MAKE_PROPERTY = 355,
|
||||
KW_MAKE_PROPERTY2 = 356,
|
||||
KW_MAKE_SEQ = 357,
|
||||
KW_MAKE_SEQ_PROPERTY = 358,
|
||||
KW_MUTABLE = 359,
|
||||
KW_NAMESPACE = 360,
|
||||
KW_NEW = 361,
|
||||
KW_NOEXCEPT = 362,
|
||||
KW_NULLPTR = 363,
|
||||
KW_OPERATOR = 364,
|
||||
KW_OVERRIDE = 365,
|
||||
KW_PRIVATE = 366,
|
||||
KW_PROTECTED = 367,
|
||||
KW_PUBLIC = 368,
|
||||
KW_REGISTER = 369,
|
||||
KW_REINTERPRET_CAST = 370,
|
||||
KW_RETURN = 371,
|
||||
KW_SHORT = 372,
|
||||
KW_SIGNED = 373,
|
||||
KW_SIZEOF = 374,
|
||||
KW_STATIC = 375,
|
||||
KW_STATIC_ASSERT = 376,
|
||||
KW_STATIC_CAST = 377,
|
||||
KW_STRUCT = 378,
|
||||
KW_TEMPLATE = 379,
|
||||
KW_THREAD_LOCAL = 380,
|
||||
KW_THROW = 381,
|
||||
KW_TRUE = 382,
|
||||
KW_TRY = 383,
|
||||
KW_TYPEDEF = 384,
|
||||
KW_TYPEID = 385,
|
||||
KW_TYPENAME = 386,
|
||||
KW_UNDERLYING_TYPE = 387,
|
||||
KW_UNION = 388,
|
||||
KW_UNSIGNED = 389,
|
||||
KW_USING = 390,
|
||||
KW_VIRTUAL = 391,
|
||||
KW_VOID = 392,
|
||||
KW_VOLATILE = 393,
|
||||
KW_WCHAR_T = 394,
|
||||
KW_WHILE = 395,
|
||||
START_CPP = 396,
|
||||
START_CONST_EXPR = 397,
|
||||
START_TYPE = 398
|
||||
ATTR_LEFT = 302,
|
||||
ATTR_RIGHT = 303,
|
||||
KW_ALIGNAS = 304,
|
||||
KW_ALIGNOF = 305,
|
||||
KW_AUTO = 306,
|
||||
KW_BEGIN_PUBLISH = 307,
|
||||
KW_BLOCKING = 308,
|
||||
KW_BOOL = 309,
|
||||
KW_CATCH = 310,
|
||||
KW_CHAR = 311,
|
||||
KW_CHAR16_T = 312,
|
||||
KW_CHAR32_T = 313,
|
||||
KW_CLASS = 314,
|
||||
KW_CONST = 315,
|
||||
KW_CONSTEXPR = 316,
|
||||
KW_CONST_CAST = 317,
|
||||
KW_DECLTYPE = 318,
|
||||
KW_DEFAULT = 319,
|
||||
KW_DELETE = 320,
|
||||
KW_DOUBLE = 321,
|
||||
KW_DYNAMIC_CAST = 322,
|
||||
KW_ELSE = 323,
|
||||
KW_END_PUBLISH = 324,
|
||||
KW_ENUM = 325,
|
||||
KW_EXTENSION = 326,
|
||||
KW_EXTERN = 327,
|
||||
KW_EXPLICIT = 328,
|
||||
KW_PUBLISHED = 329,
|
||||
KW_FALSE = 330,
|
||||
KW_FINAL = 331,
|
||||
KW_FLOAT = 332,
|
||||
KW_FRIEND = 333,
|
||||
KW_FOR = 334,
|
||||
KW_GOTO = 335,
|
||||
KW_HAS_VIRTUAL_DESTRUCTOR = 336,
|
||||
KW_IF = 337,
|
||||
KW_INLINE = 338,
|
||||
KW_INT = 339,
|
||||
KW_IS_ABSTRACT = 340,
|
||||
KW_IS_BASE_OF = 341,
|
||||
KW_IS_CLASS = 342,
|
||||
KW_IS_CONSTRUCTIBLE = 343,
|
||||
KW_IS_CONVERTIBLE_TO = 344,
|
||||
KW_IS_DESTRUCTIBLE = 345,
|
||||
KW_IS_EMPTY = 346,
|
||||
KW_IS_ENUM = 347,
|
||||
KW_IS_FINAL = 348,
|
||||
KW_IS_FUNDAMENTAL = 349,
|
||||
KW_IS_POD = 350,
|
||||
KW_IS_POLYMORPHIC = 351,
|
||||
KW_IS_STANDARD_LAYOUT = 352,
|
||||
KW_IS_TRIVIAL = 353,
|
||||
KW_IS_UNION = 354,
|
||||
KW_LONG = 355,
|
||||
KW_MAKE_MAP_PROPERTY = 356,
|
||||
KW_MAKE_PROPERTY = 357,
|
||||
KW_MAKE_PROPERTY2 = 358,
|
||||
KW_MAKE_SEQ = 359,
|
||||
KW_MAKE_SEQ_PROPERTY = 360,
|
||||
KW_MUTABLE = 361,
|
||||
KW_NAMESPACE = 362,
|
||||
KW_NEW = 363,
|
||||
KW_NOEXCEPT = 364,
|
||||
KW_NULLPTR = 365,
|
||||
KW_OPERATOR = 366,
|
||||
KW_OVERRIDE = 367,
|
||||
KW_PRIVATE = 368,
|
||||
KW_PROTECTED = 369,
|
||||
KW_PUBLIC = 370,
|
||||
KW_REGISTER = 371,
|
||||
KW_REINTERPRET_CAST = 372,
|
||||
KW_RETURN = 373,
|
||||
KW_SHORT = 374,
|
||||
KW_SIGNED = 375,
|
||||
KW_SIZEOF = 376,
|
||||
KW_STATIC = 377,
|
||||
KW_STATIC_ASSERT = 378,
|
||||
KW_STATIC_CAST = 379,
|
||||
KW_STRUCT = 380,
|
||||
KW_TEMPLATE = 381,
|
||||
KW_THREAD_LOCAL = 382,
|
||||
KW_THROW = 383,
|
||||
KW_TRUE = 384,
|
||||
KW_TRY = 385,
|
||||
KW_TYPEDEF = 386,
|
||||
KW_TYPEID = 387,
|
||||
KW_TYPENAME = 388,
|
||||
KW_UNDERLYING_TYPE = 389,
|
||||
KW_UNION = 390,
|
||||
KW_UNSIGNED = 391,
|
||||
KW_USING = 392,
|
||||
KW_VIRTUAL = 393,
|
||||
KW_VOID = 394,
|
||||
KW_VOLATILE = 395,
|
||||
KW_WCHAR_T = 396,
|
||||
KW_WHILE = 397,
|
||||
START_CPP = 398,
|
||||
START_CONST_EXPR = 399,
|
||||
START_TYPE = 400
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
|
|
@ -233,103 +235,105 @@ extern int cppyydebug;
|
|||
#define XOREQUAL 299
|
||||
#define LSHIFTEQUAL 300
|
||||
#define RSHIFTEQUAL 301
|
||||
#define KW_ALIGNAS 302
|
||||
#define KW_ALIGNOF 303
|
||||
#define KW_AUTO 304
|
||||
#define KW_BEGIN_PUBLISH 305
|
||||
#define KW_BLOCKING 306
|
||||
#define KW_BOOL 307
|
||||
#define KW_CATCH 308
|
||||
#define KW_CHAR 309
|
||||
#define KW_CHAR16_T 310
|
||||
#define KW_CHAR32_T 311
|
||||
#define KW_CLASS 312
|
||||
#define KW_CONST 313
|
||||
#define KW_CONSTEXPR 314
|
||||
#define KW_CONST_CAST 315
|
||||
#define KW_DECLTYPE 316
|
||||
#define KW_DEFAULT 317
|
||||
#define KW_DELETE 318
|
||||
#define KW_DOUBLE 319
|
||||
#define KW_DYNAMIC_CAST 320
|
||||
#define KW_ELSE 321
|
||||
#define KW_END_PUBLISH 322
|
||||
#define KW_ENUM 323
|
||||
#define KW_EXTENSION 324
|
||||
#define KW_EXTERN 325
|
||||
#define KW_EXPLICIT 326
|
||||
#define KW_PUBLISHED 327
|
||||
#define KW_FALSE 328
|
||||
#define KW_FINAL 329
|
||||
#define KW_FLOAT 330
|
||||
#define KW_FRIEND 331
|
||||
#define KW_FOR 332
|
||||
#define KW_GOTO 333
|
||||
#define KW_HAS_VIRTUAL_DESTRUCTOR 334
|
||||
#define KW_IF 335
|
||||
#define KW_INLINE 336
|
||||
#define KW_INT 337
|
||||
#define KW_IS_ABSTRACT 338
|
||||
#define KW_IS_BASE_OF 339
|
||||
#define KW_IS_CLASS 340
|
||||
#define KW_IS_CONSTRUCTIBLE 341
|
||||
#define KW_IS_CONVERTIBLE_TO 342
|
||||
#define KW_IS_DESTRUCTIBLE 343
|
||||
#define KW_IS_EMPTY 344
|
||||
#define KW_IS_ENUM 345
|
||||
#define KW_IS_FINAL 346
|
||||
#define KW_IS_FUNDAMENTAL 347
|
||||
#define KW_IS_POD 348
|
||||
#define KW_IS_POLYMORPHIC 349
|
||||
#define KW_IS_STANDARD_LAYOUT 350
|
||||
#define KW_IS_TRIVIAL 351
|
||||
#define KW_IS_UNION 352
|
||||
#define KW_LONG 353
|
||||
#define KW_MAKE_MAP_PROPERTY 354
|
||||
#define KW_MAKE_PROPERTY 355
|
||||
#define KW_MAKE_PROPERTY2 356
|
||||
#define KW_MAKE_SEQ 357
|
||||
#define KW_MAKE_SEQ_PROPERTY 358
|
||||
#define KW_MUTABLE 359
|
||||
#define KW_NAMESPACE 360
|
||||
#define KW_NEW 361
|
||||
#define KW_NOEXCEPT 362
|
||||
#define KW_NULLPTR 363
|
||||
#define KW_OPERATOR 364
|
||||
#define KW_OVERRIDE 365
|
||||
#define KW_PRIVATE 366
|
||||
#define KW_PROTECTED 367
|
||||
#define KW_PUBLIC 368
|
||||
#define KW_REGISTER 369
|
||||
#define KW_REINTERPRET_CAST 370
|
||||
#define KW_RETURN 371
|
||||
#define KW_SHORT 372
|
||||
#define KW_SIGNED 373
|
||||
#define KW_SIZEOF 374
|
||||
#define KW_STATIC 375
|
||||
#define KW_STATIC_ASSERT 376
|
||||
#define KW_STATIC_CAST 377
|
||||
#define KW_STRUCT 378
|
||||
#define KW_TEMPLATE 379
|
||||
#define KW_THREAD_LOCAL 380
|
||||
#define KW_THROW 381
|
||||
#define KW_TRUE 382
|
||||
#define KW_TRY 383
|
||||
#define KW_TYPEDEF 384
|
||||
#define KW_TYPEID 385
|
||||
#define KW_TYPENAME 386
|
||||
#define KW_UNDERLYING_TYPE 387
|
||||
#define KW_UNION 388
|
||||
#define KW_UNSIGNED 389
|
||||
#define KW_USING 390
|
||||
#define KW_VIRTUAL 391
|
||||
#define KW_VOID 392
|
||||
#define KW_VOLATILE 393
|
||||
#define KW_WCHAR_T 394
|
||||
#define KW_WHILE 395
|
||||
#define START_CPP 396
|
||||
#define START_CONST_EXPR 397
|
||||
#define START_TYPE 398
|
||||
#define ATTR_LEFT 302
|
||||
#define ATTR_RIGHT 303
|
||||
#define KW_ALIGNAS 304
|
||||
#define KW_ALIGNOF 305
|
||||
#define KW_AUTO 306
|
||||
#define KW_BEGIN_PUBLISH 307
|
||||
#define KW_BLOCKING 308
|
||||
#define KW_BOOL 309
|
||||
#define KW_CATCH 310
|
||||
#define KW_CHAR 311
|
||||
#define KW_CHAR16_T 312
|
||||
#define KW_CHAR32_T 313
|
||||
#define KW_CLASS 314
|
||||
#define KW_CONST 315
|
||||
#define KW_CONSTEXPR 316
|
||||
#define KW_CONST_CAST 317
|
||||
#define KW_DECLTYPE 318
|
||||
#define KW_DEFAULT 319
|
||||
#define KW_DELETE 320
|
||||
#define KW_DOUBLE 321
|
||||
#define KW_DYNAMIC_CAST 322
|
||||
#define KW_ELSE 323
|
||||
#define KW_END_PUBLISH 324
|
||||
#define KW_ENUM 325
|
||||
#define KW_EXTENSION 326
|
||||
#define KW_EXTERN 327
|
||||
#define KW_EXPLICIT 328
|
||||
#define KW_PUBLISHED 329
|
||||
#define KW_FALSE 330
|
||||
#define KW_FINAL 331
|
||||
#define KW_FLOAT 332
|
||||
#define KW_FRIEND 333
|
||||
#define KW_FOR 334
|
||||
#define KW_GOTO 335
|
||||
#define KW_HAS_VIRTUAL_DESTRUCTOR 336
|
||||
#define KW_IF 337
|
||||
#define KW_INLINE 338
|
||||
#define KW_INT 339
|
||||
#define KW_IS_ABSTRACT 340
|
||||
#define KW_IS_BASE_OF 341
|
||||
#define KW_IS_CLASS 342
|
||||
#define KW_IS_CONSTRUCTIBLE 343
|
||||
#define KW_IS_CONVERTIBLE_TO 344
|
||||
#define KW_IS_DESTRUCTIBLE 345
|
||||
#define KW_IS_EMPTY 346
|
||||
#define KW_IS_ENUM 347
|
||||
#define KW_IS_FINAL 348
|
||||
#define KW_IS_FUNDAMENTAL 349
|
||||
#define KW_IS_POD 350
|
||||
#define KW_IS_POLYMORPHIC 351
|
||||
#define KW_IS_STANDARD_LAYOUT 352
|
||||
#define KW_IS_TRIVIAL 353
|
||||
#define KW_IS_UNION 354
|
||||
#define KW_LONG 355
|
||||
#define KW_MAKE_MAP_PROPERTY 356
|
||||
#define KW_MAKE_PROPERTY 357
|
||||
#define KW_MAKE_PROPERTY2 358
|
||||
#define KW_MAKE_SEQ 359
|
||||
#define KW_MAKE_SEQ_PROPERTY 360
|
||||
#define KW_MUTABLE 361
|
||||
#define KW_NAMESPACE 362
|
||||
#define KW_NEW 363
|
||||
#define KW_NOEXCEPT 364
|
||||
#define KW_NULLPTR 365
|
||||
#define KW_OPERATOR 366
|
||||
#define KW_OVERRIDE 367
|
||||
#define KW_PRIVATE 368
|
||||
#define KW_PROTECTED 369
|
||||
#define KW_PUBLIC 370
|
||||
#define KW_REGISTER 371
|
||||
#define KW_REINTERPRET_CAST 372
|
||||
#define KW_RETURN 373
|
||||
#define KW_SHORT 374
|
||||
#define KW_SIGNED 375
|
||||
#define KW_SIZEOF 376
|
||||
#define KW_STATIC 377
|
||||
#define KW_STATIC_ASSERT 378
|
||||
#define KW_STATIC_CAST 379
|
||||
#define KW_STRUCT 380
|
||||
#define KW_TEMPLATE 381
|
||||
#define KW_THREAD_LOCAL 382
|
||||
#define KW_THROW 383
|
||||
#define KW_TRUE 384
|
||||
#define KW_TRY 385
|
||||
#define KW_TYPEDEF 386
|
||||
#define KW_TYPEID 387
|
||||
#define KW_TYPENAME 388
|
||||
#define KW_UNDERLYING_TYPE 389
|
||||
#define KW_UNION 390
|
||||
#define KW_UNSIGNED 391
|
||||
#define KW_USING 392
|
||||
#define KW_VIRTUAL 393
|
||||
#define KW_VOID 394
|
||||
#define KW_VOLATILE 395
|
||||
#define KW_WCHAR_T 396
|
||||
#define KW_WHILE 397
|
||||
#define START_CPP 398
|
||||
#define START_CONST_EXPR 399
|
||||
#define START_TYPE 400
|
||||
|
||||
/* Value type. */
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "cppBisonDefs.h"
|
||||
#include "cppParser.h"
|
||||
#include "cppClosureType.h"
|
||||
#include "cppExpression.h"
|
||||
#include "cppSimpleType.h"
|
||||
#include "cppExtensionType.h"
|
||||
|
|
@ -44,6 +45,7 @@ static CPPEnumType *current_enum = NULL;
|
|||
static int current_storage_class = 0;
|
||||
static CPPType *current_type = NULL;
|
||||
static CPPExpression *current_expr = NULL;
|
||||
static CPPClosureType *current_closure = NULL;
|
||||
static int publish_nest_level = 0;
|
||||
static CPPVisibility publish_previous;
|
||||
static YYLTYPE publish_loc;
|
||||
|
|
@ -247,6 +249,8 @@ pop_struct() {
|
|||
%token XOREQUAL
|
||||
%token LSHIFTEQUAL
|
||||
%token RSHIFTEQUAL
|
||||
%token ATTR_LEFT
|
||||
%token ATTR_RIGHT
|
||||
|
||||
%token KW_ALIGNAS
|
||||
%token KW_ALIGNOF
|
||||
|
|
@ -363,6 +367,8 @@ pop_struct() {
|
|||
%type <u.param_list> function_parameters
|
||||
%type <u.param_list> formal_parameter_list
|
||||
%type <u.param_list> formal_parameters
|
||||
%type <u.closure_type> capture_list
|
||||
%type <u.capture> capture
|
||||
%type <u.expr> template_parameter_maybe_initialize
|
||||
%type <u.expr> maybe_initialize
|
||||
%type <u.expr> maybe_initialize_or_constructor_body
|
||||
|
|
@ -870,10 +876,18 @@ storage_class:
|
|||
{
|
||||
$$ = $2 | (int)CPPInstance::SC_thread_local;
|
||||
}
|
||||
| '[' '[' attribute_specifiers ']' ']' storage_class
|
||||
| ATTR_LEFT attribute_specifiers ATTR_RIGHT storage_class
|
||||
{
|
||||
// Ignore attribute specifiers for now.
|
||||
$$ = $6;
|
||||
$$ = $4;
|
||||
}
|
||||
| KW_ALIGNAS '(' const_expr ')' storage_class
|
||||
{
|
||||
$$ = $5;
|
||||
}
|
||||
| KW_ALIGNAS '(' type_decl ')' storage_class
|
||||
{
|
||||
$$ = $5;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -885,6 +899,7 @@ attribute_specifiers:
|
|||
attribute_specifier:
|
||||
name
|
||||
| name '(' formal_parameter_list ')'
|
||||
| KW_USING name ':' attribute_specifier
|
||||
;
|
||||
|
||||
type_like_declaration:
|
||||
|
|
@ -1221,6 +1236,15 @@ function_post:
|
|||
{
|
||||
$$ = $1 | (int)CPPFunctionType::F_noexcept;
|
||||
}
|
||||
/* | function_post KW_NOEXCEPT '(' const_expr ')'
|
||||
{
|
||||
CPPExpression::Result result = $4->evaluate();
|
||||
if (result._type == CPPExpression::RT_error) {
|
||||
yywarning("noexcept requires a constant expression", @4);
|
||||
} else if (result.as_boolean()) {
|
||||
$$ = $1 | (int)CPPFunctionType::F_noexcept;
|
||||
}
|
||||
}*/
|
||||
| function_post KW_FINAL
|
||||
{
|
||||
$$ = $1 | (int)CPPFunctionType::F_final;
|
||||
|
|
@ -1241,6 +1265,11 @@ function_post:
|
|||
{
|
||||
// Used for lambdas, currently ignored.
|
||||
$$ = $1;
|
||||
}
|
||||
| function_post KW_CONSTEXPR
|
||||
{
|
||||
// Used for lambdas in C++17, currently ignored.
|
||||
$$ = $1;
|
||||
}
|
||||
| function_post KW_THROW '(' ')'
|
||||
{
|
||||
|
|
@ -1254,10 +1283,10 @@ function_post:
|
|||
{
|
||||
$$ = $1;
|
||||
}
|
||||
/* | function_post '[' '[' attribute_specifiers ']' ']'
|
||||
| function_post ATTR_LEFT attribute_specifiers ATTR_RIGHT
|
||||
{
|
||||
$$ = $1;
|
||||
}*/
|
||||
}
|
||||
;
|
||||
|
||||
function_operator:
|
||||
|
|
@ -1422,10 +1451,12 @@ function_operator:
|
|||
more_template_declaration:
|
||||
type_like_declaration
|
||||
| template_declaration
|
||||
| friend_declaration
|
||||
;
|
||||
|
||||
template_declaration:
|
||||
KW_TEMPLATE
|
||||
KW_EXTERN template_declaration
|
||||
| KW_TEMPLATE
|
||||
{
|
||||
push_scope(new CPPTemplateScope(current_scope));
|
||||
}
|
||||
|
|
@ -1433,7 +1464,8 @@ template_declaration:
|
|||
{
|
||||
pop_scope();
|
||||
}
|
||||
| KW_TEMPLATE type_like_declaration
|
||||
| KW_TEMPLATE type_like_declaration
|
||||
| KW_TEMPLATE friend_declaration
|
||||
;
|
||||
|
||||
template_formal_parameters:
|
||||
|
|
@ -1885,6 +1917,10 @@ function_parameter:
|
|||
| KW_REGISTER function_parameter
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| ATTR_LEFT attribute_specifiers ATTR_RIGHT function_parameter
|
||||
{
|
||||
$$ = $4;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -2228,16 +2264,16 @@ type:
|
|||
{
|
||||
$$ = CPPType::new_type($1);
|
||||
}
|
||||
| struct_keyword name
|
||||
| struct_keyword struct_attributes name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
||||
if (scope != NULL) {
|
||||
scope->define_extension_type(et);
|
||||
}
|
||||
|
|
@ -2268,6 +2304,10 @@ type:
|
|||
str << *$3;
|
||||
yyerror("could not determine type of " + str.str(), @3);
|
||||
}
|
||||
}
|
||||
| KW_DECLTYPE '(' KW_AUTO ')'
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
|
||||
}
|
||||
| KW_UNDERLYING_TYPE '(' full_type ')'
|
||||
{
|
||||
|
|
@ -2325,16 +2365,16 @@ type_decl:
|
|||
{
|
||||
$$ = new CPPTypeDeclaration(CPPType::new_type($1));
|
||||
}
|
||||
| struct_keyword name
|
||||
| struct_keyword struct_attributes name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
||||
if (scope != NULL) {
|
||||
scope->define_extension_type(et);
|
||||
}
|
||||
|
|
@ -2383,6 +2423,10 @@ type_decl:
|
|||
str << *$3;
|
||||
yyerror("could not determine type of " + str.str(), @3);
|
||||
}
|
||||
}
|
||||
| KW_DECLTYPE '(' KW_AUTO ')'
|
||||
{
|
||||
$$ = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto));
|
||||
}
|
||||
| KW_UNDERLYING_TYPE '(' full_type ')'
|
||||
{
|
||||
|
|
@ -2417,16 +2461,16 @@ predefined_type:
|
|||
{
|
||||
$$ = CPPType::new_type(new CPPTBDType($2));
|
||||
}
|
||||
| struct_keyword name
|
||||
| struct_keyword struct_attributes name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, false, current_lexer);
|
||||
CPPType *type = $3->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type != NULL) {
|
||||
$$ = type;
|
||||
} else {
|
||||
CPPExtensionType *et =
|
||||
CPPType::new_type(new CPPExtensionType($1, $2, current_scope, @1.file))
|
||||
CPPType::new_type(new CPPExtensionType($1, $3, current_scope, @1.file))
|
||||
->as_extension_type();
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope);
|
||||
if (scope != NULL) {
|
||||
scope->define_extension_type(et);
|
||||
}
|
||||
|
|
@ -2507,8 +2551,15 @@ full_type:
|
|||
}
|
||||
;
|
||||
|
||||
struct_attributes:
|
||||
empty
|
||||
| struct_attributes ATTR_LEFT attribute_specifiers ATTR_RIGHT
|
||||
| struct_attributes KW_ALIGNAS '(' const_expr ')'
|
||||
| struct_attributes KW_ALIGNAS '(' type_decl ')'
|
||||
;
|
||||
|
||||
anonymous_struct:
|
||||
struct_keyword '{'
|
||||
struct_keyword struct_attributes '{'
|
||||
{
|
||||
CPPVisibility starting_vis =
|
||||
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
||||
|
|
@ -2532,19 +2583,19 @@ anonymous_struct:
|
|||
;
|
||||
|
||||
named_struct:
|
||||
struct_keyword name_no_final
|
||||
struct_keyword struct_attributes name_no_final
|
||||
{
|
||||
CPPVisibility starting_vis =
|
||||
($1 == CPPExtensionType::T_class) ? V_private : V_public;
|
||||
|
||||
CPPScope *scope = $2->get_scope(current_scope, global_scope, current_lexer);
|
||||
CPPScope *scope = $3->get_scope(current_scope, global_scope, current_lexer);
|
||||
if (scope == NULL) {
|
||||
scope = current_scope;
|
||||
}
|
||||
CPPScope *new_scope = new CPPScope(scope, $2->_names.back(),
|
||||
CPPScope *new_scope = new CPPScope(scope, $3->_names.back(),
|
||||
starting_vis);
|
||||
|
||||
CPPStructType *st = new CPPStructType($1, $2, current_scope,
|
||||
CPPStructType *st = new CPPStructType($1, $3, current_scope,
|
||||
new_scope, @1.file);
|
||||
new_scope->set_struct_type(st);
|
||||
current_scope->define_extension_type(st);
|
||||
|
|
@ -2927,6 +2978,7 @@ element:
|
|||
| SCOPE | PLUSPLUS | MINUSMINUS
|
||||
| TIMESEQUAL | DIVIDEEQUAL | MODEQUAL | PLUSEQUAL | MINUSEQUAL
|
||||
| OREQUAL | ANDEQUAL | XOREQUAL | LSHIFTEQUAL | RSHIFTEQUAL
|
||||
| ATTR_LEFT | ATTR_RIGHT
|
||||
| KW_ALIGNAS | KW_ALIGNOF | KW_AUTO | KW_BOOL | KW_CATCH
|
||||
| KW_CHAR | KW_CHAR16_T | KW_CHAR32_T | KW_CLASS | KW_CONST
|
||||
| KW_CONSTEXPR | KW_CONST_CAST | KW_DECLTYPE | KW_DEFAULT
|
||||
|
|
@ -3010,6 +3062,18 @@ no_angle_bracket_const_expr:
|
|||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
||||
}
|
||||
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
||||
{
|
||||
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (arg == (CPPDeclaration *)NULL) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
||||
{
|
||||
|
|
@ -3172,6 +3236,16 @@ const_expr:
|
|||
}
|
||||
assert(type != NULL);
|
||||
$$ = new CPPExpression(CPPExpression::construct_op(type, $3));
|
||||
}
|
||||
| TYPENAME_IDENTIFIER '{' optional_const_expr_comma '}'
|
||||
{
|
||||
// Aggregate initialization.
|
||||
CPPType *type = $1->find_type(current_scope, global_scope, false, current_lexer);
|
||||
if (type == NULL) {
|
||||
yyerror(string("internal error resolving type ") + $1->get_fully_scoped_name(), @1);
|
||||
}
|
||||
assert(type != NULL);
|
||||
$$ = new CPPExpression(CPPExpression::aggregate_init_op(type, $3));
|
||||
}
|
||||
| KW_INT '(' optional_const_expr_comma ')'
|
||||
{
|
||||
|
|
@ -3252,6 +3326,18 @@ const_expr:
|
|||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
||||
}
|
||||
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
||||
{
|
||||
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (arg == (CPPDeclaration *)NULL) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
||||
{
|
||||
|
|
@ -3468,11 +3554,16 @@ const_operand:
|
|||
}
|
||||
| '[' capture_list ']' function_post maybe_trailing_return_type '{' code '}'
|
||||
{
|
||||
$$ = NULL;
|
||||
$2->_flags = $4;
|
||||
$2->_return_type = $5;
|
||||
$$ = new CPPExpression(CPPExpression::lambda($2));
|
||||
}
|
||||
| '[' capture_list ']' '(' function_parameter_list ')' function_post maybe_trailing_return_type '{' code '}'
|
||||
{
|
||||
$$ = NULL;
|
||||
$2->_parameters = $5;
|
||||
$2->_flags = $7;
|
||||
$2->_return_type = $8;
|
||||
$$ = new CPPExpression(CPPExpression::lambda($2));
|
||||
}
|
||||
| KW_HAS_VIRTUAL_DESTRUCTOR '(' full_type ')'
|
||||
{
|
||||
|
|
@ -3579,6 +3670,18 @@ formal_const_expr:
|
|||
| KW_SIZEOF '(' full_type ')' %prec UNARY
|
||||
{
|
||||
$$ = new CPPExpression(CPPExpression::sizeof_func($3));
|
||||
}
|
||||
| KW_SIZEOF '(' IDENTIFIER ')' %prec UNARY
|
||||
{
|
||||
CPPDeclaration *arg = $3->find_symbol(current_scope, global_scope, current_lexer);
|
||||
if (arg == (CPPDeclaration *)NULL) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
| KW_SIZEOF ELLIPSIS '(' name ')' %prec UNARY
|
||||
{
|
||||
|
|
@ -3794,15 +3897,65 @@ formal_const_operand:
|
|||
/* The contents of the [] list preceding a lambda expression. */
|
||||
capture_list:
|
||||
empty
|
||||
| capture
|
||||
| capture ',' capture_list
|
||||
{
|
||||
$$ = new CPPClosureType();
|
||||
}
|
||||
| '='
|
||||
{
|
||||
$$ = new CPPClosureType(CPPClosureType::CT_by_value);
|
||||
}
|
||||
| '&'
|
||||
{
|
||||
$$ = new CPPClosureType(CPPClosureType::CT_by_reference);
|
||||
}
|
||||
| capture maybe_initialize
|
||||
{
|
||||
$$ = new CPPClosureType();
|
||||
$1->_initializer = $2;
|
||||
$$->_captures.push_back(*$1);
|
||||
delete $1;
|
||||
}
|
||||
| capture_list ',' capture maybe_initialize
|
||||
{
|
||||
$$ = $1;
|
||||
$3->_initializer = $4;
|
||||
$$->_captures.push_back(*$3);
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
capture:
|
||||
'&'
|
||||
| '='
|
||||
| '&' name
|
||||
'&' name
|
||||
{
|
||||
$$ = new CPPClosureType::Capture;
|
||||
$$->_name = $2->get_simple_name();
|
||||
$$->_type = CPPClosureType::CT_by_reference;
|
||||
}
|
||||
| '&' name ELLIPSIS
|
||||
{
|
||||
$$ = new CPPClosureType::Capture;
|
||||
$$->_name = $2->get_simple_name();
|
||||
$$->_type = CPPClosureType::CT_by_reference;
|
||||
}
|
||||
| name
|
||||
{
|
||||
$$ = new CPPClosureType::Capture;
|
||||
$$->_name = $1->get_simple_name();
|
||||
if ($$->_name == "this") {
|
||||
$$->_type = CPPClosureType::CT_by_reference;
|
||||
} else {
|
||||
$$->_type = CPPClosureType::CT_by_value;
|
||||
}
|
||||
}
|
||||
| '*' name
|
||||
{
|
||||
$$ = new CPPClosureType::Capture;
|
||||
$$->_name = $2->get_simple_name();
|
||||
$$->_type = CPPClosureType::CT_by_value;
|
||||
if ($$->_name != "this") {
|
||||
yywarning("only capture name 'this' may be preceded by an asterisk", @2);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
class_derivation_name:
|
||||
|
|
@ -3813,14 +3966,6 @@ class_derivation_name:
|
|||
type = CPPType::new_type(new CPPTBDType($1));
|
||||
}
|
||||
$$ = type;
|
||||
}
|
||||
| struct_keyword name
|
||||
{
|
||||
CPPType *type = $2->find_type(current_scope, global_scope, true, current_lexer);
|
||||
if (type == NULL) {
|
||||
type = CPPType::new_type(new CPPTBDType($2));
|
||||
}
|
||||
$$ = type;
|
||||
}
|
||||
| KW_TYPENAME name
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "cppClosureType.h"
|
||||
#include "cppExtensionType.h"
|
||||
#include "cppFile.h"
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ class CPPParameterList;
|
|||
class CPPTemplateParameterList;
|
||||
class CPPScope;
|
||||
class CPPIdentifier;
|
||||
class CPPCaptureType;
|
||||
|
||||
void parse_cpp(CPPParser *cp);
|
||||
CPPExpression *parse_const_expr(CPPPreprocessor *pp,
|
||||
|
|
@ -81,6 +83,8 @@ public:
|
|||
CPPExtensionType::Type extension_enum;
|
||||
CPPExpression *expr;
|
||||
CPPIdentifier *identifier;
|
||||
CPPClosureType *closure_type;
|
||||
CPPClosureType::Capture *capture;
|
||||
} u;
|
||||
};
|
||||
#define YYSTYPE cppyystype
|
||||
|
|
|
|||
|
|
@ -0,0 +1,196 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file cppClosureType.cxx
|
||||
* @author rdb
|
||||
* @date 2017-01-14
|
||||
*/
|
||||
|
||||
#include "cppClosureType.h"
|
||||
#include "cppParameterList.h"
|
||||
#include "cppExpression.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPClosureType::
|
||||
CPPClosureType(CaptureType default_capture) :
|
||||
CPPFunctionType(NULL, NULL, 0),
|
||||
_default_capture(default_capture) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPClosureType::
|
||||
CPPClosureType(const CPPClosureType ©) :
|
||||
CPPFunctionType(copy),
|
||||
_captures(copy._captures),
|
||||
_default_capture(copy._default_capture)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void CPPClosureType::
|
||||
operator = (const CPPClosureType ©) {
|
||||
CPPFunctionType::operator = (copy);
|
||||
_captures = copy._captures;
|
||||
_default_capture = copy._default_capture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new capture to the beginning of the capture list.
|
||||
*/
|
||||
void CPPClosureType::
|
||||
add_capture(string name, CaptureType type, CPPExpression *initializer) {
|
||||
if (type == CT_none) {
|
||||
if (name == "this") {
|
||||
type = CT_by_reference;
|
||||
} else {
|
||||
type = CT_by_value;
|
||||
}
|
||||
}
|
||||
|
||||
Capture capture = {move(name), type, initializer};
|
||||
_captures.insert(_captures.begin(), move(capture));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this declaration is an actual, factual declaration, or
|
||||
* false if some part of the declaration depends on a template parameter which
|
||||
* has not yet been instantiated.
|
||||
*/
|
||||
bool CPPClosureType::
|
||||
is_fully_specified() const {
|
||||
return CPPFunctionType::is_fully_specified();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is default-constructible.
|
||||
*/
|
||||
bool CPPClosureType::
|
||||
is_default_constructible() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is copy-constructible.
|
||||
*/
|
||||
bool CPPClosureType::
|
||||
is_copy_constructible() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type is destructible.
|
||||
*/
|
||||
bool CPPClosureType::
|
||||
is_destructible() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void CPPClosureType::
|
||||
output(ostream &out, int indent_level, CPPScope *scope, bool complete) const {
|
||||
out.put('[');
|
||||
|
||||
bool have_capture = false;
|
||||
switch (_default_capture) {
|
||||
case CT_none:
|
||||
break;
|
||||
case CT_by_reference:
|
||||
out.put('&');
|
||||
have_capture = true;
|
||||
break;
|
||||
case CT_by_value:
|
||||
out.put('=');
|
||||
have_capture = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Captures::const_iterator it;
|
||||
for (it = _captures.begin(); it != _captures.end(); ++it) {
|
||||
const Capture &capture = *it;
|
||||
if (have_capture) {
|
||||
out << ", ";
|
||||
}
|
||||
if (capture._name == "this") {
|
||||
if (capture._type == CT_by_value) {
|
||||
out.put('*');
|
||||
}
|
||||
} else {
|
||||
if (capture._type == CT_by_reference) {
|
||||
out.put('&');
|
||||
}
|
||||
}
|
||||
out << capture._name;
|
||||
|
||||
if (capture._initializer != NULL) {
|
||||
out << " = " << *capture._initializer;
|
||||
}
|
||||
|
||||
have_capture = true;
|
||||
}
|
||||
out.put(']');
|
||||
|
||||
if (_parameters != NULL) {
|
||||
out.put('(');
|
||||
_parameters->output(out, scope, true, -1);
|
||||
out.put(')');
|
||||
}
|
||||
|
||||
if (_flags & F_noexcept) {
|
||||
out << " noexcept";
|
||||
}
|
||||
|
||||
if (_return_type != NULL) {
|
||||
out << " -> ";
|
||||
_return_type->output(out, indent_level, scope, false);
|
||||
}
|
||||
|
||||
out << " {}";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPDeclaration::SubType CPPClosureType::
|
||||
get_subtype() const {
|
||||
return ST_closure;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPClosureType *CPPClosureType::
|
||||
as_closure_type() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by CPPDeclaration() to determine whether this type is equivalent to
|
||||
* another type of the same type.
|
||||
*/
|
||||
bool CPPClosureType::
|
||||
is_equal(const CPPDeclaration *other) const {
|
||||
return (this == other);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by CPPDeclaration() to determine whether this type should be ordered
|
||||
* before another type of the same type, in an arbitrary but fixed ordering.
|
||||
*/
|
||||
bool CPPClosureType::
|
||||
is_less(const CPPDeclaration *other) const {
|
||||
return (this < other);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file cppClosureType.h
|
||||
* @author rdb
|
||||
* @date 2017-01-14
|
||||
*/
|
||||
|
||||
#ifndef CPPCLOSURETYPE_H
|
||||
#define CPPCLOSURETYPE_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#include "cppFunctionType.h"
|
||||
|
||||
/**
|
||||
* The type of a lambda expression. This is like a function, but with
|
||||
* additional captures defined.
|
||||
*/
|
||||
class CPPClosureType : public CPPFunctionType {
|
||||
public:
|
||||
enum CaptureType {
|
||||
CT_none,
|
||||
CT_by_reference,
|
||||
CT_by_value,
|
||||
};
|
||||
|
||||
CPPClosureType(CaptureType default_capture = CT_none);
|
||||
CPPClosureType(const CPPClosureType ©);
|
||||
void operator = (const CPPClosureType ©);
|
||||
|
||||
struct Capture {
|
||||
string _name;
|
||||
CaptureType _type;
|
||||
CPPExpression *_initializer;
|
||||
};
|
||||
typedef vector<Capture> Captures;
|
||||
Captures _captures;
|
||||
|
||||
CaptureType _default_capture;
|
||||
|
||||
void add_capture(string name, CaptureType type, CPPExpression *initializer = NULL);
|
||||
|
||||
virtual bool is_fully_specified() const;
|
||||
|
||||
virtual bool is_default_constructible() const;
|
||||
virtual bool is_copy_constructible() const;
|
||||
virtual bool is_destructible() const;
|
||||
|
||||
virtual void output(ostream &out, int indent_level, CPPScope *scope,
|
||||
bool complete) const;
|
||||
virtual SubType get_subtype() const;
|
||||
virtual CPPClosureType *as_closure_type();
|
||||
|
||||
protected:
|
||||
virtual bool is_equal(const CPPDeclaration *other) const;
|
||||
virtual bool is_less(const CPPDeclaration *other) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -311,6 +311,14 @@ as_make_seq() {
|
|||
return (CPPMakeSeq *)NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPClosureType *CPPDeclaration::
|
||||
as_closure_type() {
|
||||
return (CPPClosureType *)NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by CPPDeclaration to determine whether this type is equivalent to
|
||||
* another type of the same type.
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class CPPEnumType;
|
|||
class CPPTypeProxy;
|
||||
class CPPMakeProperty;
|
||||
class CPPMakeSeq;
|
||||
class CPPClosureType;
|
||||
class CPPClassTemplateParameter;
|
||||
class CPPTBDType;
|
||||
class CPPScope;
|
||||
|
|
@ -85,6 +86,7 @@ public:
|
|||
ST_tbd,
|
||||
ST_type_proxy,
|
||||
ST_typedef,
|
||||
ST_closure,
|
||||
};
|
||||
|
||||
CPPDeclaration(const CPPFile &file);
|
||||
|
|
@ -140,6 +142,7 @@ public:
|
|||
virtual CPPTypeProxy *as_type_proxy();
|
||||
virtual CPPMakeProperty *as_make_property();
|
||||
virtual CPPMakeSeq *as_make_seq();
|
||||
virtual CPPClosureType *as_closure_type();
|
||||
|
||||
inline const CPPInstance *as_instance() const {
|
||||
return ((CPPDeclaration *)this)->as_instance();
|
||||
|
|
@ -207,6 +210,9 @@ public:
|
|||
inline const CPPMakeSeq *as_make_seq() const {
|
||||
return ((CPPDeclaration *)this)->as_make_seq();
|
||||
}
|
||||
inline const CPPClosureType *as_closure_type() const {
|
||||
return ((CPPDeclaration *)this)->as_closure_type();
|
||||
}
|
||||
|
||||
CPPVisibility _vis;
|
||||
CPPTemplateScope *_template_scope;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "cppInstance.h"
|
||||
#include "cppFunctionGroup.h"
|
||||
#include "cppFunctionType.h"
|
||||
#include "cppClosureType.h"
|
||||
#include "cppStructType.h"
|
||||
#include "cppBison.h"
|
||||
#include "pdtoa.h"
|
||||
|
|
@ -256,13 +257,12 @@ CPPExpression(CPPIdentifier *ident, CPPScope *current_scope,
|
|||
_u._variable = inst;
|
||||
return;
|
||||
}
|
||||
// Actually, we can't scope function groups.
|
||||
/*CPPFunctionGroup *fgroup = decl->as_function_group();
|
||||
CPPFunctionGroup *fgroup = decl->as_function_group();
|
||||
if (fgroup != NULL) {
|
||||
_type = T_function;
|
||||
_u._fgroup = fgroup;
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
_type = T_unknown_ident;
|
||||
|
|
@ -346,6 +346,22 @@ construct_op(CPPType *type, CPPExpression *op1) {
|
|||
return expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression that represents an aggregate initialization.
|
||||
*/
|
||||
CPPExpression CPPExpression::
|
||||
aggregate_init_op(CPPType *type, CPPExpression *op1) {
|
||||
CPPExpression expr(0);
|
||||
if (op1 == NULL) {
|
||||
expr._type = T_empty_aggregate_init;
|
||||
} else {
|
||||
expr._type = T_aggregate_init;
|
||||
}
|
||||
expr._u._typecast._to = type;
|
||||
expr._u._typecast._op1 = op1;
|
||||
return expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression that represents a use of the new operator.
|
||||
*/
|
||||
|
|
@ -438,6 +454,17 @@ alignof_func(CPPType *type) {
|
|||
return expr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPPExpression CPPExpression::
|
||||
lambda(CPPClosureType *type) {
|
||||
CPPExpression expr(0);
|
||||
expr._type = T_lambda;
|
||||
expr._u._closure_type = type;
|
||||
return expr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -594,6 +621,8 @@ evaluate() const {
|
|||
|
||||
case T_construct:
|
||||
case T_default_construct:
|
||||
case T_aggregate_init:
|
||||
case T_empty_aggregate_init:
|
||||
case T_new:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
|
|
@ -1017,6 +1046,8 @@ determine_type() const {
|
|||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_default_construct:
|
||||
case T_aggregate_init:
|
||||
case T_empty_aggregate_init:
|
||||
return _u._typecast._to;
|
||||
|
||||
case T_new:
|
||||
|
|
@ -1135,10 +1166,28 @@ determine_type() const {
|
|||
|
||||
case 'f': // Function evaluation
|
||||
if (t1 != NULL) {
|
||||
// Easy case, function with only a single overload.
|
||||
CPPFunctionType *ftype = t1->as_function_type();
|
||||
if (ftype != (CPPFunctionType *)NULL) {
|
||||
return ftype->_return_type;
|
||||
}
|
||||
} else if (_u._op._op1->_type == T_function) {
|
||||
CPPFunctionGroup *fgroup = _u._op._op1->_u._fgroup;
|
||||
if (_u._op._op2 == NULL) {
|
||||
// If we are passing no args, look for an overload that has takes no
|
||||
// args.
|
||||
for (auto it = fgroup->_instances.begin(); it != fgroup->_instances.end(); ++it) {
|
||||
CPPInstance *inst = *it;
|
||||
if (inst != NULL && inst->_type != NULL) {
|
||||
CPPFunctionType *type = inst->_type->as_function_type();
|
||||
if (type != NULL && type->accepts_num_parameters(0)) {
|
||||
return type->_return_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
|
|
@ -1169,6 +1218,9 @@ determine_type() const {
|
|||
case T_type_trait:
|
||||
return bool_type;
|
||||
|
||||
case T_lambda:
|
||||
return _u._closure_type;
|
||||
|
||||
default:
|
||||
cerr << "**invalid operand**\n";
|
||||
abort();
|
||||
|
|
@ -1215,11 +1267,13 @@ is_fully_specified() const {
|
|||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
return (_u._typecast._to->is_fully_specified() &&
|
||||
_u._typecast._op1->is_fully_specified());
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
|
|
@ -1259,6 +1313,9 @@ is_fully_specified() const {
|
|||
case T_type_trait:
|
||||
return _u._type_trait._type->is_fully_specified();
|
||||
|
||||
case T_lambda:
|
||||
return _u._closure_type->is_fully_specified();
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1342,6 +1399,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
rep->_u._typecast._op1 =
|
||||
_u._typecast._op1->substitute_decl(subst, current_scope, global_scope)
|
||||
|
|
@ -1350,6 +1408,7 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
// fall through
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
|
|
@ -1444,6 +1503,8 @@ is_tbd() const {
|
|||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_empty_aggregate_init:
|
||||
case T_new:
|
||||
case T_default_construct:
|
||||
case T_default_new:
|
||||
|
|
@ -1478,6 +1539,9 @@ is_tbd() const {
|
|||
case T_type_trait:
|
||||
return _u._type_trait._type->is_tbd();
|
||||
|
||||
case T_lambda:
|
||||
return _u._closure_type->is_tbd();
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1558,6 +1622,10 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
out << "\\\"";
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
out << "\\\\";
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isprint(*si)) {
|
||||
out << *si;
|
||||
|
|
@ -1649,6 +1717,18 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
out << "()";
|
||||
break;
|
||||
|
||||
case T_aggregate_init:
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << "{";
|
||||
_u._typecast._op1->output(out, indent_level, scope, false);
|
||||
out << "}";
|
||||
break;
|
||||
|
||||
case T_empty_aggregate_init:
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
out << "{}";
|
||||
break;
|
||||
|
||||
case T_new:
|
||||
out << "(new ";
|
||||
_u._typecast._to->output(out, indent_level, scope, false);
|
||||
|
|
@ -1946,6 +2026,10 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
|
|||
out << ')';
|
||||
break;
|
||||
|
||||
case T_lambda:
|
||||
_u._closure_type->output(out, indent_level, scope, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
out << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
@ -2066,11 +2150,13 @@ is_equal(const CPPDeclaration *other) const {
|
|||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
return _u._typecast._to == ot->_u._typecast._to &&
|
||||
*_u._typecast._op1 == *ot->_u._typecast._op1;
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
|
|
@ -2105,6 +2191,9 @@ is_equal(const CPPDeclaration *other) const {
|
|||
return _u._type_trait._trait == ot->_u._type_trait._trait &&
|
||||
_u._type_trait._type == ot->_u._type_trait._type;
|
||||
|
||||
case T_lambda:
|
||||
return _u._closure_type == ot->_u._closure_type;
|
||||
|
||||
default:
|
||||
cerr << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
@ -2161,6 +2250,7 @@ is_less(const CPPDeclaration *other) const {
|
|||
case T_const_cast:
|
||||
case T_reinterpret_cast:
|
||||
case T_construct:
|
||||
case T_aggregate_init:
|
||||
case T_new:
|
||||
if (_u._typecast._to != ot->_u._typecast._to) {
|
||||
return _u._typecast._to < ot->_u._typecast._to;
|
||||
|
|
@ -2168,6 +2258,7 @@ is_less(const CPPDeclaration *other) const {
|
|||
return *_u._typecast._op1 < *ot->_u._typecast._op1;
|
||||
|
||||
case T_default_construct:
|
||||
case T_empty_aggregate_init:
|
||||
case T_default_new:
|
||||
case T_sizeof:
|
||||
case T_alignof:
|
||||
|
|
@ -2212,6 +2303,9 @@ is_less(const CPPDeclaration *other) const {
|
|||
}
|
||||
return *_u._type_trait._type < *ot->_u._type_trait._type;
|
||||
|
||||
case T_lambda:
|
||||
return _u._closure_type < ot->_u._closure_type;
|
||||
|
||||
default:
|
||||
cerr << "(** invalid operand type " << (int)_type << " **)";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ public:
|
|||
T_reinterpret_cast,
|
||||
T_construct,
|
||||
T_default_construct,
|
||||
T_aggregate_init,
|
||||
T_empty_aggregate_init,
|
||||
T_new,
|
||||
T_default_new,
|
||||
T_sizeof,
|
||||
|
|
@ -61,6 +63,7 @@ public:
|
|||
T_typeid_type,
|
||||
T_typeid_expr,
|
||||
T_type_trait,
|
||||
T_lambda,
|
||||
|
||||
// These are used when parsing =default and =delete methods.
|
||||
T_default,
|
||||
|
|
@ -80,6 +83,7 @@ public:
|
|||
|
||||
static CPPExpression typecast_op(CPPType *type, CPPExpression *op1, Type cast_type = T_typecast);
|
||||
static CPPExpression construct_op(CPPType *type, CPPExpression *op1);
|
||||
static CPPExpression aggregate_init_op(CPPType *type, CPPExpression *op1);
|
||||
static CPPExpression new_op(CPPType *type, CPPExpression *op1 = NULL);
|
||||
static CPPExpression typeid_op(CPPType *type, CPPType *std_type_info);
|
||||
static CPPExpression typeid_op(CPPExpression *op1, CPPType *std_type_info);
|
||||
|
|
@ -87,6 +91,7 @@ public:
|
|||
static CPPExpression sizeof_func(CPPType *type);
|
||||
static CPPExpression sizeof_ellipsis_func(CPPIdentifier *ident);
|
||||
static CPPExpression alignof_func(CPPType *type);
|
||||
static CPPExpression lambda(CPPClosureType *type);
|
||||
|
||||
static CPPExpression literal(unsigned long long value, CPPInstance *lit_op);
|
||||
static CPPExpression literal(long double value, CPPInstance *lit_op);
|
||||
|
|
@ -150,6 +155,7 @@ public:
|
|||
CPPInstance *_variable;
|
||||
CPPFunctionGroup *_fgroup;
|
||||
CPPIdentifier *_ident;
|
||||
CPPClosureType *_closure_type;
|
||||
struct {
|
||||
union {
|
||||
CPPType *_type;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ CPPFunctionType(CPPType *return_type, CPPParameterList *parameters,
|
|||
|
||||
// If the parameter list contains just the token "void", it means no
|
||||
// parameters.
|
||||
if (_parameters->_parameters.size() == 1 &&
|
||||
if (_parameters != NULL &&
|
||||
_parameters->_parameters.size() == 1 &&
|
||||
_parameters->_parameters.front()->_type->as_simple_type() != NULL &&
|
||||
_parameters->_parameters.front()->_type->as_simple_type()->_type ==
|
||||
CPPSimpleType::T_void &&
|
||||
|
|
@ -65,6 +66,31 @@ operator = (const CPPFunctionType ©) {
|
|||
_class_owner = copy._class_owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the function accepts the given number of parameters.
|
||||
*/
|
||||
bool CPPFunctionType::
|
||||
accepts_num_parameters(int num_parameters) {
|
||||
if (_parameters == NULL) {
|
||||
return (num_parameters == 0);
|
||||
}
|
||||
size_t actual_num_parameters = _parameters->_parameters.size();
|
||||
// If we passed too many parameters, it must have an ellipsis.
|
||||
if (num_parameters > actual_num_parameters) {
|
||||
return _parameters->_includes_ellipsis;
|
||||
}
|
||||
|
||||
// Make sure all superfluous parameters have a default value.
|
||||
for (size_t i = num_parameters; i < actual_num_parameters; ++i) {
|
||||
CPPInstance *param = _parameters->_parameters[i];
|
||||
if (param->_initializer == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this declaration is an actual, factual declaration, or
|
||||
* false if some part of the declaration depends on a template parameter which
|
||||
|
|
@ -95,8 +121,10 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
->as_type();
|
||||
}
|
||||
|
||||
rep->_parameters =
|
||||
_parameters->substitute_decl(subst, current_scope, global_scope);
|
||||
if (_parameters != NULL) {
|
||||
rep->_parameters =
|
||||
_parameters->substitute_decl(subst, current_scope, global_scope);
|
||||
}
|
||||
|
||||
if (rep->_return_type == _return_type &&
|
||||
rep->_parameters == _parameters) {
|
||||
|
|
@ -117,8 +145,12 @@ substitute_decl(CPPDeclaration::SubstDecl &subst,
|
|||
CPPType *CPPFunctionType::
|
||||
resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
|
||||
CPPType *rtype = _return_type->resolve_type(current_scope, global_scope);
|
||||
CPPParameterList *params =
|
||||
_parameters->resolve_type(current_scope, global_scope);
|
||||
CPPParameterList *params;
|
||||
if (_parameters == NULL) {
|
||||
params = NULL;
|
||||
} else {
|
||||
params = _parameters->resolve_type(current_scope, global_scope);
|
||||
}
|
||||
|
||||
if (rtype != _return_type || params != _parameters) {
|
||||
CPPFunctionType *rep = new CPPFunctionType(*this);
|
||||
|
|
@ -139,7 +171,7 @@ is_tbd() const {
|
|||
if (_return_type->is_tbd()) {
|
||||
return true;
|
||||
}
|
||||
return _parameters->is_tbd();
|
||||
return _parameters == NULL || _parameters->is_tbd();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -294,6 +326,10 @@ get_num_default_parameters() const {
|
|||
// The trick is just to count, beginning from the end and working towards
|
||||
// the front, the number of parameters that have some initializer.
|
||||
|
||||
if (_parameters == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const CPPParameterList::Parameters ¶ms = _parameters->_parameters;
|
||||
CPPParameterList::Parameters::const_reverse_iterator pi;
|
||||
int count = 0;
|
||||
|
|
@ -362,7 +398,11 @@ is_equal(const CPPDeclaration *other) const {
|
|||
if (_flags != ot->_flags) {
|
||||
return false;
|
||||
}
|
||||
if (*_parameters != *ot->_parameters) {
|
||||
if (_parameters == ot->_parameters) {
|
||||
return true;
|
||||
}
|
||||
if (_parameters == NULL || ot->_parameters == NULL ||
|
||||
*_parameters != *ot->_parameters) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -384,6 +424,11 @@ is_less(const CPPDeclaration *other) const {
|
|||
if (_flags != ot->_flags) {
|
||||
return _flags < ot->_flags;
|
||||
}
|
||||
|
||||
if (_parameters == ot->_parameters) {
|
||||
return 0;
|
||||
}
|
||||
if (_parameters == NULL || ot->_parameters == NULL) {
|
||||
return _parameters < ot->_parameters;
|
||||
}
|
||||
return *_parameters < *ot->_parameters;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ public:
|
|||
CPPFunctionType(const CPPFunctionType ©);
|
||||
void operator = (const CPPFunctionType ©);
|
||||
|
||||
bool accepts_num_parameters(int num_parameters);
|
||||
|
||||
CPPType *_return_type;
|
||||
CPPParameterList *_parameters;
|
||||
int _flags;
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ CPPPreprocessor() {
|
|||
_state = S_eof;
|
||||
_paren_nesting = 0;
|
||||
_parsing_template_params = false;
|
||||
_parsing_attribute = false;
|
||||
_unget = '\0';
|
||||
_last_c = '\0';
|
||||
_start_of_line = true;
|
||||
|
|
@ -986,6 +987,13 @@ internal_get_next_token() {
|
|||
return CPPToken(0, loc);
|
||||
}
|
||||
}
|
||||
} else if (_parsing_attribute) {
|
||||
// If we're parsing an attribute, also keep track of the paren nesting.
|
||||
if (c == '[' || c == '(') {
|
||||
++_paren_nesting;
|
||||
} else if (c == ']' || c == ')') {
|
||||
--_paren_nesting;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for an end-of-line comment, and parse it before we finish this
|
||||
|
|
@ -1090,6 +1098,20 @@ check_digraph(int c) {
|
|||
if (next_c == '=') return MODEQUAL;
|
||||
if (next_c == '>') return '}';
|
||||
break;
|
||||
|
||||
case '[':
|
||||
if (next_c == '[' && !_parsing_attribute) {
|
||||
_parsing_attribute = true;
|
||||
return ATTR_LEFT;
|
||||
}
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (next_c == ']' && _parsing_attribute && _paren_nesting == 0) {
|
||||
_parsing_attribute = false;
|
||||
return ATTR_RIGHT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -1870,11 +1892,19 @@ get_identifier(int c) {
|
|||
loc.last_column = get_col_number();
|
||||
|
||||
if ((c == '\'' || c == '"') &&
|
||||
(name == "L" || name == "u8" ||
|
||||
name == "u" || name == "U")) {
|
||||
(name == "L" || name == "u8" || name == "u" || name == "U" ||
|
||||
name == "R" || name == "LR" || name == "u8R" || name == "uR" || name == "UR")) {
|
||||
// This is actually a wide-character or wide-string literal or some such.
|
||||
// Figure out the correct character type to use.
|
||||
get();
|
||||
string str;
|
||||
if (name[name.size() - 1] == 'R') {
|
||||
name.resize(name.size() - 1);
|
||||
str = scan_raw(c);
|
||||
} else {
|
||||
str = scan_quoted(c);
|
||||
}
|
||||
|
||||
// Figure out the correct character type to use.
|
||||
CPPExpression::Type type;
|
||||
if (name == "L") {
|
||||
type = CPPExpression::T_wstring;
|
||||
|
|
@ -1887,8 +1917,6 @@ get_identifier(int c) {
|
|||
} else {
|
||||
type = CPPExpression::T_string;
|
||||
}
|
||||
get();
|
||||
string str = scan_quoted(c);
|
||||
|
||||
loc.last_line = get_line_number();
|
||||
loc.last_column = get_col_number();
|
||||
|
|
@ -2772,6 +2800,43 @@ scan_quoted(int c) {
|
|||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a C++11 raw string.
|
||||
*/
|
||||
string CPPPreprocessor::
|
||||
scan_raw(int c) {
|
||||
int quote_mark = c;
|
||||
|
||||
string delimiter = ")";
|
||||
|
||||
string str;
|
||||
c = get();
|
||||
while (c != EOF && c != '(') {
|
||||
delimiter += c;
|
||||
c = get();
|
||||
}
|
||||
|
||||
// OK, now start parsing the string, until we see the delimiter again.
|
||||
c = get();
|
||||
while (c != EOF) {
|
||||
if (c == quote_mark) {
|
||||
// We encountered a quote mark - did the last part of the string end
|
||||
// with the given delimiter? If so, we've reached the end.
|
||||
if (str.compare(str.size() - delimiter.size(), delimiter.size(), delimiter) == 0) {
|
||||
str.resize(str.size() - delimiter.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
str += c;
|
||||
c = get();
|
||||
}
|
||||
|
||||
if (c != quote_mark) {
|
||||
warning("Unclosed string");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the manifest is one that is being ignored right now
|
||||
* (presumably because we are presently expanding it).
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ private:
|
|||
static int check_keyword(const string &name);
|
||||
int scan_escape_sequence(int c);
|
||||
string scan_quoted(int c);
|
||||
string scan_raw(int c);
|
||||
|
||||
bool should_ignore_manifest(const CPPManifest *manifest) const;
|
||||
bool should_ignore_preprocessor() const;
|
||||
|
|
@ -212,6 +213,7 @@ private:
|
|||
State _state;
|
||||
int _paren_nesting;
|
||||
bool _parsing_template_params;
|
||||
bool _parsing_attribute;
|
||||
|
||||
bool _start_of_line;
|
||||
int _unget;
|
||||
|
|
|
|||
|
|
@ -252,6 +252,14 @@ output(ostream &out) const {
|
|||
out << "RSHIFTEQUAL";
|
||||
break;
|
||||
|
||||
case ATTR_LEFT:
|
||||
out << "ATTR_LEFT";
|
||||
break;
|
||||
|
||||
case ATTR_RIGHT:
|
||||
out << "ATTR_RIGHT";
|
||||
break;
|
||||
|
||||
case KW_BOOL:
|
||||
out << "KW_BOOL";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "cppFunctionType.cxx"
|
||||
#include "cppGlobals.cxx"
|
||||
#include "cppCommentBlock.cxx"
|
||||
#include "cppClosureType.cxx"
|
||||
#include "cppConstType.cxx"
|
||||
#include "cppDeclaration.cxx"
|
||||
#include "cppMakeProperty.cxx"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||
assert(size <= _buffer_size);
|
||||
|
||||
// Determine how much space to allocate.
|
||||
const size_t alloc_size = _buffer_size + flag_reserved_bytes + MemoryHook::get_memory_alignment() - 1;
|
||||
const size_t alloc_size = _buffer_size + flag_reserved_bytes + MEMORY_HOOK_ALIGNMENT - 1;
|
||||
|
||||
ObjectNode *obj;
|
||||
|
||||
|
|
@ -71,8 +71,8 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||
|
||||
// Allocate memory, and make sure the object starts at the proper alignment.
|
||||
void *mem = NeverFreeMemory::alloc(alloc_size);
|
||||
intptr_t pad = (-(intptr_t)flag_reserved_bytes - (intptr_t)mem) % MemoryHook::get_memory_alignment();
|
||||
obj = (ObjectNode *)((uintptr_t)mem + pad);
|
||||
uintptr_t aligned = ((uintptr_t)mem + flag_reserved_bytes + MEMORY_HOOK_ALIGNMENT - 1) & ~(MEMORY_HOOK_ALIGNMENT - 1);
|
||||
obj = (ObjectNode *)(aligned - flag_reserved_bytes);
|
||||
|
||||
#ifdef USE_DELETEDCHAINFLAG
|
||||
obj->_flag = DCF_alive;
|
||||
|
|
@ -81,7 +81,7 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||
void *ptr = node_to_buffer(obj);
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(((uintptr_t)ptr % MemoryHook::get_memory_alignment()) == 0);
|
||||
assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
|
||||
#endif
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
|
|
|||
|
|
@ -1,25 +1,22 @@
|
|||
// Filename: deletedChain.T
|
||||
// Created by: drose (01Apr06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file deletedChain.T
|
||||
* @author drose
|
||||
* @date 2006-04-01
|
||||
*/
|
||||
|
||||
template<class Type>
|
||||
DeletedChain<Type> StaticDeletedChain<Type>::_chain;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::allocate
|
||||
// Access: Public
|
||||
// Description: Allocates the memory for a new object of Type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Allocates the memory for a new object of Type.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE Type *DeletedChain<Type>::
|
||||
allocate(size_t size, TypeHandle type_handle) {
|
||||
|
|
@ -31,14 +28,12 @@ allocate(size_t size, TypeHandle type_handle) {
|
|||
memory_hook->mark_pointer(ptr, _chain->get_buffer_size(), make_ref_ptr(ptr));
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
return (Type *)ptr;
|
||||
return (Type *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::deallocate
|
||||
// Access: Public
|
||||
// Description: Frees the memory for an object of Type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Frees the memory for an object of Type.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE void DeletedChain<Type>::
|
||||
deallocate(Type *ptr, TypeHandle type_handle) {
|
||||
|
|
@ -57,16 +52,13 @@ deallocate(Type *ptr, TypeHandle type_handle) {
|
|||
_chain->deallocate(ptr, type_handle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::validate
|
||||
// Access: Public
|
||||
// Description: Returns true if the pointer is valid, false if it has
|
||||
// been deleted or if it was never a valid pointer.
|
||||
//
|
||||
// This is only meaningful in debug mode, where
|
||||
// USE_DELETEDCHAINFLAG is defined. If not, this
|
||||
// trivially returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns true if the pointer is valid, false if it has been deleted or if it
|
||||
* was never a valid pointer.
|
||||
*
|
||||
* This is only meaningful in debug mode, where USE_DELETEDCHAINFLAG is
|
||||
* defined. If not, this trivially returns true.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE bool DeletedChain<Type>::
|
||||
validate(const Type *ptr) {
|
||||
|
|
@ -80,48 +72,37 @@ validate(const Type *ptr) {
|
|||
#endif // USE_DELETEDCHAINFLAG
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::make_ref_ptr
|
||||
// Access: Public, Static
|
||||
// Description: This method has two overloads: one that accepts a
|
||||
// void *, and one that accepts a ReferenceCount *. We
|
||||
// rely on the C++ compiler to select the most
|
||||
// appropriate one for a given type to return the
|
||||
// ReferenceCount pointer that corresponds to a
|
||||
// particular type, or NULL if the type does not inherit
|
||||
// from ReferenceCount.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* This method has two overloads: one that accepts a void *, and one that
|
||||
* accepts a ReferenceCount *. We rely on the C++ compiler to select the most
|
||||
* appropriate one for a given type to return the ReferenceCount pointer that
|
||||
* corresponds to a particular type, or NULL if the type does not inherit from
|
||||
* ReferenceCount.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE ReferenceCount *DeletedChain<Type>::
|
||||
make_ref_ptr(void *) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::make_ref_ptr
|
||||
// Access: Public, Static
|
||||
// Description: This method has two overloads: one that accepts a
|
||||
// void *, and one that accepts a ReferenceCount *. We
|
||||
// rely on the C++ compiler to select the most
|
||||
// appropriate one for a given type to return the
|
||||
// ReferenceCount pointer that corresponds to a
|
||||
// particular type, or NULL if the type does not inherit
|
||||
// from ReferenceCount.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* This method has two overloads: one that accepts a void *, and one that
|
||||
* accepts a ReferenceCount *. We rely on the C++ compiler to select the most
|
||||
* appropriate one for a given type to return the ReferenceCount pointer that
|
||||
* corresponds to a particular type, or NULL if the type does not inherit from
|
||||
* ReferenceCount.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE ReferenceCount *DeletedChain<Type>::
|
||||
make_ref_ptr(ReferenceCount *ptr) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DeletedChain::init_deleted_chain
|
||||
// Access: Private
|
||||
// Description: Assigns the _chain pointer if it is not already
|
||||
// assigned. This can't be done by a constructor, since
|
||||
// often the DeletedChain instance is used before its
|
||||
// static construct has had a chance to be called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Assigns the _chain pointer if it is not already assigned. This can't be
|
||||
* done by a constructor, since often the DeletedChain instance is used before
|
||||
* its static construct has had a chance to be called.
|
||||
*/
|
||||
template<class Type>
|
||||
void DeletedChain<Type>::
|
||||
init_deleted_chain() {
|
||||
|
|
@ -131,38 +112,32 @@ init_deleted_chain() {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StaticDeletedChain::allocate
|
||||
// Access: Public, Static
|
||||
// Description: Allocates the memory for a new object of Type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Allocates the memory for a new object of Type.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE Type *StaticDeletedChain<Type>::
|
||||
allocate(size_t size, TypeHandle type_handle) {
|
||||
return _chain.allocate(size, type_handle);
|
||||
Type *ptr = _chain.allocate(size, type_handle);
|
||||
return (Type *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StaticDeletedChain::deallocate
|
||||
// Access: Public
|
||||
// Description: Frees the memory for an object of Type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Frees the memory for an object of Type.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE void StaticDeletedChain<Type>::
|
||||
deallocate(Type *ptr, TypeHandle type_handle) {
|
||||
_chain.deallocate(ptr, type_handle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StaticDeletedChain::validate
|
||||
// Access: Public
|
||||
// Description: Returns true if the pointer is valid, false if it has
|
||||
// been deleted or if it was never a valid pointer.
|
||||
//
|
||||
// This is only meaningful in debug mode, where
|
||||
// USE_DELETEDCHAINFLAG is defined. If not, this
|
||||
// trivially returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Returns true if the pointer is valid, false if it has been deleted or if it
|
||||
* was never a valid pointer.
|
||||
*
|
||||
* This is only meaningful in debug mode, where USE_DELETEDCHAINFLAG is
|
||||
* defined. If not, this trivially returns true.
|
||||
*/
|
||||
template<class Type>
|
||||
INLINE bool StaticDeletedChain<Type>::
|
||||
validate(const Type *ptr) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public:
|
|||
// Place this macro within a class definition to define appropriate operator
|
||||
// new and delete methods that take advantage of DeletedChain.
|
||||
#define ALLOC_DELETED_CHAIN(Type) \
|
||||
inline void *operator new(size_t size) { \
|
||||
inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
|
||||
return (void *)StaticDeletedChain< Type >::allocate(size, get_type_handle(Type)); \
|
||||
} \
|
||||
inline void *operator new(size_t size, void *ptr) { \
|
||||
|
|
@ -96,7 +96,7 @@ public:
|
|||
// Use this variant of the above macro in cases in which the compiler fails to
|
||||
// unify the static template pointers properly, to prevent leaks.
|
||||
#define ALLOC_DELETED_CHAIN_DECL(Type) \
|
||||
inline void *operator new(size_t size) { \
|
||||
inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
|
||||
return (void *)_deleted_chain.allocate(size, get_type_handle(Type)); \
|
||||
} \
|
||||
inline void *operator new(size_t size, void *ptr) { \
|
||||
|
|
|
|||
|
|
@ -76,6 +76,10 @@
|
|||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
// Use NODEFAULT to optimize a switch() stmt to tell MSVC to automatically go
|
||||
// to the final untested case after it has failed all the other cases (i.e.
|
||||
// 'assume at least one of the cases is always true')
|
||||
|
|
@ -89,6 +93,18 @@
|
|||
#define NODEFAULT
|
||||
#endif
|
||||
|
||||
// Use this to hint the compiler that a memory address is aligned.
|
||||
#if __has_builtin(__builtin_assume_aligned) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
|
||||
#define ASSUME_ALIGNED(x, y) (__builtin_assume_aligned(x, y))
|
||||
#else
|
||||
#define ASSUME_ALIGNED(x, y) (x)
|
||||
#endif
|
||||
|
||||
#if __has_attribute(assume_aligned) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
|
||||
#define RETURNS_ALIGNED(x) __attribute__((assume_aligned(x)))
|
||||
#else
|
||||
#define RETURNS_ALIGNED(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
include win32 defns for everything up to WinServer2003, and assume
|
||||
|
|
@ -394,6 +410,35 @@ typedef struct _object PyObject;
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef LINMATH_ALIGN
|
||||
/* We require 16-byte alignment of certain structures, to support SSE2. We
|
||||
don't strictly have to align everything, but it's just easier to do so. */
|
||||
#if defined(HAVE_EIGEN) && defined(__AVX__) && defined(STDFLOAT_DOUBLE)
|
||||
/* Eigen uses AVX instructions, but let's only enable this when compiling with
|
||||
double precision, so that we can keep our ABI a bit more stable. */
|
||||
#define MEMORY_HOOK_ALIGNMENT 32
|
||||
#else
|
||||
#define MEMORY_HOOK_ALIGNMENT 16
|
||||
#endif
|
||||
/* Otherwise, align to two words. This seems to be pretty standard to the
|
||||
point where some code may rely on this being the case. */
|
||||
#elif defined(IS_OSX) || NATIVE_WORDSIZE >= 64
|
||||
#define MEMORY_HOOK_ALIGNMENT 16
|
||||
#else
|
||||
#define MEMORY_HOOK_ALIGNMENT 8
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EIGEN
|
||||
/* Make sure that Eigen doesn't assume alignment guarantees we don't offer. */
|
||||
#define EIGEN_MAX_ALIGN_BYTES MEMORY_HOOK_ALIGNMENT
|
||||
#ifndef EIGEN_MPL2_ONLY
|
||||
#define EIGEN_MPL2_ONLY 1
|
||||
#endif
|
||||
#if !defined(_DEBUG) && !defined(EIGEN_NO_DEBUG)
|
||||
#define EIGEN_NO_DEBUG 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Determine our memory-allocation requirements. */
|
||||
#if defined(USE_MEMORY_PTMALLOC2) || defined(USE_MEMORY_DLMALLOC) || defined(DO_MEMORY_USAGE) || defined(MEMORY_HOOK_DO_ALIGN)
|
||||
/* In this case we have some custom memory management requirements. */
|
||||
|
|
|
|||
|
|
@ -290,10 +290,10 @@ EXPCL_DTOOL void init_memory_hook();
|
|||
|
||||
// Now redefine some handy macros to hook into the above MemoryHook object.
|
||||
#ifndef USE_MEMORY_NOWRAPPERS
|
||||
#define PANDA_MALLOC_SINGLE(size) (memory_hook->heap_alloc_single(size))
|
||||
#define PANDA_MALLOC_SINGLE(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_single(size), MEMORY_HOOK_ALIGNMENT))
|
||||
#define PANDA_FREE_SINGLE(ptr) memory_hook->heap_free_single(ptr)
|
||||
#define PANDA_MALLOC_ARRAY(size) (memory_hook->heap_alloc_array(size))
|
||||
#define PANDA_REALLOC_ARRAY(ptr, size) (memory_hook->heap_realloc_array(ptr, size))
|
||||
#define PANDA_MALLOC_ARRAY(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_array(size), MEMORY_HOOK_ALIGNMENT))
|
||||
#define PANDA_REALLOC_ARRAY(ptr, size) (ASSUME_ALIGNED(memory_hook->heap_realloc_array(ptr, size), MEMORY_HOOK_ALIGNMENT))
|
||||
#define PANDA_FREE_ARRAY(ptr) memory_hook->heap_free_array(ptr)
|
||||
#else
|
||||
#define PANDA_MALLOC_SINGLE(size) ::malloc(size)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#ifndef USE_MEMORY_NOWRAPPERS
|
||||
|
||||
#define ALLOC_MEMORY_BASE \
|
||||
inline void *operator new(size_t size) { \
|
||||
inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
|
||||
return PANDA_MALLOC_SINGLE(size); \
|
||||
} \
|
||||
inline void *operator new(size_t size, void *ptr) { \
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
} \
|
||||
inline void operator delete(void *, void *) { \
|
||||
} \
|
||||
inline void *operator new[](size_t size) { \
|
||||
inline void *operator new[](size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
|
||||
return PANDA_MALLOC_ARRAY(size); \
|
||||
} \
|
||||
inline void *operator new[](size_t size, void *ptr) { \
|
||||
|
|
|
|||
|
|
@ -38,57 +38,9 @@ dec_heap(size_t size) {
|
|||
* Returns the global memory alignment. This is the number of bytes at which
|
||||
* each allocated memory pointer will be aligned.
|
||||
*/
|
||||
INLINE size_t MemoryHook::
|
||||
CONSTEXPR size_t MemoryHook::
|
||||
get_memory_alignment() {
|
||||
#ifdef LINMATH_ALIGN
|
||||
// We require 16-byte alignment of certain structures, to support SSE2. We
|
||||
// don't strictly have to align *everything*, but it's just easier to do so.
|
||||
#ifdef __AVX__
|
||||
// Eigen requires 32-byte alignment when using AVX instructions.
|
||||
const size_t alignment_size = 32;
|
||||
#else
|
||||
const size_t alignment_size = 16;
|
||||
#endif
|
||||
#else
|
||||
// Otherwise, align to two words. This seems to be pretty standard to the
|
||||
// point where some code may rely on this being the case.
|
||||
const size_t alignment_size = sizeof(void *) * 2;
|
||||
#endif
|
||||
return alignment_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of additional bytes that are reserved at the beginning
|
||||
* of every allocated block to store a size_t.
|
||||
*/
|
||||
INLINE size_t MemoryHook::
|
||||
get_header_reserved_bytes() {
|
||||
// We need to figure out the minimum amount of additional space we need in
|
||||
// order to place a single word at the start of each allocated block, to
|
||||
// store the size of the block.
|
||||
|
||||
#ifdef LINMATH_ALIGN
|
||||
// If we're doing SSE2 alignment, we must reserve a full 16-byte block,
|
||||
// since anything less than that will spoil the alignment.
|
||||
#ifdef __AVX__
|
||||
// Eigen requires 32-byte alignment when using AVX instructions.
|
||||
static const size_t header_reserved_bytes = 32;
|
||||
#else
|
||||
static const size_t header_reserved_bytes = 16;
|
||||
#endif
|
||||
|
||||
#elif defined(MEMORY_HOOK_DO_ALIGN)
|
||||
// If we're just aligning to words, we reserve a block as big as two words,
|
||||
// to allow us wiggle room to align the word precisely within that block.
|
||||
static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
|
||||
|
||||
#else
|
||||
// Virtually all allocators align to two words, so we make sure we preserve
|
||||
// that alignment for the benefit of anyone who relies upon that.
|
||||
static const size_t header_reserved_bytes = sizeof(void *) * 2;
|
||||
#endif
|
||||
|
||||
return header_reserved_bytes;
|
||||
return MEMORY_HOOK_ALIGNMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,67 +62,29 @@ round_up_to_page_size(size_t size) const {
|
|||
}
|
||||
|
||||
/**
|
||||
* Increments the amount of requested size as necessary to accommodate the
|
||||
* extra data we might piggyback on each allocated block.
|
||||
* Given a pointer that was returned by a MemoryHook allocation, returns the
|
||||
* number of bytes that were allocated for it. This may be slightly larger
|
||||
* than the number of bytes requested.
|
||||
* The behavior of this function is undefined if the given pointer was not
|
||||
* returned by the MemoryHook allocator or was already freed.
|
||||
* May return 0 if not compiling with DO_MEMORY_USAGE.
|
||||
*
|
||||
* This is only defined publicly so TypeHandle can get at it; it really
|
||||
* shouldn't be used outside of dtoolbase.
|
||||
*/
|
||||
INLINE size_t MemoryHook::
|
||||
inflate_size(size_t size) {
|
||||
get_ptr_size(void *ptr) {
|
||||
#if defined(MEMORY_HOOK_DO_ALIGN)
|
||||
// If we're aligning, we need to request the header size, plus extra bytes
|
||||
// to give us wiggle room to adjust the pointer.
|
||||
return size + get_header_reserved_bytes() + get_memory_alignment() - 1;
|
||||
uintptr_t *root = (uintptr_t *)ptr;
|
||||
return (size_t)root[-2];
|
||||
#elif defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
// If we are using dlmalloc, we know how it stores the size.
|
||||
size_t *root = (size_t *)ptr;
|
||||
return (root[-1] & ~0x7) - sizeof(size_t);
|
||||
#elif defined(DO_MEMORY_USAGE)
|
||||
// If we're not aligning, but we're tracking memory allocations, we just
|
||||
// need the header size extra (this gives us a place to store the size of
|
||||
// the allocated block).
|
||||
return size + get_header_reserved_bytes();
|
||||
size_t *root = (size_t *)((char *)ptr - MEMORY_HOOK_ALIGNMENT);
|
||||
return *root;
|
||||
#else
|
||||
// If we're not doing any of that, we can just allocate the precise
|
||||
// requested amount.
|
||||
return size;
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an allocated pointer to a pointer returnable to the application.
|
||||
* Stuffs size in the first n bytes of the allocated space.
|
||||
*/
|
||||
INLINE void *MemoryHook::
|
||||
alloc_to_ptr(void *alloc, size_t size) {
|
||||
#if defined(MEMORY_HOOK_DO_ALIGN)
|
||||
size_t alignment = get_memory_alignment();
|
||||
// Move the allocated pointer up to the next even alignment.
|
||||
size_t *root = (size_t *)((((size_t)alloc + alignment - 1) / alignment) * alignment);
|
||||
assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment);
|
||||
root[0] = size;
|
||||
root[1] = (size_t)alloc; // Save the pointer we originally allocated.
|
||||
return (void *)((char *)root + get_header_reserved_bytes());
|
||||
#elif defined(DO_MEMORY_USAGE)
|
||||
size_t *root = (size_t *)alloc;
|
||||
root[0] = size;
|
||||
return (void *)((char *)root + get_header_reserved_bytes());
|
||||
#else
|
||||
return alloc;
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an application pointer back to the original allocated pointer.
|
||||
* Extracts size from the first n bytes of the allocated space.
|
||||
*/
|
||||
INLINE void *MemoryHook::
|
||||
ptr_to_alloc(void *ptr, size_t &size) {
|
||||
#if defined(MEMORY_HOOK_DO_ALIGN)
|
||||
size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
|
||||
size = root[0];
|
||||
void *alloc = (void *)root[1]; // Get the pointer we originally allocated.
|
||||
assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment());
|
||||
return alloc;
|
||||
#elif defined(DO_MEMORY_USAGE)
|
||||
size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
|
||||
size = root[0];
|
||||
return (void *)root;
|
||||
#else
|
||||
return ptr;
|
||||
return 0;
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "memoryHook.h"
|
||||
#include "deletedBufferChain.h"
|
||||
#include <stdlib.h>
|
||||
#include "typeRegistry.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
|
|
@ -36,6 +37,15 @@
|
|||
|
||||
#endif // WIN32
|
||||
|
||||
// Ensure we made the right decisions about the alignment size.
|
||||
static_assert(MEMORY_HOOK_ALIGNMENT >= sizeof(size_t),
|
||||
"MEMORY_HOOK_ALIGNMENT should at least be sizeof(size_t)");
|
||||
static_assert(MEMORY_HOOK_ALIGNMENT >= sizeof(void *),
|
||||
"MEMORY_HOOK_ALIGNMENT should at least be sizeof(void *)");
|
||||
static_assert(MEMORY_HOOK_ALIGNMENT * 8 >= NATIVE_WORDSIZE,
|
||||
"MEMORY_HOOK_ALIGNMENT * 8 should at least be NATIVE_WORDSIZE");
|
||||
static_assert((MEMORY_HOOK_ALIGNMENT & (MEMORY_HOOK_ALIGNMENT - 1)) == 0,
|
||||
"MEMORY_HOOK_ALIGNMENT should be a power of two");
|
||||
|
||||
#if defined(USE_MEMORY_DLMALLOC)
|
||||
|
||||
|
|
@ -49,17 +59,8 @@
|
|||
#ifdef _DEBUG
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
#ifdef LINMATH_ALIGN
|
||||
// drose: We require 16-byte alignment of certain structures, to
|
||||
// support SSE2. We don't strictly have to align *everything*, but
|
||||
// it's just easier to do so.
|
||||
#ifdef __AVX__
|
||||
// Eigen requires 32-byte alignment when using AVX instructions.
|
||||
#define MALLOC_ALIGNMENT ((size_t)32U)
|
||||
#else
|
||||
#define MALLOC_ALIGNMENT ((size_t)16U)
|
||||
#endif
|
||||
#endif
|
||||
// dlmalloc can do the alignment we ask for.
|
||||
#define MALLOC_ALIGNMENT MEMORY_HOOK_ALIGNMENT
|
||||
|
||||
#include "dlmalloc_src.cxx"
|
||||
|
||||
|
|
@ -104,6 +105,83 @@
|
|||
|
||||
#endif // USE_MEMORY_*
|
||||
|
||||
/**
|
||||
* Increments the amount of requested size as necessary to accommodate the
|
||||
* extra data we might piggyback on each allocated block.
|
||||
*/
|
||||
INLINE static size_t
|
||||
inflate_size(size_t size) {
|
||||
#if defined(MEMORY_HOOK_DO_ALIGN)
|
||||
// If we're aligning, we need to request the header size, plus extra bytes
|
||||
// to give us wiggle room to adjust the pointer.
|
||||
return size + sizeof(uintptr_t) * 2 + MEMORY_HOOK_ALIGNMENT - 1;
|
||||
#elif defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
// If we are can access the allocator's bookkeeping to figure out how many
|
||||
// bytes were allocated, we don't need to add our own information.
|
||||
return size;
|
||||
#elif defined(DO_MEMORY_USAGE)
|
||||
// If we're not aligning, but we're tracking memory allocations, we just
|
||||
// need the header size extra (this gives us a place to store the size of
|
||||
// the allocated block). However, we do need to make sure that any
|
||||
// alignment guarantee is kept.
|
||||
return size + MEMORY_HOOK_ALIGNMENT;
|
||||
#else
|
||||
// If we're not doing any of that, we can just allocate the precise
|
||||
// requested amount.
|
||||
return size;
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an allocated pointer to a pointer returnable to the application.
|
||||
* Stuffs size in the first n bytes of the allocated space.
|
||||
*/
|
||||
INLINE static void *
|
||||
alloc_to_ptr(void *alloc, size_t size) {
|
||||
#if defined(MEMORY_HOOK_DO_ALIGN)
|
||||
// Add room for two uintptr_t values.
|
||||
uintptr_t *root = (uintptr_t *)((char *)alloc + sizeof(uintptr_t) * 2);
|
||||
// Align this to the requested boundary.
|
||||
root = (uintptr_t *)(((uintptr_t)root + MEMORY_HOOK_ALIGNMENT - 1) & ~(MEMORY_HOOK_ALIGNMENT - 1));
|
||||
root[-2] = size;
|
||||
root[-1] = (uintptr_t)alloc; // Save the pointer we originally allocated.
|
||||
return (void *)root;
|
||||
#elif defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
return alloc;
|
||||
#elif defined(DO_MEMORY_USAGE)
|
||||
size_t *root = (size_t *)alloc;
|
||||
root[0] = size;
|
||||
return (void *)((char *)root + MEMORY_HOOK_ALIGNMENT);
|
||||
#else
|
||||
return alloc;
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an application pointer back to the original allocated pointer.
|
||||
* Extracts size from the first n bytes of the allocated space, but only if
|
||||
* DO_MEMORY_USAGE is defined.
|
||||
*/
|
||||
INLINE static void *
|
||||
ptr_to_alloc(void *ptr, size_t &size) {
|
||||
#if defined(MEMORY_HOOK_DO_ALIGN)
|
||||
uintptr_t *root = (uintptr_t *)ptr;
|
||||
size = root[-2];
|
||||
return (void *)root[-1]; // Get the pointer we originally allocated.
|
||||
#elif defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
size = MemoryHook::get_ptr_size(ptr);
|
||||
#endif
|
||||
return ptr;
|
||||
#elif defined(DO_MEMORY_USAGE)
|
||||
size_t *root = (size_t *)((char *)ptr - MEMORY_HOOK_ALIGNMENT);
|
||||
size = root[0];
|
||||
return (void *)root;
|
||||
#else
|
||||
return ptr;
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -195,6 +273,11 @@ heap_alloc_single(size_t size) {
|
|||
#ifdef DO_MEMORY_USAGE
|
||||
// In the DO_MEMORY_USAGE case, we want to track the total size of allocated
|
||||
// bytes on the heap.
|
||||
#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
// dlmalloc may slightly overallocate, however.
|
||||
size = get_ptr_size(alloc);
|
||||
inflated_size = size;
|
||||
#endif
|
||||
AtomicAdjust::add(_total_heap_single_size, (AtomicAdjust::Integer)size);
|
||||
if ((size_t)AtomicAdjust::get(_total_heap_single_size) +
|
||||
(size_t)AtomicAdjust::get(_total_heap_array_size) >
|
||||
|
|
@ -204,7 +287,10 @@ heap_alloc_single(size_t size) {
|
|||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
void *ptr = alloc_to_ptr(alloc, size);
|
||||
#ifdef _DEBUG
|
||||
assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
|
||||
assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -264,6 +350,11 @@ heap_alloc_array(size_t size) {
|
|||
#ifdef DO_MEMORY_USAGE
|
||||
// In the DO_MEMORY_USAGE case, we want to track the total size of allocated
|
||||
// bytes on the heap.
|
||||
#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
// dlmalloc may slightly overallocate, however.
|
||||
size = get_ptr_size(alloc);
|
||||
inflated_size = size;
|
||||
#endif
|
||||
AtomicAdjust::add(_total_heap_array_size, (AtomicAdjust::Integer)size);
|
||||
if ((size_t)AtomicAdjust::get(_total_heap_single_size) +
|
||||
(size_t)AtomicAdjust::get(_total_heap_array_size) >
|
||||
|
|
@ -273,7 +364,10 @@ heap_alloc_array(size_t size) {
|
|||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
void *ptr = alloc_to_ptr(alloc, size);
|
||||
#ifdef _DEBUG
|
||||
assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
|
||||
assert(ptr >= alloc && (char *)ptr + size <= (char *)alloc + inflated_size);
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -285,11 +379,6 @@ heap_realloc_array(void *ptr, size_t size) {
|
|||
size_t orig_size;
|
||||
void *alloc = ptr_to_alloc(ptr, orig_size);
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
assert((AtomicAdjust::Integer)orig_size <= _total_heap_array_size);
|
||||
AtomicAdjust::add(_total_heap_array_size, (AtomicAdjust::Integer)size-(AtomicAdjust::Integer)orig_size);
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
size_t inflated_size = inflate_size(size);
|
||||
|
||||
void *alloc1 = alloc;
|
||||
|
|
@ -316,17 +405,40 @@ heap_realloc_array(void *ptr, size_t size) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void *ptr1 = alloc_to_ptr(alloc1, size);
|
||||
assert(ptr1 >= alloc1 && (char *)ptr1 + size <= (char *)alloc1 + inflated_size);
|
||||
#if defined(MEMORY_HOOK_DO_ALIGN)
|
||||
// We might have to shift the memory to account for the new offset due to
|
||||
// the alignment.
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
// dlmalloc may slightly overallocate, however.
|
||||
size = get_ptr_size(alloc1);
|
||||
inflated_size = size;
|
||||
#endif
|
||||
assert((AtomicAdjust::Integer)orig_size <= _total_heap_array_size);
|
||||
AtomicAdjust::add(_total_heap_array_size, (AtomicAdjust::Integer)size-(AtomicAdjust::Integer)orig_size);
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
// Align this to the requested boundary.
|
||||
#ifdef MEMORY_HOOK_DO_ALIGN
|
||||
// This copies the code from alloc_to_ptr, since we can't write the size and
|
||||
// pointer until after we have done the memmove.
|
||||
uintptr_t *root = (uintptr_t *)((char *)alloc1 + sizeof(uintptr_t) * 2);
|
||||
root = (uintptr_t *)(((uintptr_t)root + MEMORY_HOOK_ALIGNMENT - 1) & ~(MEMORY_HOOK_ALIGNMENT - 1));
|
||||
void *ptr1 = (void *)root;
|
||||
|
||||
size_t orig_delta = (char *)ptr - (char *)alloc;
|
||||
size_t new_delta = (char *)ptr1 - (char *)alloc1;
|
||||
if (orig_delta != new_delta) {
|
||||
memmove((char *)alloc1 + new_delta, (char *)alloc1 + orig_delta, min(size, orig_size));
|
||||
}
|
||||
#endif // MEMORY_HOOK_DO_ALIGN
|
||||
|
||||
root[-2] = size;
|
||||
root[-1] = (uintptr_t)alloc1; // Save the pointer we originally allocated.
|
||||
#else
|
||||
void *ptr1 = alloc_to_ptr(alloc1, size);
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
assert(ptr1 >= alloc1 && (char *)ptr1 + size <= (char *)alloc1 + inflated_size);
|
||||
assert(((uintptr_t)ptr1 % MEMORY_HOOK_ALIGNMENT) == 0);
|
||||
#endif
|
||||
return ptr1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ public:
|
|||
|
||||
bool heap_trim(size_t pad);
|
||||
|
||||
INLINE static size_t get_memory_alignment();
|
||||
INLINE static size_t get_header_reserved_bytes();
|
||||
CONSTEXPR static size_t get_memory_alignment();
|
||||
|
||||
virtual void *mmap_alloc(size_t size, bool allow_exec);
|
||||
virtual void mmap_free(void *ptr, size_t size);
|
||||
|
|
@ -66,10 +65,7 @@ public:
|
|||
|
||||
virtual void alloc_fail(size_t attempted_size);
|
||||
|
||||
private:
|
||||
INLINE static size_t inflate_size(size_t size);
|
||||
INLINE static void *alloc_to_ptr(void *alloc, size_t size);
|
||||
INLINE static void *ptr_to_alloc(void *ptr, size_t &size);
|
||||
INLINE static size_t get_ptr_size(void *ptr);
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
// Filename: pallocator.T
|
||||
// Created by: drose (05Jun01)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file pallocator.T
|
||||
* @author drose
|
||||
* @date 2001-06-05
|
||||
*/
|
||||
|
||||
template<class Type>
|
||||
INLINE pallocator_single<Type>::
|
||||
|
|
@ -20,12 +19,13 @@ pallocator_single(TypeHandle type_handle) NOEXCEPT :
|
|||
}
|
||||
|
||||
template<class Type>
|
||||
INLINE TYPENAME pallocator_single<Type>::pointer pallocator_single<Type>::
|
||||
INLINE Type *pallocator_single<Type>::
|
||||
allocate(TYPENAME pallocator_single<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
|
||||
TAU_PROFILE("pallocator_single:allocate()", " ", TAU_USER);
|
||||
// This doesn't support allocating arrays.
|
||||
assert(n == 1);
|
||||
return StaticDeletedChain<Type>::allocate(sizeof(Type), _type_handle);
|
||||
return (Type *)ASSUME_ALIGNED(StaticDeletedChain<Type>::allocate(sizeof(Type), _type_handle),
|
||||
MEMORY_HOOK_ALIGNMENT);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
|
|
@ -43,35 +43,14 @@ pallocator_array(TypeHandle type_handle) NOEXCEPT :
|
|||
}
|
||||
|
||||
template<class Type>
|
||||
INLINE TYPENAME pallocator_array<Type>::pointer pallocator_array<Type>::
|
||||
INLINE Type *pallocator_array<Type>::
|
||||
allocate(TYPENAME pallocator_array<Type>::size_type n, TYPENAME allocator<void>::const_pointer) {
|
||||
TAU_PROFILE("pallocator_array:allocate()", " ", TAU_USER);
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
const size_t header_reserved_bytes = MemoryHook::get_header_reserved_bytes();
|
||||
size_t alloc_size = n * sizeof(Type);
|
||||
// We also need to store the total number of bytes we allocated.
|
||||
alloc_size += header_reserved_bytes;
|
||||
_type_handle.inc_memory_usage(TypeHandle::MC_array, alloc_size);
|
||||
void *ptr = (TYPENAME pallocator_array<Type>::pointer)PANDA_MALLOC_ARRAY(alloc_size);
|
||||
*((size_t *)ptr) = alloc_size;
|
||||
return (TYPENAME pallocator_array<Type>::pointer)(((char *)ptr) + header_reserved_bytes);
|
||||
#else
|
||||
return (TYPENAME pallocator_array<Type>::pointer)PANDA_MALLOC_ARRAY(n * sizeof(Type));
|
||||
#endif // DO_MEMORY_USAGE
|
||||
return (TYPENAME pallocator_array<Type>::pointer)
|
||||
ASSUME_ALIGNED(_type_handle.allocate_array(n * sizeof(Type)), MEMORY_HOOK_ALIGNMENT);
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
INLINE void pallocator_array<Type>::
|
||||
deallocate(TYPENAME pallocator_array<Type>::pointer p, TYPENAME pallocator_array<Type>::size_type) {
|
||||
TAU_PROFILE("pallocator_array:deallocate()", " ", TAU_USER);
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
// Now we need to recover the total number of bytes.
|
||||
const size_t header_reserved_bytes = MemoryHook::get_header_reserved_bytes();
|
||||
void *ptr = (void *)((char *)p - header_reserved_bytes);
|
||||
size_t alloc_size = *((size_t *)ptr);
|
||||
_type_handle.dec_memory_usage(TypeHandle::MC_array, alloc_size);
|
||||
PANDA_FREE_ARRAY(ptr);
|
||||
#else
|
||||
PANDA_FREE_ARRAY(p);
|
||||
#endif // DO_MEMORY_USAGE
|
||||
_type_handle.deallocate_array((void *)p);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ public:
|
|||
INLINE pallocator_single(const pallocator_single<U> ©) NOEXCEPT :
|
||||
_type_handle(copy._type_handle) { }
|
||||
|
||||
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
|
||||
INLINE Type *allocate(size_type n, allocator<void>::const_pointer hint = 0)
|
||||
RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
INLINE void deallocate(pointer p, size_type n);
|
||||
|
||||
template<class U> struct rebind {
|
||||
|
|
@ -87,7 +88,8 @@ public:
|
|||
INLINE pallocator_array(const pallocator_array<U> ©) NOEXCEPT :
|
||||
_type_handle(copy._type_handle) { }
|
||||
|
||||
INLINE pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
|
||||
INLINE Type *allocate(size_type n, allocator<void>::const_pointer hint = 0)
|
||||
RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
INLINE void deallocate(pointer p, size_type n);
|
||||
|
||||
template<class U> struct rebind {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
// This is initialized to zero by static initialization.
|
||||
TypeHandle TypeHandle::_none;
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
/**
|
||||
* Returns the total allocated memory used by objects of this type, for the
|
||||
* indicated memory class. This is only updated if track-memory-usage is set
|
||||
|
|
@ -26,6 +25,7 @@ TypeHandle TypeHandle::_none;
|
|||
*/
|
||||
size_t TypeHandle::
|
||||
get_memory_usage(MemoryClass memory_class) const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
assert((int)memory_class >= 0 && (int)memory_class < (int)MC_limit);
|
||||
if ((*this) == TypeHandle::none()) {
|
||||
return 0;
|
||||
|
|
@ -34,16 +34,17 @@ get_memory_usage(MemoryClass memory_class) const {
|
|||
assert(rnode != (TypeRegistryNode *)NULL);
|
||||
return (size_t)AtomicAdjust::get(rnode->_memory_usage[memory_class]);
|
||||
}
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
/**
|
||||
* Adds the indicated amount to the record for the total allocated memory for
|
||||
* objects of this type.
|
||||
*/
|
||||
void TypeHandle::
|
||||
inc_memory_usage(MemoryClass memory_class, size_t size) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
assert((int)memory_class >= 0 && (int)memory_class < (int)MC_limit);
|
||||
if ((*this) != TypeHandle::none()) {
|
||||
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL);
|
||||
|
|
@ -56,16 +57,16 @@ inc_memory_usage(MemoryClass memory_class, size_t size) {
|
|||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
/**
|
||||
* Subtracts the indicated amount from the record for the total allocated
|
||||
* memory for objects of this type.
|
||||
*/
|
||||
void TypeHandle::
|
||||
dec_memory_usage(MemoryClass memory_class, size_t size) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
assert((int)memory_class >= 0 && (int)memory_class < (int)MC_limit);
|
||||
if ((*this) != TypeHandle::none()) {
|
||||
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL);
|
||||
|
|
@ -75,8 +76,81 @@ dec_memory_usage(MemoryClass memory_class, size_t size) {
|
|||
// rnode->_memory_usage[memory_class] << "\n";
|
||||
assert(rnode->_memory_usage[memory_class] >= 0);
|
||||
}
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates memory, adding it to the total amount of memory allocated for
|
||||
* this type.
|
||||
*/
|
||||
void *TypeHandle::
|
||||
allocate_array(size_t size) {
|
||||
TAU_PROFILE("TypeHandle:allocate_array()", " ", TAU_USER);
|
||||
|
||||
void *ptr = PANDA_MALLOC_ARRAY(size);
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if ((*this) != TypeHandle::none()) {
|
||||
size_t alloc_size = MemoryHook::get_ptr_size(ptr);
|
||||
#ifdef _DEBUG
|
||||
assert(size <= alloc_size);
|
||||
#endif
|
||||
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL);
|
||||
assert(rnode != (TypeRegistryNode *)NULL);
|
||||
AtomicAdjust::add(rnode->_memory_usage[MC_array], (AtomicAdjust::Integer)alloc_size);
|
||||
if (rnode->_memory_usage[MC_array] < 0) {
|
||||
cerr << "Memory usage overflow for type " << *this << ".\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reallocates memory, adjusting the total amount of memory allocated for this
|
||||
* type.
|
||||
*/
|
||||
void *TypeHandle::
|
||||
reallocate_array(void *old_ptr, size_t size) {
|
||||
TAU_PROFILE("TypeHandle:reallocate_array()", " ", TAU_USER);
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
size_t old_size = MemoryHook::get_ptr_size(old_ptr);
|
||||
void *new_ptr = PANDA_REALLOC_ARRAY(old_ptr, size);
|
||||
|
||||
if ((*this) != TypeHandle::none()) {
|
||||
size_t new_size = MemoryHook::get_ptr_size(new_ptr);
|
||||
|
||||
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL);
|
||||
assert(rnode != (TypeRegistryNode *)NULL);
|
||||
AtomicAdjust::add(rnode->_memory_usage[MC_array], (AtomicAdjust::Integer)new_size - (AtomicAdjust::Integer)old_size);
|
||||
assert(rnode->_memory_usage[MC_array] >= 0);
|
||||
}
|
||||
#else
|
||||
void *new_ptr = PANDA_REALLOC_ARRAY(old_ptr, size);
|
||||
#endif
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocates memory, subtracting it from the total amount of memory
|
||||
* allocated for this type.
|
||||
*/
|
||||
void TypeHandle::
|
||||
deallocate_array(void *ptr) {
|
||||
TAU_PROFILE("TypeHandle:deallocate_array()", " ", TAU_USER);
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
size_t alloc_size = MemoryHook::get_ptr_size(ptr);
|
||||
if ((*this) != TypeHandle::none()) {
|
||||
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, NULL);
|
||||
assert(rnode != (TypeRegistryNode *)NULL);
|
||||
AtomicAdjust::add(rnode->_memory_usage[MC_array], -(AtomicAdjust::Integer)alloc_size);
|
||||
assert(rnode->_memory_usage[MC_array] >= 0);
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
PANDA_FREE_ARRAY(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Index of the BEst fit Classs from a set
|
||||
|
|
|
|||
|
|
@ -18,25 +18,49 @@
|
|||
|
||||
#include <set>
|
||||
|
||||
// The following illustrates the convention for declaring a type that uses
|
||||
// TypeHandle. In this example, ThisThingie inherits from TypedObject, which
|
||||
// automatically supplies some type-differentiation functions at the cost of
|
||||
// one virtual function, get_type(); however, this inheritance is optional,
|
||||
// and may be omitted to avoid the virtual function pointer overhead. (If you
|
||||
// do use TypedObject, be sure to consider whether your destructor should also
|
||||
// be virtual.)
|
||||
|
||||
/*
|
||||
* class ThatThingie : public SimpleTypedObject { public: static TypeHandle
|
||||
* get_class_type() { return _type_handle; } static void init_type() {
|
||||
* register_type(_type_handle, "ThatThingie"); } private: static TypeHandle
|
||||
* _type_handle; }; class ThisThingie : public ThatThingie, publid TypedObject
|
||||
* { public: static TypeHandle get_class_type() { return _type_handle; }
|
||||
* static void init_type() { ThatThingie::init_type();
|
||||
* TypedObject::init_type(); register_type(_type_handle, "ThisThingie",
|
||||
* ThatThingie::get_class_type(), TypedObject::get_class_type()); } virtual
|
||||
* TypeHandle get_type() const { return get_class_type(); } private: static
|
||||
* TypeHandle _type_handle; };
|
||||
/**
|
||||
* The following illustrates the convention for declaring a type that uses
|
||||
* TypeHandle. In this example, ThisThingie inherits from TypedObject, which
|
||||
* automatically supplies some type-differentiation functions at the cost of
|
||||
* one virtual function, get_type(); however, this inheritance is optional,
|
||||
* and may be omitted to avoid the virtual function pointer overhead. (If you
|
||||
* do use TypedObject, be sure to consider whether your destructor should also
|
||||
* be virtual.)
|
||||
*
|
||||
* @code
|
||||
* class ThatThingie : public SimpleTypedObject {
|
||||
* public:
|
||||
* static TypeHandle get_class_type() {
|
||||
* return _type_handle;
|
||||
* }
|
||||
* static void init_type() {
|
||||
* register_type(_type_handle, "ThatThingie");
|
||||
* }
|
||||
*
|
||||
* private:
|
||||
* static TypeHandle _type_handle;
|
||||
* };
|
||||
*
|
||||
* class ThisThingie : public ThatThingie, publid TypedObject {
|
||||
* public:
|
||||
* static TypeHandle get_class_type() {
|
||||
* return _type_handle;
|
||||
* }
|
||||
* static void init_type() {
|
||||
* ThatThingie::init_type();
|
||||
* TypedObject::init_type();
|
||||
* register_type(_type_handle, "ThisThingie",
|
||||
* ThatThingie::get_class_type(),
|
||||
* TypedObject::get_class_type());
|
||||
* }
|
||||
* virtual TypeHandle get_type() const {
|
||||
* return get_class_type();
|
||||
* }
|
||||
*
|
||||
* private:
|
||||
* static TypeHandle _type_handle;
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
class TypedObject;
|
||||
|
|
@ -97,15 +121,9 @@ PUBLISHED:
|
|||
|
||||
int get_best_parent_from_Set(const std::set< int > &legal_vals) const;
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
size_t get_memory_usage(MemoryClass memory_class) const;
|
||||
void inc_memory_usage(MemoryClass memory_class, size_t size);
|
||||
void dec_memory_usage(MemoryClass memory_class, size_t size);
|
||||
#else
|
||||
static CONSTEXPR size_t get_memory_usage(MemoryClass) { return 0; }
|
||||
INLINE void inc_memory_usage(MemoryClass, size_t) { }
|
||||
INLINE void dec_memory_usage(MemoryClass, size_t) { }
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
INLINE int get_index() const;
|
||||
INLINE void output(ostream &out) const;
|
||||
|
|
@ -118,6 +136,10 @@ PUBLISHED:
|
|||
MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class);
|
||||
|
||||
public:
|
||||
void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
void deallocate_array(void *ptr);
|
||||
|
||||
INLINE static TypeHandle from_index(int index);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -591,8 +591,8 @@ read_args() {
|
|||
dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map);
|
||||
|
||||
while (map != NULL) {
|
||||
char *tail = strrchr(map->l_name, '/');
|
||||
char *head = strchr(map->l_name, '/');
|
||||
const char *tail = strrchr(map->l_name, '/');
|
||||
const char *head = strchr(map->l_name, '/');
|
||||
if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
|
||||
|| strcmp(tail, "/libp3dtool.so") == 0)) {
|
||||
_dtool_name = head;
|
||||
|
|
@ -615,8 +615,8 @@ read_args() {
|
|||
char buffer[PATH_MAX];
|
||||
buffer[0] = 0;
|
||||
maps.getline(buffer, PATH_MAX);
|
||||
char *tail = strrchr(buffer, '/');
|
||||
char *head = strchr(buffer, '/');
|
||||
const char *tail = strrchr(buffer, '/');
|
||||
const char *head = strchr(buffer, '/');
|
||||
if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
|
||||
|| strcmp(tail, "/libp3dtool.so") == 0)) {
|
||||
_dtool_name = head;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ match_files(vector_string &results, const Filename &cwd) const {
|
|||
pattern = source;
|
||||
} else {
|
||||
pattern = source.substr(0, slash);
|
||||
suffix = source.substr(slash + 1);
|
||||
suffix = source.substr(slash);
|
||||
}
|
||||
|
||||
GlobPattern glob(pattern);
|
||||
|
|
@ -118,11 +118,21 @@ r_match_files(const Filename &prefix, const string &suffix,
|
|||
size_t slash = suffix.find('/');
|
||||
if (slash == string::npos) {
|
||||
next_pattern = suffix;
|
||||
} else if (slash + 1 == suffix.size()) {
|
||||
// If the slash is at the end, we need to keep it, since it indicates that
|
||||
// we only want to match directories.
|
||||
next_pattern = suffix.substr(0, slash);
|
||||
next_suffix = "/";
|
||||
} else {
|
||||
next_pattern = suffix.substr(0, slash);
|
||||
next_suffix = suffix.substr(slash + 1);
|
||||
}
|
||||
|
||||
if (_pattern == "**" && next_pattern == "**") {
|
||||
// Collapse consecutive globstar patterns.
|
||||
return r_match_files(prefix, next_suffix, results, cwd);
|
||||
}
|
||||
|
||||
Filename parent_dir;
|
||||
if (prefix.is_local() && !cwd.empty()) {
|
||||
parent_dir = Filename(cwd, prefix);
|
||||
|
|
@ -136,19 +146,24 @@ r_match_files(const Filename &prefix, const string &suffix,
|
|||
if (!has_glob_characters()) {
|
||||
// If there are no special characters in the pattern, it's a literal
|
||||
// match.
|
||||
Filename fn(parent_dir, _pattern);
|
||||
if (suffix.empty()) {
|
||||
// Time to stop.
|
||||
Filename single_filename(parent_dir, _pattern);
|
||||
if (single_filename.exists()) {
|
||||
if (fn.exists()) {
|
||||
results.push_back(Filename(prefix, _pattern));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else if (fn.is_directory()) {
|
||||
// If the pattern ends with a slash, match a directory only.
|
||||
if (suffix == "/") {
|
||||
results.push_back(Filename(prefix, _pattern + "/"));
|
||||
return 1;
|
||||
} else {
|
||||
return next_glob.r_match_files(Filename(prefix, _pattern),
|
||||
next_suffix, results, cwd);
|
||||
}
|
||||
}
|
||||
|
||||
return next_glob.r_match_files(Filename(prefix, _pattern),
|
||||
next_suffix, results, cwd);
|
||||
|
||||
}
|
||||
|
||||
// If there *are* special glob characters, we must attempt to match the
|
||||
|
|
@ -164,18 +179,44 @@ r_match_files(const Filename &prefix, const string &suffix,
|
|||
// the pattern.
|
||||
int num_matched = 0;
|
||||
|
||||
// A globstar pattern matches zero or more directories.
|
||||
if (_pattern == "**") {
|
||||
// Try to match this directory (as if the globstar wasn't there)
|
||||
if (suffix.empty()) {
|
||||
// This is a directory. Add it.
|
||||
results.push_back(Filename(prefix));
|
||||
num_matched++;
|
||||
} else if (suffix == "/") {
|
||||
// Keep the trailing slash, but be sure not to duplicate it.
|
||||
results.push_back(Filename(prefix, ""));
|
||||
num_matched++;
|
||||
} else {
|
||||
num_matched += next_glob.r_match_files(prefix, next_suffix, results, cwd);
|
||||
}
|
||||
next_suffix = suffix;
|
||||
next_glob = *this;
|
||||
}
|
||||
|
||||
vector_string::const_iterator fi;
|
||||
for (fi = dir_files.begin(); fi != dir_files.end(); ++fi) {
|
||||
const string &local_file = (*fi);
|
||||
if (_pattern[0] == '.' || (local_file.empty() || local_file[0] != '.')) {
|
||||
if (matches(local_file)) {
|
||||
// We have a match; continue.
|
||||
if (suffix.empty()) {
|
||||
if (Filename(parent_dir, local_file).is_directory()) {
|
||||
if (suffix.empty() && _pattern != "**") {
|
||||
results.push_back(Filename(prefix, local_file));
|
||||
num_matched++;
|
||||
} else if (suffix == "/" && _pattern != "**") {
|
||||
results.push_back(Filename(prefix, local_file + "/"));
|
||||
num_matched++;
|
||||
} else {
|
||||
num_matched += next_glob.r_match_files(Filename(prefix, local_file),
|
||||
next_suffix, results, cwd);
|
||||
}
|
||||
} else if (suffix.empty()) {
|
||||
results.push_back(Filename(prefix, local_file));
|
||||
num_matched++;
|
||||
} else {
|
||||
num_matched += next_glob.r_match_files(Filename(prefix, local_file),
|
||||
next_suffix, results, cwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ PandaSystem() :
|
|||
#else
|
||||
set_system_tag("eigen", "vectorize", "0");
|
||||
#endif
|
||||
#ifdef __AVX__
|
||||
set_system_tag("eigen", "avx", "1");
|
||||
#else
|
||||
set_system_tag("eigen", "avx", "0");
|
||||
#endif
|
||||
#endif // HAVE_EIGEN
|
||||
|
||||
#ifdef USE_MEMORY_DLMALLOC
|
||||
|
|
@ -189,6 +194,14 @@ is_official_version() {
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory alignment that Panda's allocators are using.
|
||||
*/
|
||||
int PandaSystem::
|
||||
get_memory_alignment() {
|
||||
return MEMORY_HOOK_ALIGNMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string defined by the distributor of this version of Panda, or
|
||||
* "homebuilt" if this version was built directly from the sources by the end-
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ PUBLISHED:
|
|||
static int get_sequence_version();
|
||||
static bool is_official_version();
|
||||
|
||||
static int get_memory_alignment();
|
||||
|
||||
static string get_distributor();
|
||||
static string get_compiler();
|
||||
static string get_build_date();
|
||||
|
|
|
|||
|
|
@ -791,6 +791,15 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
_args_type = InterfaceMaker::AT_single_arg;
|
||||
} else {
|
||||
_args_type = InterfaceMaker::AT_varargs;
|
||||
|
||||
// If the arguments are named "args" and "kwargs", we will be directly
|
||||
// passing the argument tuples to the function.
|
||||
if (_parameters.size() == first_param + 2 &&
|
||||
_parameters[first_param]._name == "args" &&
|
||||
(_parameters[first_param + 1]._name == "kwargs" ||
|
||||
_parameters[first_param + 1]._name == "kwds")) {
|
||||
_flags |= F_explicit_args;
|
||||
}
|
||||
}
|
||||
|
||||
switch (_type) {
|
||||
|
|
@ -890,7 +899,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
if (_args_type == InterfaceMaker::AT_varargs) {
|
||||
// Every other method can take keyword arguments, if they take more
|
||||
// than one argument.
|
||||
_args_type = InterfaceMaker::AT_keyword_args;
|
||||
_args_type |= InterfaceMaker::AT_keyword_args;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ public:
|
|||
F_coerce_constructor = 0x1000,
|
||||
F_divide_float = 0x2000,
|
||||
F_hash = 0x4000,
|
||||
F_explicit_args = 0x8000,
|
||||
};
|
||||
|
||||
typedef vector<Parameter> Parameters;
|
||||
|
|
|
|||
|
|
@ -3453,7 +3453,13 @@ write_function_for_name(ostream &out, Object *obj,
|
|||
max_required_args = collapse_default_remaps(map_sets, max_required_args);
|
||||
}
|
||||
|
||||
if (map_sets.size() > 1 && (args_type == AT_varargs || args_type == AT_keyword_args)) {
|
||||
if (remap->_flags & FunctionRemap::F_explicit_args) {
|
||||
// We have a remap that wants to handle the wrapper itself.
|
||||
string expected_params;
|
||||
write_function_instance(out, remap, 0, 0, expected_params, 2, true, true,
|
||||
args_type, return_flags);
|
||||
|
||||
} else if (map_sets.size() > 1 && (args_type == AT_varargs || args_type == AT_keyword_args)) {
|
||||
switch (args_type) {
|
||||
case AT_keyword_args:
|
||||
indent(out, 2) << "int parameter_count = (int)PyTuple_Size(args);\n";
|
||||
|
|
@ -4536,19 +4542,23 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
expected_params += methodNameFromCppName(remap, "", false);
|
||||
expected_params += "(";
|
||||
|
||||
int num_params = max_num_args;
|
||||
if (remap->_has_this) {
|
||||
num_params += 1;
|
||||
}
|
||||
if (num_params > (int)remap->_parameters.size()) {
|
||||
// Limit to how many parameters this remap actually has.
|
||||
num_params = (int)remap->_parameters.size();
|
||||
max_num_args = num_params;
|
||||
int num_params = 0;
|
||||
|
||||
if ((remap->_flags & FunctionRemap::F_explicit_args) == 0) {
|
||||
num_params = max_num_args;
|
||||
if (remap->_has_this) {
|
||||
--max_num_args;
|
||||
num_params += 1;
|
||||
}
|
||||
if (num_params > (int)remap->_parameters.size()) {
|
||||
// Limit to how many parameters this remap actually has.
|
||||
num_params = (int)remap->_parameters.size();
|
||||
max_num_args = num_params;
|
||||
if (remap->_has_this) {
|
||||
--max_num_args;
|
||||
}
|
||||
}
|
||||
nassertv(num_params <= (int)remap->_parameters.size());
|
||||
}
|
||||
nassertv(num_params <= (int)remap->_parameters.size());
|
||||
|
||||
bool only_pyobjects = true;
|
||||
|
||||
|
|
@ -4584,6 +4594,17 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
|||
}
|
||||
}
|
||||
|
||||
if (remap->_flags & FunctionRemap::F_explicit_args) {
|
||||
// The function handles the arguments by itself.
|
||||
expected_params += "*args";
|
||||
pexprs.push_back("args");
|
||||
if (args_type == AT_keyword_args) {
|
||||
expected_params += ", **kwargs";
|
||||
pexprs.push_back("kwds");
|
||||
}
|
||||
num_params = 0;
|
||||
}
|
||||
|
||||
// Now convert (the rest of the) actual arguments, one by one.
|
||||
for (; pn < num_params; ++pn) {
|
||||
ParameterRemap *param = remap->_parameters[pn]._remap;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#ifndef EVP_H
|
||||
#define EVP_H
|
||||
|
||||
struct EVP_CIPHER_CTX;
|
||||
struct EVP_PKEY;
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
#ifndef SSL_H
|
||||
#define SSL_H
|
||||
|
||||
struct BIO;
|
||||
struct SSL_CTX;
|
||||
struct EVP_CIPHER_CTX;
|
||||
struct EVP_PKEY;
|
||||
struct X509;
|
||||
struct X509_STORE;
|
||||
struct X509_NAME;
|
||||
typedef struct bio_st BIO;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
|
||||
typedef struct evp_pkey_st EVP_PKEY;
|
||||
typedef struct x509_st X509;
|
||||
typedef struct x509_store_st X509_STORE;
|
||||
typedef struct X509_name_st X509_NAME;
|
||||
typedef struct ssl_cipher_st SSL_CIPHER;
|
||||
struct SSL;
|
||||
#define STACK_OF(type) struct stack_st_##type
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
#ifndef X509_H
|
||||
#define X509_H
|
||||
|
||||
struct X509;
|
||||
struct X509_STORE;
|
||||
struct X509_NAME;
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "openssl/rand.h"
|
||||
#include "openssl/evp.h"
|
||||
|
||||
#ifndef HAVE_STREAMSIZE
|
||||
// Some compilers (notably SGI) don't define this for us
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "openssl/evp.h"
|
||||
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
|
||||
|
||||
/**
|
||||
* The streambuf object that implements IDecompressStream and OCompressStream.
|
||||
|
|
|
|||
|
|
@ -19,8 +19,12 @@
|
|||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "openssl/evp.h"
|
||||
#include "openssl/pem.h"
|
||||
|
||||
// Some versions of OpenSSL appear to define this as a macro. Yucky.
|
||||
#undef set_key
|
||||
|
||||
PrcKeyRegistry *PrcKeyRegistry::_global_ptr = NULL;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,10 +22,8 @@
|
|||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include <vector>
|
||||
#include "openssl/evp.h"
|
||||
|
||||
// Some versions of OpenSSL appear to define this as a macro. Yucky.
|
||||
#undef set_key
|
||||
typedef struct evp_pkey_st EVP_PKEY;
|
||||
|
||||
/**
|
||||
* This class records the set of public keys used to verify the signature on a
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ extern "C" {
|
|||
EXPCL_PYSTUB int PyModule_AddObject(...);
|
||||
EXPCL_PYSTUB int PyModule_AddStringConstant(...);
|
||||
EXPCL_PYSTUB int PyModule_Create2(...);
|
||||
EXPCL_PYSTUB int PyModule_Create2TraceRefs(...);
|
||||
EXPCL_PYSTUB int PyNumber_Check(...);
|
||||
EXPCL_PYSTUB int PyNumber_Float(...);
|
||||
EXPCL_PYSTUB int PyNumber_Int(...);
|
||||
|
|
@ -175,6 +176,7 @@ extern "C" {
|
|||
EXPCL_PYSTUB int Py_InitModule4(...);
|
||||
EXPCL_PYSTUB int Py_InitModule4_64(...);
|
||||
EXPCL_PYSTUB int Py_InitModule4TraceRefs(...);
|
||||
EXPCL_PYSTUB int Py_InitModule4TraceRefs_64(...);
|
||||
EXPCL_PYSTUB int _PyArg_ParseTuple_SizeT(...);
|
||||
EXPCL_PYSTUB int _PyArg_ParseTupleAndKeywords_SizeT(...);
|
||||
EXPCL_PYSTUB int _PyArg_Parse_SizeT(...);
|
||||
|
|
@ -184,9 +186,14 @@ extern "C" {
|
|||
EXPCL_PYSTUB int _PyObject_Del(...);
|
||||
EXPCL_PYSTUB int _PyUnicode_AsString(...);
|
||||
EXPCL_PYSTUB int _PyUnicode_AsStringAndSize(...);
|
||||
EXPCL_PYSTUB int _Py_AddToAllObjects(...);
|
||||
EXPCL_PYSTUB int _Py_BuildValue_SizeT(...);
|
||||
EXPCL_PYSTUB int _Py_Dealloc(...);
|
||||
EXPCL_PYSTUB int _Py_ForgetReference(...);
|
||||
EXPCL_PYSTUB int _Py_NegativeRefcount(...);
|
||||
EXPCL_PYSTUB int _Py_NewReference(...);
|
||||
EXPCL_PYSTUB int _Py_PrintReferenceAddresses(...);
|
||||
EXPCL_PYSTUB int _Py_PrintReferences(...);
|
||||
EXPCL_PYSTUB int _Py_RefTotal(...);
|
||||
|
||||
EXPCL_PYSTUB void Py_Initialize();
|
||||
|
|
@ -292,6 +299,7 @@ int PyModule_AddIntConstant(...) { return 0; };
|
|||
int PyModule_AddObject(...) { return 0; };
|
||||
int PyModule_AddStringConstant(...) { return 0; };
|
||||
int PyModule_Create2(...) { return 0; };
|
||||
int PyModule_Create2TraceRefs(...) { return 0; };
|
||||
int PyNumber_Check(...) { return 0; }
|
||||
int PyNumber_Float(...) { return 0; }
|
||||
int PyNumber_Int(...) { return 0; }
|
||||
|
|
@ -377,6 +385,7 @@ int Py_BuildValue(...) { return 0; }
|
|||
int Py_InitModule4(...) { return 0; }
|
||||
int Py_InitModule4_64(...) { return 0; }
|
||||
int Py_InitModule4TraceRefs(...) { return 0; };
|
||||
int Py_InitModule4TraceRefs_64(...) { return 0; };
|
||||
int _PyArg_ParseTuple_SizeT(...) { return 0; };
|
||||
int _PyArg_ParseTupleAndKeywords_SizeT(...) { return 0; };
|
||||
int _PyArg_Parse_SizeT(...) { return 0; };
|
||||
|
|
@ -386,9 +395,14 @@ int _PyObject_DebugFree(...) { return 0; };
|
|||
int _PyObject_Del(...) { return 0; };
|
||||
int _PyUnicode_AsString(...) { return 0; };
|
||||
int _PyUnicode_AsStringAndSize(...) { return 0; };
|
||||
int _Py_AddToAllObjects(...) { return 0; };
|
||||
int _Py_BuildValue_SizeT(...) { return 0; };
|
||||
int _Py_Dealloc(...) { return 0; };
|
||||
int _Py_ForgetReference(...) { return 0; };
|
||||
int _Py_NegativeRefcount(...) { return 0; };
|
||||
int _Py_NewReference(...) { return 0; };
|
||||
int _Py_PrintReferenceAddresses(...) { return 0; };
|
||||
int _Py_PrintReferences(...) { return 0; };
|
||||
int _Py_RefTotal(...) { return 0; };
|
||||
|
||||
// We actually might call this one.
|
||||
|
|
|
|||
|
|
@ -974,9 +974,7 @@ if GetTarget() == 'android':
|
|||
DefSymbol("ALWAYS", "ANDROID")
|
||||
|
||||
if not PkgSkip("EIGEN"):
|
||||
DefSymbol("ALWAYS", "EIGEN_MPL2_ONLY")
|
||||
if GetOptimize() >= 3:
|
||||
DefSymbol("ALWAYS", "EIGEN_NO_DEBUG")
|
||||
if COMPILER == "MSVC":
|
||||
# Squeeze out a bit more performance on MSVC builds...
|
||||
# Only do this if EIGEN_NO_DEBUG is also set, otherwise it
|
||||
|
|
|
|||
|
|
@ -14,6 +14,13 @@
|
|||
#include "graphicsStateGuardian.h"
|
||||
#include "displayInformation.h"
|
||||
|
||||
// For __rdtsc
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#elif defined(__GNUC__) && !defined(__clang__)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns true if these two DisplayModes are identical.
|
||||
*/
|
||||
|
|
@ -58,12 +65,6 @@ DisplayInformation::
|
|||
if (_display_mode_array != NULL) {
|
||||
delete[] _display_mode_array;
|
||||
}
|
||||
if (_cpu_id_data != NULL) {
|
||||
delete _cpu_id_data;
|
||||
}
|
||||
if (_cpu_brand_string != NULL) {
|
||||
delete _cpu_brand_string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -134,12 +135,6 @@ DisplayInformation() {
|
|||
_driver_date_day = 0;
|
||||
_driver_date_year = 0;
|
||||
|
||||
_cpu_id_version = 1;
|
||||
_cpu_id_size = 0;
|
||||
_cpu_id_data = 0;
|
||||
|
||||
_cpu_vendor_string = 0;
|
||||
_cpu_brand_string = 0;
|
||||
_cpu_version_information = 0;
|
||||
_cpu_brand_index = 0;
|
||||
|
||||
|
|
@ -152,7 +147,6 @@ DisplayInformation() {
|
|||
_num_logical_cpus = 0;
|
||||
|
||||
_get_memory_information_function = 0;
|
||||
_cpu_time_function = 0;
|
||||
_update_cpu_frequency_function = 0;
|
||||
|
||||
_os_version_major = -1;
|
||||
|
|
@ -493,62 +487,17 @@ get_driver_date_year() {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
int DisplayInformation::
|
||||
get_cpu_id_version() {
|
||||
return _cpu_id_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of 32-bit values for cpu id binary data.
|
||||
*/
|
||||
int DisplayInformation::
|
||||
get_cpu_id_size() {
|
||||
return _cpu_id_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns part of cpu id binary data based on the index.
|
||||
*/
|
||||
unsigned int DisplayInformation::
|
||||
get_cpu_id_data(int index) {
|
||||
unsigned int data;
|
||||
|
||||
data = 0;
|
||||
if (index >= 0 && index < _cpu_id_size) {
|
||||
data = _cpu_id_data [index];
|
||||
}
|
||||
|
||||
return data;
|
||||
const string &DisplayInformation::
|
||||
get_cpu_vendor_string() const {
|
||||
return _cpu_vendor_string;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const char *DisplayInformation::
|
||||
get_cpu_vendor_string() {
|
||||
const char *string;
|
||||
|
||||
string = _cpu_vendor_string;
|
||||
if (string == 0) {
|
||||
string = "";
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const char *DisplayInformation::
|
||||
get_cpu_brand_string() {
|
||||
const char *string;
|
||||
|
||||
string = _cpu_brand_string;
|
||||
if (string == 0) {
|
||||
string = "";
|
||||
}
|
||||
|
||||
return string;
|
||||
const string &DisplayInformation::
|
||||
get_cpu_brand_string() const {
|
||||
return _cpu_brand_string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -576,18 +525,17 @@ get_cpu_frequency() {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Equivalent to the rdtsc processor instruction.
|
||||
*/
|
||||
uint64_t DisplayInformation::
|
||||
get_cpu_time() {
|
||||
uint64_t cpu_time;
|
||||
|
||||
cpu_time = 0;
|
||||
if (_cpu_time_function) {
|
||||
cpu_time = _cpu_time_function();
|
||||
}
|
||||
|
||||
return cpu_time;
|
||||
#if defined(_MSC_VER) || (defined(__GNUC__) && !defined(__clang__))
|
||||
return __rdtsc();
|
||||
#else
|
||||
unsigned int lo, hi = 0;
|
||||
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
|
||||
return ((uint64_t)hi << 32) | lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -94,17 +94,13 @@ PUBLISHED:
|
|||
int get_driver_date_day();
|
||||
int get_driver_date_year();
|
||||
|
||||
int get_cpu_id_version();
|
||||
int get_cpu_id_size();
|
||||
unsigned int get_cpu_id_data(int index);
|
||||
|
||||
const char *get_cpu_vendor_string();
|
||||
const char *get_cpu_brand_string();
|
||||
const string &get_cpu_vendor_string() const;
|
||||
const string &get_cpu_brand_string() const;
|
||||
unsigned int get_cpu_version_information();
|
||||
unsigned int get_cpu_brand_index();
|
||||
|
||||
uint64_t get_cpu_frequency();
|
||||
uint64_t get_cpu_time();
|
||||
static uint64_t get_cpu_time();
|
||||
|
||||
uint64_t get_maximum_cpu_frequency();
|
||||
uint64_t get_current_cpu_frequency();
|
||||
|
|
@ -158,12 +154,9 @@ public:
|
|||
int _driver_date_day;
|
||||
int _driver_date_year;
|
||||
|
||||
int _cpu_id_version;
|
||||
int _cpu_id_size;
|
||||
unsigned int *_cpu_id_data;
|
||||
|
||||
char *_cpu_vendor_string;
|
||||
char *_cpu_brand_string;
|
||||
string _cpu_vendor_string;
|
||||
string _cpu_brand_string;
|
||||
unsigned int _cpu_version_information;
|
||||
unsigned int _cpu_brand_index;
|
||||
|
||||
|
|
@ -176,7 +169,6 @@ public:
|
|||
int _num_logical_cpus;
|
||||
|
||||
void (*_get_memory_information_function) (DisplayInformation *display_information);
|
||||
uint64_t (*_cpu_time_function) (void);
|
||||
int (*_update_cpu_frequency_function) (int processor_number, DisplayInformation *display_information);
|
||||
|
||||
int _os_version_major;
|
||||
|
|
|
|||
|
|
@ -491,6 +491,12 @@ get_screenshot() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
// Make sure that the correct viewport is active.
|
||||
DisplayRegionPipelineReader dr_reader(this, current_thread);
|
||||
gsg->prepare_display_region(&dr_reader);
|
||||
}
|
||||
|
||||
PT(Texture) tex = new Texture;
|
||||
|
||||
RenderBuffer buffer = gsg->get_render_buffer(get_screenshot_buffer_type(),
|
||||
|
|
|
|||
|
|
@ -1328,21 +1328,24 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
|||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
nassertv(gsg != (GraphicsStateGuardian *)NULL);
|
||||
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
new DisplayRegionPipelineReader(dr, current_thread);
|
||||
PT(SceneSetup) scene_setup;
|
||||
|
||||
win->change_scenes(dr_reader);
|
||||
gsg->prepare_display_region(dr_reader);
|
||||
{
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
win->change_scenes(&dr_reader);
|
||||
gsg->prepare_display_region(&dr_reader);
|
||||
|
||||
if (dr_reader->is_any_clear_active()) {
|
||||
gsg->clear(dr);
|
||||
if (dr_reader.is_any_clear_active()) {
|
||||
gsg->clear(dr);
|
||||
}
|
||||
|
||||
scene_setup = setup_scene(gsg, &dr_reader);
|
||||
}
|
||||
|
||||
PT(SceneSetup) scene_setup = setup_scene(gsg, dr_reader);
|
||||
if (scene_setup == (SceneSetup *)NULL) {
|
||||
// Never mind.
|
||||
|
||||
} else if (dr_reader->get_object()->is_stereo()) {
|
||||
} else if (dr->is_stereo()) {
|
||||
// Don't draw stereo DisplayRegions directly.
|
||||
|
||||
} else if (!gsg->set_scene(scene_setup)) {
|
||||
|
|
@ -1353,9 +1356,6 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
|||
} else {
|
||||
DrawCullHandler cull_handler(gsg);
|
||||
if (gsg->begin_scene()) {
|
||||
delete dr_reader;
|
||||
dr_reader = NULL;
|
||||
|
||||
CallbackObject *cbobj = dr->get_cull_callback();
|
||||
if (cbobj != (CallbackObject *)NULL) {
|
||||
// Issue the cull callback on this DisplayRegion.
|
||||
|
|
@ -1372,10 +1372,6 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
|||
gsg->end_scene();
|
||||
}
|
||||
}
|
||||
|
||||
if (dr_reader != (DisplayRegionPipelineReader *)NULL) {
|
||||
delete dr_reader;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1399,27 +1395,41 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
for (size_t wi = 0; wi < wlist_size; ++wi) {
|
||||
GraphicsOutput *win = wlist[wi];
|
||||
if (win->is_active() && win->get_gsg()->is_active()) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
for (int i = 0; i < num_display_regions; ++i) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
if (dr != (DisplayRegion *)NULL) {
|
||||
DisplayRegionPipelineReader *dr_reader =
|
||||
new DisplayRegionPipelineReader(dr, current_thread);
|
||||
|
||||
if (dr != nullptr) {
|
||||
PT(SceneSetup) scene_setup;
|
||||
PT(CullResult) cull_result;
|
||||
CullKey key;
|
||||
key._gsg = win->get_gsg();
|
||||
key._camera = dr_reader->get_camera();
|
||||
key._lens_index = dr_reader->get_lens_index();
|
||||
{
|
||||
PStatTimer timer(_cull_setup_pcollector, current_thread);
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
scene_setup = setup_scene(gsg, &dr_reader);
|
||||
if (scene_setup == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(key, (DisplayRegion *)NULL)).first;
|
||||
if ((*aci).second == NULL) {
|
||||
key._gsg = gsg;
|
||||
key._camera = dr_reader.get_camera();
|
||||
key._lens_index = dr_reader.get_lens_index();
|
||||
}
|
||||
|
||||
AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(move(key), nullptr)).first;
|
||||
if ((*aci).second == nullptr) {
|
||||
// We have not used this camera already in this thread. Perform
|
||||
// the cull operation.
|
||||
delete dr_reader;
|
||||
dr_reader = NULL;
|
||||
cull_result = dr->get_cull_result(current_thread);
|
||||
if (cull_result != nullptr) {
|
||||
cull_result = cull_result->make_next();
|
||||
} else {
|
||||
// This DisplayRegion has no cull results; draw it.
|
||||
cull_result = new CullResult(gsg, dr->get_draw_region_pcollector());
|
||||
}
|
||||
(*aci).second = dr;
|
||||
cull_to_bins(win, dr, current_thread);
|
||||
cull_to_bins(win, gsg, dr, scene_setup, cull_result, current_thread);
|
||||
|
||||
} else {
|
||||
// We have already culled a scene using this camera in this
|
||||
|
|
@ -1429,14 +1439,11 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
// image.) Of course, the cull result will be the same, so just
|
||||
// use the result from the other DisplayRegion.
|
||||
DisplayRegion *other_dr = (*aci).second;
|
||||
dr->set_cull_result(other_dr->get_cull_result(current_thread),
|
||||
setup_scene(win->get_gsg(), dr_reader),
|
||||
current_thread);
|
||||
cull_result = other_dr->get_cull_result(current_thread);
|
||||
}
|
||||
|
||||
if (dr_reader != (DisplayRegionPipelineReader *)NULL) {
|
||||
delete dr_reader;
|
||||
}
|
||||
// Save the results for next frame.
|
||||
dr->set_cull_result(MOVE(cull_result), MOVE(scene_setup), current_thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1447,50 +1454,26 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
* Called only within the inner loop of cull_to_bins(), above.
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
if (gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return;
|
||||
cull_to_bins(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||
DisplayRegion *dr, SceneSetup *scene_setup,
|
||||
CullResult *cull_result, Thread *current_thread) {
|
||||
|
||||
BinCullHandler cull_handler(cull_result);
|
||||
CallbackObject *cbobj = dr->get_cull_callback();
|
||||
if (cbobj != (CallbackObject *)NULL) {
|
||||
// Issue the cull callback on this DisplayRegion.
|
||||
DisplayRegionCullCallbackData cbdata(&cull_handler, scene_setup);
|
||||
cbobj->do_callback(&cbdata);
|
||||
|
||||
// The callback has taken care of the culling.
|
||||
|
||||
} else {
|
||||
// Perform the cull normally.
|
||||
dr->do_cull(&cull_handler, scene_setup, gsg, current_thread);
|
||||
}
|
||||
|
||||
PT(CullResult) cull_result;
|
||||
PT(SceneSetup) scene_setup;
|
||||
{
|
||||
PStatTimer timer(_cull_setup_pcollector, current_thread);
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
scene_setup = setup_scene(gsg, &dr_reader);
|
||||
cull_result = dr->get_cull_result(current_thread);
|
||||
|
||||
if (cull_result != (CullResult *)NULL) {
|
||||
cull_result = cull_result->make_next();
|
||||
|
||||
} else {
|
||||
// This DisplayRegion has no cull results; draw it.
|
||||
cull_result = new CullResult(gsg, dr->get_draw_region_pcollector());
|
||||
}
|
||||
}
|
||||
|
||||
if (scene_setup != (SceneSetup *)NULL) {
|
||||
BinCullHandler cull_handler(cull_result);
|
||||
CallbackObject *cbobj = dr->get_cull_callback();
|
||||
if (cbobj != (CallbackObject *)NULL) {
|
||||
// Issue the cull callback on this DisplayRegion.
|
||||
DisplayRegionCullCallbackData cbdata(&cull_handler, scene_setup);
|
||||
cbobj->do_callback(&cbdata);
|
||||
|
||||
// The callback has taken care of the culling.
|
||||
|
||||
} else {
|
||||
// Perform the cull normally.
|
||||
dr->do_cull(&cull_handler, scene_setup, gsg, current_thread);
|
||||
}
|
||||
|
||||
PStatTimer timer(_cull_sort_pcollector, current_thread);
|
||||
cull_result->finish_cull(scene_setup, current_thread);
|
||||
}
|
||||
|
||||
// Save the results for next frame.
|
||||
dr->set_cull_result(MOVE(cull_result), MOVE(scene_setup), current_thread);
|
||||
PStatTimer timer(_cull_sort_pcollector, current_thread);
|
||||
cull_result->finish_cull(scene_setup, current_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1538,7 +1521,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
for (int i = 0; i < num_display_regions; ++i) {
|
||||
DisplayRegion *dr = win->get_active_display_region(i);
|
||||
if (dr != (DisplayRegion *)NULL) {
|
||||
draw_bins(win, dr, current_thread);
|
||||
do_draw(win, gsg, dr, current_thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1582,22 +1565,6 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This variant on draw_bins() is only called from draw_bins(), above. It
|
||||
* draws the cull result for a particular DisplayRegion.
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
if (gsg == (GraphicsStateGuardian *)NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
PT(CullResult) cull_result = dr->get_cull_result(current_thread);
|
||||
PT(SceneSetup) scene_setup = dr->get_scene_setup(current_thread);
|
||||
do_draw(cull_result, scene_setup, win, dr, current_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in the draw thread, this calls make_context() on each window on the
|
||||
* list to guarantee its gsg and graphics context both get created.
|
||||
|
|
@ -1899,15 +1866,20 @@ setup_scene(GraphicsStateGuardian *gsg, DisplayRegionPipelineReader *dr) {
|
|||
* Draws the previously-culled scene.
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
do_draw(CullResult *cull_result, SceneSetup *scene_setup,
|
||||
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) {
|
||||
|
||||
CallbackObject *cbobj;
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
|
||||
do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thread *current_thread) {
|
||||
// Statistics
|
||||
PStatGPUTimer timer(gsg, dr->get_draw_region_pcollector(), current_thread);
|
||||
|
||||
PT(CullResult) cull_result;
|
||||
PT(SceneSetup) scene_setup;
|
||||
{
|
||||
DisplayRegion::CDCullReader cdata(dr->_cycler_cull, current_thread);
|
||||
cull_result = cdata->_cull_result;
|
||||
scene_setup = cdata->_scene_setup;
|
||||
}
|
||||
|
||||
CallbackObject *cbobj;
|
||||
|
||||
{
|
||||
DisplayRegionPipelineReader dr_reader(dr, current_thread);
|
||||
win->change_scenes(&dr_reader);
|
||||
|
|
|
|||
|
|
@ -147,9 +147,10 @@ private:
|
|||
Thread *current_thread);
|
||||
|
||||
void cull_to_bins(const Windows &wlist, Thread *current_thread);
|
||||
void cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
|
||||
void cull_to_bins(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||
DisplayRegion *dr, SceneSetup *scene_setup,
|
||||
CullResult *cull_result, Thread *current_thread);
|
||||
void draw_bins(const Windows &wlist, Thread *current_thread);
|
||||
void draw_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
|
||||
void make_contexts(const Windows &wlist, Thread *current_thread);
|
||||
|
||||
void process_events(const Windows &wlist, Thread *current_thread);
|
||||
|
|
@ -162,8 +163,8 @@ private:
|
|||
|
||||
PT(SceneSetup) setup_scene(GraphicsStateGuardian *gsg,
|
||||
DisplayRegionPipelineReader *dr);
|
||||
void do_draw(CullResult *cull_result, SceneSetup *scene_setup,
|
||||
GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread);
|
||||
void do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg,
|
||||
DisplayRegion *dr, Thread *current_thread);
|
||||
|
||||
void do_add_window(GraphicsOutput *window,
|
||||
const GraphicsThreadingModel &threading_model);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,89 @@
|
|||
#include "mutexHolder.h"
|
||||
#include "displayInformation.h"
|
||||
|
||||
#ifdef IS_LINUX
|
||||
#include <sys/sysinfo.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(IS_OSX) || defined(IS_FREEBSD)
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
// GCC and Clang offer a useful cpuid.h header.
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// MSVC has a __cpuid intrinsic.
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
union cpuid_info {
|
||||
char str[16];
|
||||
struct {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the highest cpuid leaf that is supported by the CPU.
|
||||
*/
|
||||
static inline uint32_t get_cpuid_max(uint32_t leaf) {
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
return __get_cpuid_max(leaf, 0);
|
||||
#elif defined(_MSC_VER)
|
||||
uint32_t p[4] = {0};
|
||||
__cpuid((int *)p, leaf);
|
||||
return p[0];
|
||||
#else
|
||||
unsigned int eax = 0;
|
||||
__asm__ ("cpuid\n\t"
|
||||
: "=a" (eax)
|
||||
: "0" (leaf));
|
||||
return eax;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cpuid info for the given leaf.
|
||||
*/
|
||||
static inline void get_cpuid(uint32_t leaf, cpuid_info &info) {
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
__cpuid(leaf, info.eax, info.ebx, info.ecx, info.edx);
|
||||
#elif defined(_MSC_VER)
|
||||
__cpuid((int *)info.str, leaf);
|
||||
#else
|
||||
__asm__ ("cpuid\n\t"
|
||||
: "=a" (info.eax), "=b" (info.ebx), "=c" (info.ecx), "=d" (info.edx)
|
||||
: "0" (leaf));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef IS_LINUX
|
||||
/**
|
||||
* Updates the current memory usage statistics in the DisplayInformation.
|
||||
*/
|
||||
static void update_memory_info(DisplayInformation *info) {
|
||||
struct sysinfo meminfo;
|
||||
if (sysinfo(&meminfo) == 0) {
|
||||
info->_physical_memory = meminfo.totalram;
|
||||
info->_available_physical_memory = meminfo.freeram;
|
||||
info->_page_file_size = meminfo.totalswap;
|
||||
info->_available_page_file_size = meminfo.freeswap;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TypeHandle GraphicsPipe::_type_handle;
|
||||
|
||||
/**
|
||||
|
|
@ -38,24 +121,79 @@ GraphicsPipe() :
|
|||
_display_width = 0;
|
||||
_display_height = 0;
|
||||
|
||||
_display_information = new DisplayInformation ( );
|
||||
}
|
||||
_display_information = new DisplayInformation();
|
||||
|
||||
/**
|
||||
* Don't try to copy GraphicsPipes.
|
||||
*/
|
||||
GraphicsPipe::
|
||||
GraphicsPipe(const GraphicsPipe &) {
|
||||
_is_valid = false;
|
||||
nassertv(false);
|
||||
}
|
||||
cpuid_info info;
|
||||
const uint32_t max_cpuid = get_cpuid_max(0);
|
||||
const uint32_t max_extended = get_cpuid_max(0x80000000);
|
||||
|
||||
/**
|
||||
* Don't try to copy GraphicsPipes.
|
||||
*/
|
||||
void GraphicsPipe::
|
||||
operator = (const GraphicsPipe &) {
|
||||
nassertv(false);
|
||||
if (max_cpuid >= 1) {
|
||||
get_cpuid(0, info);
|
||||
swap(info.ecx, info.edx);
|
||||
_display_information->_cpu_vendor_string = string(info.str + 4, 12);
|
||||
|
||||
get_cpuid(1, info);
|
||||
_display_information->_cpu_version_information = info.eax;
|
||||
_display_information->_cpu_brand_index = info.ebx & 0xff;
|
||||
}
|
||||
|
||||
if (max_extended >= 0x80000004) {
|
||||
char brand[49];
|
||||
get_cpuid(0x80000002, info);
|
||||
memcpy(brand, info.str, 16);
|
||||
get_cpuid(0x80000003, info);
|
||||
memcpy(brand + 16, info.str, 16);
|
||||
get_cpuid(0x80000004, info);
|
||||
memcpy(brand + 32, info.str, 16);
|
||||
brand[48] = 0;
|
||||
_display_information->_cpu_brand_string = brand;
|
||||
}
|
||||
|
||||
#if defined(IS_OSX)
|
||||
// macOS exposes a lot of useful information through sysctl.
|
||||
size_t len = sizeof(uint64_t);
|
||||
sysctlbyname("hw.memsize", &_display_information->_physical_memory, &len, NULL, 0);
|
||||
len = sizeof(uint64_t);
|
||||
sysctlbyname("hw.cpufrequency", &_display_information->_cpu_frequency, &len, NULL, 0);
|
||||
len = sizeof(uint64_t);
|
||||
sysctlbyname("hw.cpufrequency", &_display_information->_current_cpu_frequency, &len, NULL, 0);
|
||||
len = sizeof(uint64_t);
|
||||
sysctlbyname("hw.cpufrequency_max", &_display_information->_maximum_cpu_frequency, &len, NULL, 0);
|
||||
len = sizeof(int);
|
||||
sysctlbyname("hw.physicalcpu", &_display_information->_num_cpu_cores, &len, NULL, 0);
|
||||
len = sizeof(int);
|
||||
sysctlbyname("hw.logicalcpu", &_display_information->_num_logical_cpus, &len, NULL, 0);
|
||||
|
||||
#elif defined(IS_LINUX)
|
||||
_display_information->_get_memory_information_function = &update_memory_info;
|
||||
update_memory_info(_display_information);
|
||||
|
||||
#elif defined(IS_FREEBSD)
|
||||
size_t len = sizeof(uint64_t);
|
||||
sysctlbyname("hw.physmem", &_display_information->_physical_memory, &len, NULL, 0);
|
||||
len = sizeof(uint64_t);
|
||||
sysctlbyname("vm.swap_total", &_display_information->_page_file_size, &len, NULL, 0);
|
||||
|
||||
#elif defined(_WIN32)
|
||||
MEMORYSTATUSEX status;
|
||||
status.dwLength = sizeof(MEMORYSTATUSEX);
|
||||
if (GlobalMemoryStatusEx(&status)) {
|
||||
_display_information->_physical_memory = status.ullTotalPhys;
|
||||
_display_information->_available_physical_memory = status.ullAvailPhys;
|
||||
_display_information->_page_file_size = status.ullTotalPageFile;
|
||||
_display_information->_available_page_file_size = status.ullAvailPageFile;
|
||||
_display_information->_process_virtual_memory = status.ullTotalVirtual;
|
||||
_display_information->_available_process_virtual_memory = status.ullAvailVirtual;
|
||||
_display_information->_memory_load = status.dwMemoryLoad;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(IS_LINUX) || defined(IS_FREEBSD)
|
||||
long nproc = sysconf(_SC_NPROCESSORS_CONF);
|
||||
if (nproc > 0) {
|
||||
_display_information->_num_logical_cpus = nproc;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ class EXPCL_PANDA_DISPLAY GraphicsPipe : public TypedReferenceCount {
|
|||
protected:
|
||||
GraphicsPipe();
|
||||
private:
|
||||
GraphicsPipe(const GraphicsPipe ©);
|
||||
void operator = (const GraphicsPipe ©);
|
||||
GraphicsPipe(const GraphicsPipe ©) DELETED;
|
||||
GraphicsPipe &operator = (const GraphicsPipe ©) DELETED_ASSIGN;
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~GraphicsPipe();
|
||||
|
|
|
|||
|
|
@ -538,6 +538,14 @@ get_supports_depth_stencil() const {
|
|||
return _supports_depth_stencil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this particular GSG supports luminance textures.
|
||||
*/
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_supports_luminance_texture() const {
|
||||
return _supports_luminance_texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this particular GSG supports the filter mode FT_shadow for
|
||||
* depth textures.
|
||||
|
|
|
|||
|
|
@ -253,6 +253,9 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||
_supports_geometry_instancing = false;
|
||||
_supports_indirect_draw = false;
|
||||
|
||||
// We are safe assuming it has luminance support
|
||||
_supports_luminance_texture = true;
|
||||
|
||||
// Assume a maximum of 1 render target in absence of MRT.
|
||||
_max_color_targets = 1;
|
||||
_supports_dual_source_blending = false;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ PUBLISHED:
|
|||
INLINE bool get_supports_generate_mipmap() const;
|
||||
INLINE bool get_supports_depth_texture() const;
|
||||
INLINE bool get_supports_depth_stencil() const;
|
||||
INLINE bool get_supports_luminance_texture() const;
|
||||
INLINE bool get_supports_shadow_filter() const;
|
||||
INLINE bool get_supports_sampler_objects() const;
|
||||
INLINE bool get_supports_basic_shaders() const;
|
||||
|
|
@ -203,6 +204,7 @@ PUBLISHED:
|
|||
MAKE_PROPERTY(supports_generate_mipmap, get_supports_generate_mipmap);
|
||||
MAKE_PROPERTY(supports_depth_texture, get_supports_depth_texture);
|
||||
MAKE_PROPERTY(supports_depth_stencil, get_supports_depth_stencil);
|
||||
MAKE_PROPERTY(supports_luminance_texture, get_supports_luminance_texture);
|
||||
MAKE_PROPERTY(supports_shadow_filter, get_supports_shadow_filter);
|
||||
MAKE_PROPERTY(supports_sampler_objects, get_supports_sampler_objects);
|
||||
MAKE_PROPERTY(supports_basic_shaders, get_supports_basic_shaders);
|
||||
|
|
@ -597,6 +599,7 @@ protected:
|
|||
bool _supports_generate_mipmap;
|
||||
bool _supports_depth_texture;
|
||||
bool _supports_depth_stencil;
|
||||
bool _supports_luminance_texture;
|
||||
bool _supports_shadow_filter;
|
||||
bool _supports_sampler_objects;
|
||||
bool _supports_basic_shaders;
|
||||
|
|
|
|||
|
|
@ -18,14 +18,6 @@ INLINE BioPtr::
|
|||
BioPtr(BIO *bio) : _bio(bio) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE bool BioPtr::
|
||||
should_retry() const {
|
||||
return (_bio != NULL) && BIO_should_retry(_bio);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
#include "urlSpec.h"
|
||||
#include "config_downloader.h"
|
||||
|
||||
#include "openSSLWrapper.h" // must be included before any other openssl.
|
||||
#include "openssl/ssl.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
|
|
@ -199,7 +202,7 @@ connect() {
|
|||
|
||||
if (result != 0 && BIO_sock_should_retry(-1)) {
|
||||
// It's still in progress; we should retry later. This causes
|
||||
// should_reply() to return true.
|
||||
// should_retry() to return true.
|
||||
BIO_set_flags(_bio, BIO_FLAGS_SHOULD_RETRY);
|
||||
_connecting = true;
|
||||
return false;
|
||||
|
|
@ -218,6 +221,14 @@ connect() {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
bool BioPtr::
|
||||
should_retry() const {
|
||||
return (_bio != NULL) && BIO_should_retry(_bio);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -19,13 +19,7 @@
|
|||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
#define OPENSSL_NO_KRB5
|
||||
#endif
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "openSSLWrapper.h" // must be included before any other openssl.
|
||||
#include "openssl/ssl.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
|
|
@ -35,6 +29,8 @@
|
|||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
typedef struct bio_st BIO;
|
||||
|
||||
class URLSpec;
|
||||
|
||||
/**
|
||||
|
|
@ -52,7 +48,7 @@ public:
|
|||
void set_nbio(bool nbio);
|
||||
bool connect();
|
||||
|
||||
INLINE bool should_retry() const;
|
||||
bool should_retry() const;
|
||||
|
||||
INLINE BIO &operator *() const;
|
||||
INLINE BIO *operator -> () const;
|
||||
|
|
|
|||
|
|
@ -19,14 +19,8 @@
|
|||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
#define OPENSSL_NO_KRB5
|
||||
#endif
|
||||
|
||||
#include "bioPtr.h"
|
||||
#include "pointerTo.h"
|
||||
#include "openSSLWrapper.h" // must be included before any other openssl.
|
||||
#include "openssl/ssl.h"
|
||||
|
||||
/**
|
||||
* The streambuf object that implements IBioStream.
|
||||
|
|
|
|||
|
|
@ -19,14 +19,8 @@
|
|||
// This module is not compiled if OpenSSL is not available.
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
#define OPENSSL_NO_KRB5
|
||||
#endif
|
||||
|
||||
#include "bioStream.h"
|
||||
#include "referenceCount.h"
|
||||
#include "openSSLWrapper.h" // must be included before any other openssl.
|
||||
#include "openssl/ssl.h"
|
||||
|
||||
/**
|
||||
* A wrapper around an BioStream object to make a reference-counting pointer
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "openSSLWrapper.h"
|
||||
|
||||
#if defined(WIN32_VC) || defined(WIN64_VC)
|
||||
#include <WinSock2.h>
|
||||
#include <windows.h> // for select()
|
||||
|
|
@ -1474,6 +1476,14 @@ run_setup_ssl() {
|
|||
return false;
|
||||
}
|
||||
|
||||
string hostname = _request.get_url().get_server();
|
||||
result = SSL_set_tlsext_host_name(ssl, hostname.c_str());
|
||||
if (result == 0) {
|
||||
downloader_cat.error()
|
||||
<< _NOTIFY_HTTP_CHANNEL_ID
|
||||
<< "Could not set TLS SNI hostname to '" << hostname << "'\n";
|
||||
}
|
||||
|
||||
/*
|
||||
* It would be nice to use something like SSL_set_client_cert_cb() here to set
|
||||
* a callback to provide the certificate should it be requested, or even to
|
||||
|
|
|
|||
|
|
@ -22,10 +22,6 @@
|
|||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
#define OPENSSL_NO_KRB5
|
||||
#endif
|
||||
|
||||
#include "httpClient.h"
|
||||
#include "httpEnum.h"
|
||||
#include "urlSpec.h"
|
||||
|
|
@ -37,10 +33,10 @@
|
|||
#include "pointerTo.h"
|
||||
#include "config_downloader.h"
|
||||
#include "filename.h"
|
||||
#include "openSSLWrapper.h" // must be included before any other openssl.
|
||||
#include "openssl/ssl.h"
|
||||
#include "typedReferenceCount.h"
|
||||
|
||||
typedef struct bio_st BIO;
|
||||
|
||||
class Ramfile;
|
||||
class HTTPClient;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
||||
#include "openSSLWrapper.h"
|
||||
|
||||
PT(HTTPClient) HTTPClient::_global_ptr;
|
||||
|
||||
/**
|
||||
|
|
@ -68,6 +70,68 @@ tokenize(const string &str, vector_string &words, const string &delimiters) {
|
|||
words.push_back(string());
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/**
|
||||
* This method is attached as a callback for SSL messages only when debug
|
||||
* output is enabled.
|
||||
*/
|
||||
static void
|
||||
ssl_msg_callback(int write_p, int version, int content_type,
|
||||
const void *, size_t len, SSL *, void *) {
|
||||
ostringstream describe;
|
||||
if (write_p) {
|
||||
describe << "sent ";
|
||||
} else {
|
||||
describe << "received ";
|
||||
}
|
||||
switch (version) {
|
||||
case SSL2_VERSION:
|
||||
describe << "SSL 2.0 ";
|
||||
break;
|
||||
|
||||
case SSL3_VERSION:
|
||||
describe << "SSL 3.0 ";
|
||||
break;
|
||||
|
||||
case TLS1_VERSION:
|
||||
describe << "TLS 1.0 ";
|
||||
break;
|
||||
|
||||
default:
|
||||
describe << "unknown protocol ";
|
||||
}
|
||||
|
||||
describe << "message: ";
|
||||
|
||||
if (version != SSL2_VERSION) {
|
||||
switch (content_type) {
|
||||
case 20:
|
||||
describe << "change cipher spec, ";
|
||||
break;
|
||||
|
||||
case 21:
|
||||
describe << "alert, ";
|
||||
break;
|
||||
|
||||
case 22:
|
||||
describe << "handshake, ";
|
||||
break;
|
||||
|
||||
case 23:
|
||||
describe << "application data, ";
|
||||
break;
|
||||
|
||||
default:
|
||||
describe << "unknown content type, ";
|
||||
}
|
||||
}
|
||||
|
||||
describe << len << " bytes.\n";
|
||||
|
||||
downloader_cat.debug() << describe.str();
|
||||
}
|
||||
#endif // !defined(NDEBUG)
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -1564,68 +1628,6 @@ split_whitespace(string &a, string &b, const string &c) {
|
|||
b = c.substr(p);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/**
|
||||
* This method is attached as a callback for SSL messages only when debug
|
||||
* output is enabled.
|
||||
*/
|
||||
void HTTPClient::
|
||||
ssl_msg_callback(int write_p, int version, int content_type,
|
||||
const void *, size_t len, SSL *, void *) {
|
||||
ostringstream describe;
|
||||
if (write_p) {
|
||||
describe << "sent ";
|
||||
} else {
|
||||
describe << "received ";
|
||||
}
|
||||
switch (version) {
|
||||
case SSL2_VERSION:
|
||||
describe << "SSL 2.0 ";
|
||||
break;
|
||||
|
||||
case SSL3_VERSION:
|
||||
describe << "SSL 3.0 ";
|
||||
break;
|
||||
|
||||
case TLS1_VERSION:
|
||||
describe << "TLS 1.0 ";
|
||||
break;
|
||||
|
||||
default:
|
||||
describe << "unknown protocol ";
|
||||
}
|
||||
|
||||
describe << "message: ";
|
||||
|
||||
if (version != SSL2_VERSION) {
|
||||
switch (content_type) {
|
||||
case 20:
|
||||
describe << "change cipher spec, ";
|
||||
break;
|
||||
|
||||
case 21:
|
||||
describe << "alert, ";
|
||||
break;
|
||||
|
||||
case 22:
|
||||
describe << "handshake, ";
|
||||
break;
|
||||
|
||||
case 23:
|
||||
describe << "application data, ";
|
||||
break;
|
||||
|
||||
default:
|
||||
describe << "unknown content type, ";
|
||||
}
|
||||
}
|
||||
|
||||
describe << len << " bytes.\n";
|
||||
|
||||
downloader_cat.debug() << describe.str();
|
||||
}
|
||||
#endif // !defined(NDEBUG)
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -32,7 +32,11 @@
|
|||
#include "pmap.h"
|
||||
#include "pset.h"
|
||||
#include "referenceCount.h"
|
||||
#include "openSSLWrapper.h"
|
||||
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
typedef struct x509_st X509;
|
||||
typedef struct X509_name_st X509_NAME;
|
||||
typedef struct evp_pkey_st EVP_PKEY;
|
||||
|
||||
class Filename;
|
||||
class HTTPChannel;
|
||||
|
|
@ -155,12 +159,6 @@ private:
|
|||
|
||||
static void split_whitespace(string &a, string &b, const string &c);
|
||||
|
||||
#ifndef NDEBUG
|
||||
static void ssl_msg_callback(int write_p, int version, int content_type,
|
||||
const void *buf, size_t len, SSL *ssl,
|
||||
void *arg);
|
||||
#endif
|
||||
|
||||
typedef pvector<URLSpec> Proxies;
|
||||
typedef pmap<string, Proxies> ProxiesByScheme;
|
||||
ProxiesByScheme _proxies_by_scheme;
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
|
|||
} else if (child->is_of_type(CollisionSphere::get_class_type())) {
|
||||
CPT(CollisionSphere) sphere = DCAST(CollisionSphere, child);
|
||||
LPoint3 center = sphere->get_center();
|
||||
LVector3 offset(sphere->get_radius(), 0, 0);
|
||||
PN_stdfloat radius = sphere->get_radius();
|
||||
|
||||
EggGroup *egg_sphere;
|
||||
if (num_solids == 1) {
|
||||
|
|
@ -499,15 +499,19 @@ convert_collision_node(CollisionNode *node, const WorkingNodePath &node_path,
|
|||
}
|
||||
egg_sphere->set_collide_flags(flags);
|
||||
|
||||
EggVertex ev1, ev2;
|
||||
ev1.set_pos(LCAST(double, (center + offset) * net_mat));
|
||||
ev2.set_pos(LCAST(double, (center - offset) * net_mat));
|
||||
EggVertex ev1, ev2, ev3, ev4;
|
||||
ev1.set_pos(LCAST(double, (center + LVector3(radius, 0, 0)) * net_mat));
|
||||
ev2.set_pos(LCAST(double, (center + LVector3(0, radius, 0)) * net_mat));
|
||||
ev3.set_pos(LCAST(double, (center + LVector3(-radius, 0, 0)) * net_mat));
|
||||
ev4.set_pos(LCAST(double, (center + LVector3(0, -radius, 0)) * net_mat));
|
||||
|
||||
EggPolygon *egg_poly = new EggPolygon;
|
||||
egg_sphere->add_child(egg_poly);
|
||||
|
||||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev1));
|
||||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev2));
|
||||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev3));
|
||||
egg_poly->add_vertex(cvpool->create_unique_vertex(ev4));
|
||||
|
||||
} else if (child->is_of_type(CollisionPlane::get_class_type())) {
|
||||
LPlane plane = DCAST(CollisionPlane, child)->get_plane();
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include <iterator>
|
||||
#include <time.h>
|
||||
|
||||
#include "openSSLWrapper.h"
|
||||
|
||||
// This sequence of bytes begins each Multifile to identify it as a Multifile.
|
||||
const char Multifile::_header[] = "pmf\0\n\r";
|
||||
const size_t Multifile::_header_size = 6;
|
||||
|
|
@ -768,43 +770,6 @@ add_signature(const Filename &composite, const string &password) {
|
|||
}
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
/**
|
||||
* Adds a new signature to the Multifile. This signature associates the
|
||||
* indicated certificate with the current contents of the Multifile. When the
|
||||
* Multifile is read later, the signature will still be present only if the
|
||||
* Multifile is unchanged; any subsequent changes to the Multifile will
|
||||
* automatically invalidate and remove the signature.
|
||||
*
|
||||
* If chain is non-NULL, it represents the certificate chain that validates
|
||||
* the certificate.
|
||||
*
|
||||
* The specified private key must match the certificate, and the Multifile
|
||||
* must be open in read-write mode. The private key is only used for
|
||||
* generating the signature; it is not written to the Multifile and cannot be
|
||||
* retrieved from the Multifile later. (However, the certificate *can* be
|
||||
* retrieved from the Multifile later, to identify the entity that created the
|
||||
* signature.)
|
||||
*
|
||||
* This implicitly causes a repack() operation if one is needed. Returns true
|
||||
* on success, false on failure.
|
||||
*/
|
||||
bool Multifile::
|
||||
add_signature(X509 *certificate, STACK_OF(X509) *chain, EVP_PKEY *pkey) {
|
||||
// Convert the certificate and chain into our own CertChain structure.
|
||||
CertChain cert_chain;
|
||||
cert_chain.push_back(CertRecord(certificate));
|
||||
if (chain != NULL) {
|
||||
int num = sk_X509_num(chain);
|
||||
for (int i = 0; i < num; ++i) {
|
||||
cert_chain.push_back(CertRecord((X509 *)sk_X509_value(chain, i)));
|
||||
}
|
||||
}
|
||||
|
||||
return add_signature(cert_chain, pkey);
|
||||
}
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
/**
|
||||
* Adds a new signature to the Multifile. This signature associates the
|
||||
|
|
|
|||
|
|
@ -24,7 +24,11 @@
|
|||
#include "indirectLess.h"
|
||||
#include "referenceCount.h"
|
||||
#include "pvector.h"
|
||||
#include "openSSLWrapper.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
typedef struct x509_st X509;
|
||||
typedef struct evp_pkey_st EVP_PKEY;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A file that contains a set of files.
|
||||
|
|
@ -148,7 +152,6 @@ public:
|
|||
};
|
||||
typedef pvector<CertRecord> CertChain;
|
||||
|
||||
bool add_signature(X509 *certificate, STACK_OF(X509) *chain, EVP_PKEY *pkey);
|
||||
bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
|
||||
|
||||
const CertChain &get_signature(int n) const;
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
|
|||
|
||||
if (cgGetParameterBaseResource(p) == CG_ATTR0) {
|
||||
// The Cg toolkit claims that it is bound to a generic vertex attribute.
|
||||
if (_glsl_program != 0) {
|
||||
if (_glgsg->has_fixed_function_pipeline() && _glsl_program != 0) {
|
||||
// This is where the Cg glslv compiler lies, making the stupid
|
||||
// assumption that we're using an NVIDIA card where generic attributes
|
||||
// are aliased with conventional vertex attributes. Instead, it
|
||||
|
|
@ -246,7 +246,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
|
|||
// A conventional texture coordinate set.
|
||||
loc = CA_texcoord + cgGetParameterResourceIndex(p);
|
||||
|
||||
} else {
|
||||
} else if (_glgsg->has_fixed_function_pipeline()) {
|
||||
// Some other conventional vertex attribute.
|
||||
switch (res) {
|
||||
case CG_POSITION0:
|
||||
|
|
@ -276,6 +276,14 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
|
|||
GLCAT.error(false) << ".\n";
|
||||
loc = CA_unknown;
|
||||
}
|
||||
} else {
|
||||
GLCAT.error()
|
||||
<< "Cg varying " << cgGetParameterName(p);
|
||||
if (cgGetParameterSemantic(p)) {
|
||||
GLCAT.error(false) << " : " << cgGetParameterSemantic(p);
|
||||
}
|
||||
GLCAT.error(false) << " is bound to a conventional vertex attribute, "
|
||||
"but the compatibility profile is not enabled.\n";
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
@ -916,8 +924,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
|||
} else {
|
||||
// There is no vertex column with this name; disable the attribute
|
||||
// array.
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (p == 0) {
|
||||
if (_glgsg->has_fixed_function_pipeline() && p == 0) {
|
||||
// NOTE: if we disable attribute 0 in compatibility profile, the
|
||||
// object will disappear. In GLSL we fix this by forcing the vertex
|
||||
// column to be at 0, but we don't have control over that with Cg.
|
||||
|
|
@ -930,9 +937,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
|||
_glgsg->_glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
}
|
||||
|
||||
} else
|
||||
#endif // SUPPORT_FIXED_FUNCTION
|
||||
if (p >= 0) {
|
||||
} else if (p >= 0) {
|
||||
_glgsg->disable_vertex_attrib_array(p);
|
||||
|
||||
if (p == _color_attrib_index) {
|
||||
|
|
|
|||
|
|
@ -269,6 +269,9 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||
}
|
||||
}
|
||||
#endif
|
||||
} else if (mode == FM_refresh) {
|
||||
// Just bind the FBO.
|
||||
rebuild_bitplanes();
|
||||
}
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
|
|
@ -1162,8 +1165,10 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) {
|
|||
glgsg->apply_texture(gtc);
|
||||
|
||||
#if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION)
|
||||
GLclampf priority = 1.0f;
|
||||
glPrioritizeTextures(1, >c->_index, &priority);
|
||||
if (glgsg->has_fixed_function_pipeline()) {
|
||||
GLclampf priority = 1.0f;
|
||||
glPrioritizeTextures(1, >c->_index, &priority);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
|
|
|
|||
|
|
@ -130,6 +130,33 @@ get_gl_version_minor() const {
|
|||
return _gl_version_minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a core profile or a compatibility mode is considered.
|
||||
*/
|
||||
/*INLINE bool CLP(GraphicsStateGuardian)::
|
||||
has_core_profile() const {
|
||||
return _core_profile;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Returns whether the fixed function pipeline is supported.
|
||||
*/
|
||||
INLINE bool CLP(GraphicsStateGuardian)::
|
||||
has_fixed_function_pipeline() const {
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
return false;
|
||||
#elif defined(OPENGLES_1)
|
||||
return true;
|
||||
#elif defined(OPENGLES)
|
||||
return false;
|
||||
#else
|
||||
// Otherwise, we can just check whether we are using a core profile or a
|
||||
// compatibility mode. The variable _core_profile is already taking into
|
||||
// account if a GL < 3.2 is considered (becoming false)
|
||||
return !_core_profile;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls glFinish() if the config variable gl-finish is set True.
|
||||
*/
|
||||
|
|
@ -363,7 +390,7 @@ enable_line_smooth(bool val) {
|
|||
INLINE void CLP(GraphicsStateGuardian)::
|
||||
enable_point_smooth(bool val) {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (_point_smooth_enabled != val) {
|
||||
if (has_fixed_function_pipeline() && _point_smooth_enabled != val) {
|
||||
_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
|
||||
_point_smooth_enabled = val;
|
||||
if (val) {
|
||||
|
|
|
|||
|
|
@ -369,6 +369,12 @@ CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
|
|||
_gl_shadlang_ver_major = 0;
|
||||
_gl_shadlang_ver_minor = 0;
|
||||
|
||||
// Let's say we have a core profile, to be checked later (Otherwise, if we are
|
||||
// wrong the user may ask for some non-available functions)
|
||||
#ifndef OPENGLES
|
||||
_core_profile = true;
|
||||
#endif
|
||||
|
||||
// Hack. Turn on the flag that we turned off at a higher level, since we
|
||||
// know this works properly in OpenGL, and we want the performance benefit
|
||||
// it gives us.
|
||||
|
|
@ -547,6 +553,7 @@ reset() {
|
|||
GLCAT.debug() << "Using compatibility profile\n";
|
||||
}
|
||||
}
|
||||
_core_profile = core_profile;
|
||||
#elif defined(OPENGLES_1)
|
||||
static const bool core_profile = false;
|
||||
#else
|
||||
|
|
@ -723,7 +730,7 @@ reset() {
|
|||
#endif
|
||||
|
||||
#if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION)
|
||||
if (is_at_least_gl_version(1, 4)) {
|
||||
if (has_fixed_function_pipeline() && is_at_least_gl_version(1, 4)) {
|
||||
_glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)
|
||||
get_extension_func("glSecondaryColorPointer");
|
||||
|
||||
|
|
@ -1105,12 +1112,13 @@ reset() {
|
|||
_supports_rescale_normal = true;
|
||||
#else
|
||||
_supports_rescale_normal =
|
||||
!core_profile && gl_support_rescale_normal &&
|
||||
has_fixed_function_pipeline() && gl_support_rescale_normal &&
|
||||
(is_at_least_gl_version(1, 2) || has_extension("GL_EXT_rescale_normal"));
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
_use_separate_specular_color = gl_separate_specular_color &&
|
||||
_use_separate_specular_color =
|
||||
has_fixed_function_pipeline() && gl_separate_specular_color &&
|
||||
(is_at_least_gl_version(1, 2) || has_extension("GL_EXT_separate_specular_color"));
|
||||
#endif
|
||||
#endif // SUPPORT_FIXED_FUNCTION
|
||||
|
|
@ -1162,8 +1170,10 @@ reset() {
|
|||
get_extension_func("glActiveTexture");
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
_glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
|
||||
get_extension_func("glClientActiveTexture");
|
||||
if (has_fixed_function_pipeline()) {
|
||||
_glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
|
||||
get_extension_func("glClientActiveTexture");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
|
|
@ -1192,8 +1202,10 @@ reset() {
|
|||
get_extension_func("glActiveTextureARB");
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
_glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
|
||||
get_extension_func("glClientActiveTextureARB");
|
||||
if (has_fixed_function_pipeline()) {
|
||||
_glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
|
||||
get_extension_func("glClientActiveTextureARB");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
|
|
@ -1221,7 +1233,7 @@ reset() {
|
|||
if (supports_multitexture) {
|
||||
if (_glActiveTexture == NULL
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
|| _glClientActiveTexture == NULL
|
||||
|| (has_fixed_function_pipeline() && _glClientActiveTexture == NULL)
|
||||
#endif
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
|| GLf(_glMultiTexCoord1) == NULL || GLf(_glMultiTexCoord2) == NULL
|
||||
|
|
@ -1240,7 +1252,7 @@ reset() {
|
|||
}
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (!supports_multitexture || core_profile) {
|
||||
if (!supports_multitexture || !has_fixed_function_pipeline()) {
|
||||
_glClientActiveTexture = null_glActiveTexture;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1251,6 +1263,7 @@ reset() {
|
|||
_supports_depth_stencil = has_extension("GL_OES_packed_depth_stencil");
|
||||
_supports_depth24 = has_extension("GL_OES_depth24");
|
||||
_supports_depth32 = has_extension("GL_OES_depth32");
|
||||
_supports_luminance_texture = true;
|
||||
|
||||
#elif defined(OPENGLES)
|
||||
if (is_at_least_gles_version(3, 0)) {
|
||||
|
|
@ -1271,12 +1284,16 @@ reset() {
|
|||
_supports_depth24 = has_extension("GL_OES_depth24");
|
||||
_supports_depth32 = has_extension("GL_OES_depth32");
|
||||
}
|
||||
_supports_luminance_texture = true;
|
||||
#else
|
||||
_supports_depth_texture = (is_at_least_gl_version(1, 4) ||
|
||||
has_extension("GL_ARB_depth_texture"));
|
||||
_supports_depth_stencil = (is_at_least_gl_version(3, 0) ||
|
||||
has_extension("GL_ARB_framebuffer_object") ||
|
||||
has_extension("GL_EXT_packed_depth_stencil"));
|
||||
|
||||
// OpenGL 3 deprecates luminance, luminance-alpha and alpha textures.
|
||||
_supports_luminance_texture = !core_profile;
|
||||
#endif
|
||||
|
||||
#ifdef OPENGLES_2
|
||||
|
|
@ -1300,12 +1317,11 @@ reset() {
|
|||
_supports_shadow_filter = false;
|
||||
}*/
|
||||
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
_supports_texture_combine = false;
|
||||
_supports_texture_saved_result = false;
|
||||
_supports_texture_dot3 = false;
|
||||
#else
|
||||
if (!core_profile) {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (has_fixed_function_pipeline()) {
|
||||
_supports_texture_combine =
|
||||
is_at_least_gl_version(1, 3) ||
|
||||
is_at_least_gles_version(1, 1) ||
|
||||
|
|
@ -1786,12 +1802,8 @@ reset() {
|
|||
// We need to have a default shader to apply in case something didn't happen
|
||||
// to have a shader applied, or if it failed to compile. This default
|
||||
// shader just outputs a red color, indicating that something went wrong.
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
if (_default_shader == NULL) {
|
||||
_default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
|
||||
}
|
||||
#elif !defined(OPENGLES)
|
||||
if (_default_shader == NULL && core_profile) {
|
||||
#ifndef OPENGLES_1
|
||||
if (_default_shader == NULL && !has_fixed_function_pipeline()) {
|
||||
_default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2943,7 +2955,7 @@ reset() {
|
|||
glDisable(GL_LINE_SMOOTH);
|
||||
#endif
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (!core_profile) {
|
||||
if (has_fixed_function_pipeline()) {
|
||||
glDisable(GL_POINT_SMOOTH);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -2995,7 +3007,7 @@ reset() {
|
|||
// Count the max number of lights
|
||||
_max_lights = 0;
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (!core_profile) {
|
||||
if (has_fixed_function_pipeline()) {
|
||||
GLint max_lights = 0;
|
||||
glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
|
||||
_max_lights = max_lights;
|
||||
|
|
@ -3010,7 +3022,7 @@ reset() {
|
|||
// Count the max number of clipping planes
|
||||
_max_clip_planes = 0;
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (!core_profile) {
|
||||
if (has_fixed_function_pipeline()) {
|
||||
GLint max_clip_planes = 0;
|
||||
glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
|
||||
_max_clip_planes = max_clip_planes;
|
||||
|
|
@ -3024,7 +3036,7 @@ reset() {
|
|||
|
||||
_max_texture_stages = 1;
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (supports_multitexture && !core_profile) {
|
||||
if (supports_multitexture && has_fixed_function_pipeline()) {
|
||||
GLint max_texture_stages = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_stages);
|
||||
_max_texture_stages = max_texture_stages;
|
||||
|
|
@ -3057,7 +3069,7 @@ reset() {
|
|||
report_my_gl_errors();
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (!core_profile) {
|
||||
if (has_fixed_function_pipeline()) {
|
||||
if (gl_cheap_textures) {
|
||||
GLCAT.info()
|
||||
<< "Setting glHint() for fastest textures.\n";
|
||||
|
|
@ -3070,7 +3082,7 @@ reset() {
|
|||
#endif
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (!core_profile) {
|
||||
if (has_fixed_function_pipeline()) {
|
||||
GLint num_red_bits = 0;
|
||||
glGetIntegerv(GL_RED_BITS, &num_red_bits);
|
||||
if (num_red_bits < 8) {
|
||||
|
|
@ -3538,7 +3550,9 @@ prepare_display_region(DisplayRegionPipelineReader *dr) {
|
|||
void CLP(GraphicsStateGuardian)::
|
||||
clear_before_callback() {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
disable_standard_vertex_arrays();
|
||||
if (has_fixed_function_pipeline()) {
|
||||
disable_standard_vertex_arrays();
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENGLES_1
|
||||
if (_vertex_array_shader_context != 0) {
|
||||
|
|
@ -3620,16 +3634,18 @@ calc_projection_mat(const Lens *lens) {
|
|||
bool CLP(GraphicsStateGuardian)::
|
||||
prepare_lens() {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
|
||||
if (has_fixed_function_pipeline()) {
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
call_glLoadMatrix(_projection_mat->get_mat());
|
||||
report_my_gl_errors();
|
||||
|
||||
do_point_size();
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
call_glLoadMatrix(_projection_mat->get_mat());
|
||||
report_my_gl_errors();
|
||||
|
||||
do_point_size();
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
|
|
@ -3762,7 +3778,7 @@ end_frame(Thread *current_thread) {
|
|||
// will just mean that we'll count everything as resident until the user
|
||||
// connects PStats, at which point it will then correct the assessment. No
|
||||
// harm done.
|
||||
if (PStatClient::is_connected()) {
|
||||
if (has_fixed_function_pipeline() && PStatClient::is_connected()) {
|
||||
check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
|
||||
check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
|
||||
|
||||
|
|
@ -3813,7 +3829,7 @@ end_frame(Thread *current_thread) {
|
|||
// Now is a good time to delete any pending display lists.
|
||||
#ifndef OPENGLES
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (display_lists) {
|
||||
if (has_fixed_function_pipeline() && display_lists) {
|
||||
LightMutexHolder holder(_lock);
|
||||
if (!_deleted_display_lists.empty()) {
|
||||
DeletedNames::iterator ddli;
|
||||
|
|
@ -3922,11 +3938,13 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
// We can't draw without a shader bound in OpenGL ES 2. This shouldn't
|
||||
// happen anyway unless the default shader failed to compile somehow.
|
||||
if (_current_shader_context == NULL) {
|
||||
return false;
|
||||
#ifndef OPENGLES_1
|
||||
if (!has_fixed_function_pipeline()) {
|
||||
// We can't draw without a shader bound in OpenGL ES 2. This shouldn't
|
||||
// happen anyway unless the default shader failed to compile somehow.
|
||||
if (_current_shader_context == NULL) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3967,7 +3985,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
}
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
if (has_fixed_function_pipeline() && _data_reader->is_vertex_transformed()) {
|
||||
// If the vertex data claims to be already transformed into clip
|
||||
// coordinates, wipe out the current projection and modelview matrix (so
|
||||
// we don't attempt to transform it again).
|
||||
|
|
@ -3981,7 +3999,8 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
#endif
|
||||
|
||||
#if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
|
||||
if (/*geom_reader->get_usage_hint() == Geom::UH_static &&*/
|
||||
if (has_fixed_function_pipeline() &&
|
||||
/*geom_reader->get_usage_hint() == Geom::UH_static &&*/
|
||||
_data_reader->get_usage_hint() == Geom::UH_static &&
|
||||
display_lists) {
|
||||
// If the geom claims to be totally static, try to build it into a display
|
||||
|
|
@ -4072,33 +4091,35 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
_vertex_array_shader_context->disable_shader_vertex_arrays();
|
||||
}
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (!update_standard_vertex_arrays(force)) {
|
||||
if (has_fixed_function_pipeline() && !update_standard_vertex_arrays(force)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
// Shader.
|
||||
if (_vertex_array_shader_context == 0 ||
|
||||
_vertex_array_shader_context->uses_standard_vertex_arrays()) {
|
||||
// Previous shader used standard arrays.
|
||||
if (_current_shader_context->uses_standard_vertex_arrays()) {
|
||||
// So does the current, so update them.
|
||||
if (!update_standard_vertex_arrays(force)) {
|
||||
return false;
|
||||
if (has_fixed_function_pipeline()) {
|
||||
// Shader.
|
||||
if (_vertex_array_shader_context == 0 ||
|
||||
_vertex_array_shader_context->uses_standard_vertex_arrays()) {
|
||||
// Previous shader used standard arrays.
|
||||
if (_current_shader_context->uses_standard_vertex_arrays()) {
|
||||
// So does the current, so update them.
|
||||
if (!update_standard_vertex_arrays(force)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// The current shader does not, so disable them entirely.
|
||||
disable_standard_vertex_arrays();
|
||||
}
|
||||
} else {
|
||||
// The current shader does not, so disable them entirely.
|
||||
disable_standard_vertex_arrays();
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_CG
|
||||
else if (_vertex_array_shader_context->is_of_type(CLP(CgShaderContext)::get_class_type())) {
|
||||
// The previous shader was a Cg shader, which can leave a messy
|
||||
// situation.
|
||||
_vertex_array_shader_context->disable_shader_vertex_arrays();
|
||||
}
|
||||
else if (_vertex_array_shader_context->is_of_type(CLP(CgShaderContext)::get_class_type())) {
|
||||
// The previous shader was a Cg shader, which can leave a messy
|
||||
// situation.
|
||||
_vertex_array_shader_context->disable_shader_vertex_arrays();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // SUPPORT_FIXED_FUNCTION
|
||||
// Now update the vertex arrays for the current shader.
|
||||
if (!_current_shader_context->
|
||||
|
|
@ -4334,7 +4355,9 @@ unbind_buffers() {
|
|||
#endif
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
disable_standard_vertex_arrays();
|
||||
if (has_fixed_function_pipeline()) {
|
||||
disable_standard_vertex_arrays();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -5040,7 +5063,7 @@ draw_points(const GeomPrimitivePipelineReader *reader, bool force) {
|
|||
void CLP(GraphicsStateGuardian)::
|
||||
end_draw_primitives() {
|
||||
#if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
|
||||
if (_geom_display_list != 0) {
|
||||
if (has_fixed_function_pipeline() && _geom_display_list != 0) {
|
||||
// If we were building a display list, close it now.
|
||||
glEndList();
|
||||
_load_display_list_pcollector.stop();
|
||||
|
|
@ -5054,12 +5077,12 @@ end_draw_primitives() {
|
|||
#endif
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
if (_transform_stale) {
|
||||
if (has_fixed_function_pipeline() && _transform_stale) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
call_glLoadMatrix(_internal_transform->get_mat());
|
||||
}
|
||||
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
if (has_fixed_function_pipeline() && _data_reader->is_vertex_transformed()) {
|
||||
// Restore the matrices that we pushed above.
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
|
@ -5436,7 +5459,9 @@ prepare_geom(Geom *geom) {
|
|||
void CLP(GraphicsStateGuardian)::
|
||||
release_geom(GeomContext *gc) {
|
||||
CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
|
||||
ggc->release_display_lists();
|
||||
if (has_fixed_function_pipeline()) {
|
||||
ggc->release_display_lists();
|
||||
}
|
||||
report_my_gl_errors();
|
||||
|
||||
delete ggc;
|
||||
|
|
@ -6594,17 +6619,19 @@ apply_fog(Fog *fog) {
|
|||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_transform() {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
// OpenGL ES 2 does not support glLoadMatrix.
|
||||
if (has_fixed_function_pipeline()) {
|
||||
// OpenGL ES 2 does not support glLoadMatrix.
|
||||
|
||||
const TransformState *transform = _internal_transform;
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
|
||||
const TransformState *transform = _internal_transform;
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
|
||||
}
|
||||
|
||||
DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
call_glLoadMatrix(transform->get_mat());
|
||||
}
|
||||
|
||||
DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
call_glLoadMatrix(transform->get_mat());
|
||||
#endif
|
||||
_transform_stale = false;
|
||||
|
||||
|
|
@ -6643,13 +6670,11 @@ do_issue_shader() {
|
|||
ShaderContext *context = 0;
|
||||
Shader *shader = (Shader *)_target_shader->get_shader();
|
||||
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
// If we don't have a shader, apply the default shader.
|
||||
if (!shader) {
|
||||
if (!has_fixed_function_pipeline() && !shader) {
|
||||
shader = _default_shader;
|
||||
nassertv(shader != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (shader) {
|
||||
if (_current_shader != shader) {
|
||||
|
|
@ -6659,9 +6684,9 @@ do_issue_shader() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
// If it failed, try applying the default shader.
|
||||
if (shader != _default_shader && (context == 0 || !context->valid())) {
|
||||
if (_default_shader != nullptr && shader != _default_shader &&
|
||||
(context == 0 || !context->valid())) {
|
||||
shader = _default_shader;
|
||||
nassertv(shader != NULL);
|
||||
if (_current_shader != shader) {
|
||||
|
|
@ -6670,7 +6695,6 @@ do_issue_shader() {
|
|||
context = _current_shader_context;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (context == 0 || !context->valid()) {
|
||||
if (_current_shader_context != 0) {
|
||||
|
|
@ -6762,7 +6786,9 @@ do_issue_render_mode() {
|
|||
report_my_gl_errors();
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
do_point_size();
|
||||
if (has_fixed_function_pipeline()) {
|
||||
do_point_size();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -7372,6 +7398,8 @@ do_issue_blending() {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector
|
||||
// _draw_set_state_light_bind_point_pcollector("Draw:Set
|
||||
// State:Light:Bind:Point"); PStatGPUTimer timer(this,
|
||||
|
|
@ -7416,6 +7444,8 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector
|
||||
// _draw_set_state_light_bind_directional_pcollector("Draw:Set
|
||||
// State:Light:Bind:Directional"); PStatGPUTimer timer(this,
|
||||
|
|
@ -7467,6 +7497,8 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector
|
||||
// _draw_set_state_light_bind_spotlight_pcollector("Draw:Set
|
||||
// State:Light:Bind:Spotlight"); PStatGPUTimer timer(this,
|
||||
|
|
@ -8701,10 +8733,10 @@ get_external_image_format(Texture *tex) const {
|
|||
#endif
|
||||
|
||||
case Texture::F_alpha:
|
||||
#if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
|
||||
#ifdef OPENGLES
|
||||
return GL_ALPHA;
|
||||
#else
|
||||
return GL_RED;
|
||||
return _supports_luminance_texture ? GL_ALPHA : GL_RED;
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
|
|
@ -8744,18 +8776,18 @@ get_external_image_format(Texture *tex) const {
|
|||
|
||||
case Texture::F_luminance:
|
||||
case Texture::F_sluminance:
|
||||
#if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
|
||||
#ifdef OPENGLES
|
||||
return GL_LUMINANCE;
|
||||
#else
|
||||
return GL_RED;
|
||||
return _supports_luminance_texture ? GL_LUMINANCE : GL_RED;
|
||||
#endif
|
||||
case Texture::F_luminance_alphamask:
|
||||
case Texture::F_luminance_alpha:
|
||||
case Texture::F_sluminance_alpha:
|
||||
#if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
|
||||
#ifdef OPENGLES
|
||||
return GL_LUMINANCE_ALPHA;
|
||||
#else
|
||||
return GL_RG;
|
||||
return _supports_luminance_texture ? GL_LUMINANCE_ALPHA : GL_RG;
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
|
|
@ -9402,42 +9434,76 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
#endif
|
||||
|
||||
case Texture::F_alpha:
|
||||
#if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
|
||||
#ifdef OPENGLES
|
||||
return force_sized ? GL_ALPHA8 : GL_ALPHA;
|
||||
#else
|
||||
return force_sized ? GL_R8 : GL_RED;
|
||||
if (_supports_luminance_texture) {
|
||||
return force_sized ? GL_ALPHA8 : GL_ALPHA;
|
||||
} else {
|
||||
return force_sized ? GL_R8 : GL_RED;
|
||||
}
|
||||
#endif
|
||||
|
||||
case Texture::F_luminance:
|
||||
#if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
|
||||
#ifndef OPENGLES
|
||||
if (tex->get_component_type() == Texture::T_float) {
|
||||
return GL_LUMINANCE16F_ARB;
|
||||
} else if (tex->get_component_type() == Texture::T_short) {
|
||||
return GL_LUMINANCE16_SNORM;
|
||||
} else if (tex->get_component_type() == Texture::T_unsigned_short) {
|
||||
return GL_LUMINANCE16;
|
||||
} else
|
||||
#endif // OPENGLES
|
||||
{
|
||||
return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
|
||||
}
|
||||
#ifdef OPENGLES
|
||||
return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
|
||||
#else
|
||||
return force_sized ? GL_R8 : GL_RED;
|
||||
if (_supports_luminance_texture) {
|
||||
switch (tex->get_component_type()) {
|
||||
case Texture::T_float:
|
||||
case Texture::T_half_float:
|
||||
return GL_LUMINANCE16F_ARB;
|
||||
case Texture::T_short:
|
||||
return GL_LUMINANCE16_SNORM;
|
||||
case Texture::T_unsigned_short:
|
||||
return GL_LUMINANCE16;
|
||||
default:
|
||||
return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
|
||||
}
|
||||
} else {
|
||||
switch (tex->get_component_type()) {
|
||||
case Texture::T_float:
|
||||
case Texture::T_half_float:
|
||||
return GL_R16F;
|
||||
case Texture::T_short:
|
||||
return GL_R16_SNORM;
|
||||
case Texture::T_unsigned_short:
|
||||
return GL_R16;
|
||||
default:
|
||||
return force_sized ? GL_R8 : GL_RED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
case Texture::F_luminance_alpha:
|
||||
case Texture::F_luminance_alphamask:
|
||||
#if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
|
||||
#ifndef OPENGLES
|
||||
if (tex->get_component_type() == Texture::T_float || tex->get_component_type() == Texture::T_unsigned_short) {
|
||||
return GL_LUMINANCE_ALPHA16F_ARB;
|
||||
} else
|
||||
#endif // OPENGLES
|
||||
{
|
||||
return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
|
||||
}
|
||||
#ifdef OPENGLES
|
||||
return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
|
||||
#else
|
||||
return force_sized ? GL_RG8 : GL_RG;
|
||||
if (_supports_luminance_texture) {
|
||||
switch (tex->get_component_type()) {
|
||||
case Texture::T_float:
|
||||
case Texture::T_half_float:
|
||||
return GL_LUMINANCE_ALPHA16F_ARB;
|
||||
case Texture::T_short:
|
||||
return GL_LUMINANCE16_SNORM;
|
||||
case Texture::T_unsigned_short:
|
||||
return GL_LUMINANCE16_ALPHA16;
|
||||
default:
|
||||
return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
|
||||
}
|
||||
} else {
|
||||
switch (tex->get_component_type()) {
|
||||
case Texture::T_float:
|
||||
case Texture::T_half_float:
|
||||
return GL_RG16F;
|
||||
case Texture::T_short:
|
||||
return GL_RG16_SNORM;
|
||||
case Texture::T_unsigned_short:
|
||||
return GL_RG16;
|
||||
default:
|
||||
return force_sized ? GL_RG8 : GL_RG;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
|
|
@ -10019,6 +10085,8 @@ reissue_transforms() {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
enable_lighting(bool enable) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector
|
||||
// _draw_set_state_light_enable_lighting_pcollector("Draw:Set
|
||||
// State:Light:Enable lighting"); PStatGPUTimer timer(this,
|
||||
|
|
@ -10040,6 +10108,8 @@ enable_lighting(bool enable) {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
set_ambient_light(const LColor &color) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set
|
||||
// State:Light:Ambient"); PStatGPUTimer timer(this,
|
||||
// _draw_set_state_light_ambient_pcollector);
|
||||
|
|
@ -10061,6 +10131,8 @@ set_ambient_light(const LColor &color) {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
enable_light(int light_id, bool enable) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector
|
||||
// _draw_set_state_light_enable_light_pcollector("Draw:Set
|
||||
// State:Light:Enable light"); PStatGPUTimer timer(this,
|
||||
|
|
@ -10085,6 +10157,8 @@ enable_light(int light_id, bool enable) {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
begin_bind_lights() {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector
|
||||
// _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin
|
||||
// bind"); PStatGPUTimer timer(this,
|
||||
|
|
@ -10115,6 +10189,8 @@ begin_bind_lights() {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
end_bind_lights() {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set
|
||||
// State:Light:End bind"); PStatGPUTimer timer(this,
|
||||
// _draw_set_state_light_end_bind_pcollector);
|
||||
|
|
@ -10132,6 +10208,8 @@ end_bind_lights() {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
enable_clip_plane(int plane_id, bool enable) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
if (enable) {
|
||||
glEnable(get_clip_plane_id(plane_id));
|
||||
} else {
|
||||
|
|
@ -10151,6 +10229,8 @@ enable_clip_plane(int plane_id, bool enable) {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
begin_bind_clip_planes() {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
// We need to temporarily load a new matrix so we can define the clip_plane
|
||||
// in a known coordinate system. We pick the transform of the root.
|
||||
// (Alternatively, we could leave the current transform where it is and
|
||||
|
|
@ -10175,6 +10255,8 @@ begin_bind_clip_planes() {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
bind_clip_plane(const NodePath &plane, int plane_id) {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
GLenum id = get_clip_plane_id(plane_id);
|
||||
|
||||
CPT(TransformState) transform = plane.get_transform(_scene_setup->get_scene_root().get_parent());
|
||||
|
|
@ -10205,6 +10287,8 @@ bind_clip_plane(const NodePath &plane, int plane_id) {
|
|||
*/
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
end_bind_clip_planes() {
|
||||
nassertv(has_fixed_function_pipeline());
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
|
@ -10259,12 +10343,10 @@ set_state_and_transform(const RenderState *target,
|
|||
_state_shader = _target_shader;
|
||||
_state_mask.clear_bit(TextureAttrib::get_class_slot());
|
||||
}
|
||||
#ifndef SUPPORT_FIXED_FUNCTION
|
||||
else if (_current_shader == NULL) { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
|
||||
else if (!has_fixed_function_pipeline() && _current_shader == NULL) { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
|
||||
do_issue_shader();
|
||||
_state_mask.clear_bit(TextureAttrib::get_class_slot());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Update all of the state that is bound to the shader program.
|
||||
if (_current_shader_context != NULL) {
|
||||
|
|
@ -10273,17 +10355,19 @@ set_state_and_transform(const RenderState *target,
|
|||
#endif
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
int alpha_test_slot = AlphaTestAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
|
||||
!_state_mask.get_bit(alpha_test_slot)
|
||||
if (has_fixed_function_pipeline()) {
|
||||
int alpha_test_slot = AlphaTestAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
|
||||
!_state_mask.get_bit(alpha_test_slot)
|
||||
#ifndef OPENGLES_1
|
||||
|| (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) !=
|
||||
_state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))
|
||||
|| (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) !=
|
||||
_state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))
|
||||
#endif
|
||||
) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_alpha_test_pcollector);
|
||||
do_issue_alpha_test();
|
||||
_state_mask.set_bit(alpha_test_slot);
|
||||
) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_alpha_test_pcollector);
|
||||
do_issue_alpha_test();
|
||||
_state_mask.set_bit(alpha_test_slot);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -10357,22 +10441,22 @@ set_state_and_transform(const RenderState *target,
|
|||
}
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
|
||||
!_state_mask.get_bit(rescale_normal_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_rescale_normal_pcollector);
|
||||
do_issue_rescale_normal();
|
||||
_state_mask.set_bit(rescale_normal_slot);
|
||||
}
|
||||
#endif
|
||||
if (has_fixed_function_pipeline()) {
|
||||
int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
|
||||
!_state_mask.get_bit(rescale_normal_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_rescale_normal_pcollector);
|
||||
do_issue_rescale_normal();
|
||||
_state_mask.set_bit(rescale_normal_slot);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
int shade_model_slot = ShadeModelAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
|
||||
!_state_mask.get_bit(shade_model_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_shade_model_pcollector);
|
||||
do_issue_shade_model();
|
||||
_state_mask.set_bit(shade_model_slot);
|
||||
int shade_model_slot = ShadeModelAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
|
||||
!_state_mask.get_bit(shade_model_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_shade_model_pcollector);
|
||||
do_issue_shade_model();
|
||||
_state_mask.set_bit(shade_model_slot);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -10444,7 +10528,9 @@ set_state_and_transform(const RenderState *target,
|
|||
!_state_mask.get_bit(tex_matrix_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector);
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
do_issue_tex_matrix();
|
||||
if (has_fixed_function_pipeline()) {
|
||||
do_issue_tex_matrix();
|
||||
}
|
||||
#endif
|
||||
_state_mask.set_bit(tex_matrix_slot);
|
||||
#ifndef OPENGLES_1
|
||||
|
|
@ -10455,35 +10541,41 @@ set_state_and_transform(const RenderState *target,
|
|||
}
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
int tex_gen_slot = TexGenAttrib::get_class_slot();
|
||||
if (_target_tex_gen != _state_tex_gen ||
|
||||
!_state_mask.get_bit(tex_gen_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_tex_gen_pcollector);
|
||||
do_issue_tex_gen();
|
||||
_state_tex_gen = _target_tex_gen;
|
||||
_state_mask.set_bit(tex_gen_slot);
|
||||
}
|
||||
#endif
|
||||
if (has_fixed_function_pipeline()) {
|
||||
int tex_gen_slot = TexGenAttrib::get_class_slot();
|
||||
if (_target_tex_gen != _state_tex_gen ||
|
||||
!_state_mask.get_bit(tex_gen_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_tex_gen_pcollector);
|
||||
do_issue_tex_gen();
|
||||
_state_tex_gen = _target_tex_gen;
|
||||
_state_mask.set_bit(tex_gen_slot);
|
||||
}
|
||||
|
||||
int material_slot = MaterialAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
|
||||
!_state_mask.get_bit(material_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_material_pcollector);
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
do_issue_material();
|
||||
#endif
|
||||
_state_mask.set_bit(material_slot);
|
||||
}
|
||||
int material_slot = MaterialAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
|
||||
!_state_mask.get_bit(material_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_material_pcollector);
|
||||
do_issue_material();
|
||||
_state_mask.set_bit(material_slot);
|
||||
}
|
||||
|
||||
int light_slot = LightAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
|
||||
!_state_mask.get_bit(light_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_light_pcollector);
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
do_issue_light();
|
||||
#endif
|
||||
_state_mask.set_bit(light_slot);
|
||||
int light_slot = LightAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
|
||||
!_state_mask.get_bit(light_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_light_pcollector);
|
||||
do_issue_light();
|
||||
_state_mask.set_bit(light_slot);
|
||||
}
|
||||
|
||||
int fog_slot = FogAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
|
||||
!_state_mask.get_bit(fog_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_fog_pcollector);
|
||||
do_issue_fog();
|
||||
_state_mask.set_bit(fog_slot);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int stencil_slot = StencilAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
|
||||
|
|
@ -10493,16 +10585,6 @@ set_state_and_transform(const RenderState *target,
|
|||
_state_mask.set_bit(stencil_slot);
|
||||
}
|
||||
|
||||
int fog_slot = FogAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
|
||||
!_state_mask.get_bit(fog_slot)) {
|
||||
// PStatGPUTimer timer(this, _draw_set_state_fog_pcollector);
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
do_issue_fog();
|
||||
#endif
|
||||
_state_mask.set_bit(fog_slot);
|
||||
}
|
||||
|
||||
int scissor_slot = ScissorAttrib::get_class_slot();
|
||||
if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
|
||||
!_state_mask.get_bit(scissor_slot)) {
|
||||
|
|
@ -10546,12 +10628,16 @@ do_issue_texture() {
|
|||
_texture_binding_shader_context->disable_shader_texture_bindings();
|
||||
}
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
update_standard_texture_bindings();
|
||||
if (has_fixed_function_pipeline()) {
|
||||
update_standard_texture_bindings();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (_texture_binding_shader_context == 0) {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
disable_standard_texture_bindings();
|
||||
if (has_fixed_function_pipeline()) {
|
||||
disable_standard_texture_bindings();
|
||||
}
|
||||
#endif
|
||||
_current_shader_context->update_shader_texture_bindings(NULL);
|
||||
} else {
|
||||
|
|
@ -10881,20 +10967,22 @@ update_show_usage_texture_bindings(int show_stage_index) {
|
|||
}
|
||||
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
// Disable all texture stages.
|
||||
for (i = 0; i < _num_active_texture_stages; i++) {
|
||||
set_active_texture_stage(i);
|
||||
if (has_fixed_function_pipeline()) {
|
||||
// Disable all texture stages.
|
||||
for (i = 0; i < _num_active_texture_stages; i++) {
|
||||
set_active_texture_stage(i);
|
||||
#ifndef OPENGLES
|
||||
glDisable(GL_TEXTURE_1D);
|
||||
glDisable(GL_TEXTURE_1D);
|
||||
#endif // OPENGLES
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (_supports_3d_texture) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (_supports_3d_texture) {
|
||||
#ifndef OPENGLES_1
|
||||
glDisable(GL_TEXTURE_3D);
|
||||
glDisable(GL_TEXTURE_3D);
|
||||
#endif // OPENGLES_1
|
||||
}
|
||||
if (_supports_cube_map) {
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
}
|
||||
if (_supports_cube_map) {
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -10917,7 +11005,9 @@ update_show_usage_texture_bindings(int show_stage_index) {
|
|||
// Choose the corresponding usage texture and apply it.
|
||||
set_active_texture_stage(i);
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
if (has_fixed_function_pipeline()) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
#endif
|
||||
|
||||
UsageTextureKey key(texture->get_x_size(), texture->get_y_size());
|
||||
|
|
@ -11445,7 +11535,9 @@ specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
|
|||
tex->get_format() == Texture::F_depth_component24 ||
|
||||
tex->get_format() == Texture::F_depth_component32) {
|
||||
#ifdef SUPPORT_FIXED_FUNCTION
|
||||
glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
|
||||
if (has_fixed_function_pipeline()) {
|
||||
glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
|
||||
}
|
||||
#endif
|
||||
if (_supports_shadow_filter) {
|
||||
if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
|
||||
|
|
@ -11893,33 +11985,35 @@ upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !defined(SUPPORT_FIXED_FUNCTION) && !defined(OPENGLES)
|
||||
// Do we need to apply a swizzle mask to emulate these deprecated texture
|
||||
// formats?
|
||||
switch (tex->get_format()) {
|
||||
case Texture::F_alpha:
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_ZERO);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_RED);
|
||||
break;
|
||||
#ifndef OPENGLES
|
||||
if (!_supports_luminance_texture) {
|
||||
// Do we need to apply a swizzle mask to emulate these deprecated texture
|
||||
// formats?
|
||||
switch (tex->get_format()) {
|
||||
case Texture::F_alpha:
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_ZERO);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_RED);
|
||||
break;
|
||||
|
||||
case Texture::F_luminance:
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
break;
|
||||
case Texture::F_luminance:
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
break;
|
||||
|
||||
case Texture::F_luminance_alpha:
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
|
||||
break;
|
||||
case Texture::F_luminance_alpha:
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -12676,9 +12770,8 @@ get_texture_memory_size(CLP(TextureContext) *gtc) {
|
|||
}
|
||||
|
||||
// OK, get the noncompressed size.
|
||||
GLint red_size, green_size, blue_size, alpha_size,
|
||||
luminance_size, intensity_size;
|
||||
GLint depth_size = 0;
|
||||
GLint red_size, green_size, blue_size, alpha_size;
|
||||
GLint depth_size = 0, luminance_size = 0, intensity_size = 0;
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_RED_SIZE, &red_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
|
|
@ -12687,11 +12780,13 @@ get_texture_memory_size(CLP(TextureContext) *gtc) {
|
|||
GL_TEXTURE_BLUE_SIZE, &blue_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
||||
if (_supports_depth_texture) {
|
||||
if (get_supports_luminance_texture()) {
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
|
||||
}
|
||||
if (get_supports_depth_texture()) {
|
||||
glGetTexLevelParameteriv(page_target, 0,
|
||||
GL_TEXTURE_DEPTH_SIZE, &depth_size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ public:
|
|||
INLINE const string &get_gl_version() const;
|
||||
INLINE int get_gl_version_major() const;
|
||||
INLINE int get_gl_version_minor() const;
|
||||
INLINE bool has_fixed_function_pipeline() const;
|
||||
|
||||
virtual void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *transform);
|
||||
|
|
@ -719,6 +720,11 @@ protected:
|
|||
|
||||
pset<string> _extensions;
|
||||
|
||||
#ifndef OPENGLES
|
||||
// True for non-compatibility GL 3.2+ contexts.
|
||||
bool _core_profile;
|
||||
#endif
|
||||
|
||||
public:
|
||||
bool _supports_point_parameters;
|
||||
PFNGLPOINTPARAMETERFVPROC _glPointParameterfv;
|
||||
|
|
|
|||
|
|
@ -261,8 +261,8 @@ public:
|
|||
|
||||
INLINE Thread *get_current_thread() const;
|
||||
|
||||
INLINE const unsigned char *get_read_pointer(bool force) const;
|
||||
unsigned char *get_write_pointer();
|
||||
INLINE const unsigned char *get_read_pointer(bool force) const RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
unsigned char *get_write_pointer() RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE const GeomVertexArrayData *get_object() const;
|
||||
|
|
|
|||
|
|
@ -67,17 +67,22 @@ INLINE const unsigned char *VertexDataBuffer::
|
|||
get_read_pointer(bool force) const {
|
||||
LightMutexHolder holder(_lock);
|
||||
|
||||
const unsigned char *ptr;
|
||||
if (_resident_data != (unsigned char *)NULL || _size == 0) {
|
||||
return _resident_data;
|
||||
ptr = _resident_data;
|
||||
} else {
|
||||
nassertr(_block != (VertexDataBlock *)NULL, NULL);
|
||||
nassertr(_reserved_size >= _size, NULL);
|
||||
|
||||
// We don't necessarily need to page the buffer all the way into independent
|
||||
// status; it's sufficient just to return the block's pointer, which will
|
||||
// force its page to resident status.
|
||||
ptr = _block->get_pointer(force);
|
||||
}
|
||||
|
||||
nassertr(_block != (VertexDataBlock *)NULL, NULL);
|
||||
nassertr(_reserved_size >= _size, NULL);
|
||||
|
||||
// We don't necessarily need to page the buffer all the way into independent
|
||||
// status; it's sufficient just to return the block's pointer, which will
|
||||
// force its page to resident status.
|
||||
return _block->get_pointer(force);
|
||||
#ifdef _DEBUG
|
||||
assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
|
||||
#endif
|
||||
return (const unsigned char *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,7 +96,10 @@ get_write_pointer() {
|
|||
do_page_in();
|
||||
}
|
||||
nassertr(_reserved_size >= _size, NULL);
|
||||
return _resident_data;
|
||||
#ifdef _DEBUG
|
||||
assert(((uintptr_t)_resident_data % MEMORY_HOOK_ALIGNMENT) == 0);
|
||||
#endif
|
||||
return (unsigned char *)ASSUME_ALIGNED(_resident_data, MEMORY_HOOK_ALIGNMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,15 +27,13 @@ operator = (const VertexDataBuffer ©) {
|
|||
|
||||
if (_resident_data != (unsigned char *)NULL) {
|
||||
nassertv(_reserved_size != 0);
|
||||
get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_reserved_size);
|
||||
PANDA_FREE_ARRAY(_resident_data);
|
||||
get_class_type().deallocate_array(_resident_data);
|
||||
_resident_data = NULL;
|
||||
}
|
||||
if (copy._resident_data != (unsigned char *)NULL && copy._size != 0) {
|
||||
// We only allocate _size bytes, not the full _reserved_size allocated by
|
||||
// the original copy.
|
||||
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)copy._size);
|
||||
_resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(copy._size);
|
||||
_resident_data = (unsigned char *)get_class_type().allocate_array(copy._size);
|
||||
memcpy(_resident_data, copy._resident_data, copy._size);
|
||||
}
|
||||
_size = copy._size;
|
||||
|
|
@ -55,17 +53,16 @@ swap(VertexDataBuffer &other) {
|
|||
unsigned char *resident_data = _resident_data;
|
||||
size_t size = _size;
|
||||
size_t reserved_size = _reserved_size;
|
||||
PT(VertexDataBlock) block = _block;
|
||||
|
||||
_block.swap(other._block);
|
||||
|
||||
_resident_data = other._resident_data;
|
||||
_size = other._size;
|
||||
_reserved_size = other._reserved_size;
|
||||
_block = other._block;
|
||||
|
||||
other._resident_data = resident_data;
|
||||
other._size = size;
|
||||
other._reserved_size = reserved_size;
|
||||
other._block = block;
|
||||
nassertv(_reserved_size >= _size);
|
||||
}
|
||||
|
||||
|
|
@ -94,13 +91,12 @@ do_clean_realloc(size_t reserved_size) {
|
|||
do_page_in();
|
||||
}
|
||||
|
||||
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)reserved_size - (int)_reserved_size);
|
||||
if (_reserved_size == 0) {
|
||||
nassertv(_resident_data == (unsigned char *)NULL);
|
||||
_resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(reserved_size);
|
||||
_resident_data = (unsigned char *)get_class_type().allocate_array(reserved_size);
|
||||
} else {
|
||||
nassertv(_resident_data != (unsigned char *)NULL);
|
||||
_resident_data = (unsigned char *)PANDA_REALLOC_ARRAY(_resident_data, reserved_size);
|
||||
_resident_data = (unsigned char *)get_class_type().reallocate_array(_resident_data, reserved_size);
|
||||
}
|
||||
nassertv(_resident_data != (unsigned char *)NULL);
|
||||
_reserved_size = reserved_size;
|
||||
|
|
@ -129,16 +125,14 @@ do_unclean_realloc(size_t reserved_size) {
|
|||
if (_resident_data != (unsigned char *)NULL) {
|
||||
nassertv(_reserved_size != 0);
|
||||
|
||||
get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_reserved_size);
|
||||
PANDA_FREE_ARRAY(_resident_data);
|
||||
get_class_type().deallocate_array(_resident_data);
|
||||
_resident_data = NULL;
|
||||
_reserved_size = 0;
|
||||
}
|
||||
|
||||
if (reserved_size != 0) {
|
||||
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)reserved_size);
|
||||
nassertv(_resident_data == (unsigned char *)NULL);
|
||||
_resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(reserved_size);
|
||||
_resident_data = (unsigned char *)get_class_type().allocate_array(reserved_size);
|
||||
}
|
||||
|
||||
_reserved_size = reserved_size;
|
||||
|
|
@ -166,8 +160,7 @@ do_page_out(VertexDataBook &book) {
|
|||
if (_size == 0) {
|
||||
// It's an empty buffer. Just deallocate it; don't bother to create a
|
||||
// block.
|
||||
get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_reserved_size);
|
||||
PANDA_FREE_ARRAY(_resident_data);
|
||||
get_class_type().deallocate_array(_resident_data);
|
||||
_resident_data = NULL;
|
||||
_reserved_size = 0;
|
||||
|
||||
|
|
@ -180,8 +173,7 @@ do_page_out(VertexDataBook &book) {
|
|||
nassertv(pointer != (unsigned char *)NULL);
|
||||
memcpy(pointer, _resident_data, _size);
|
||||
|
||||
get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_reserved_size);
|
||||
PANDA_FREE_ARRAY(_resident_data);
|
||||
get_class_type().deallocate_array(_resident_data);
|
||||
_resident_data = NULL;
|
||||
|
||||
_reserved_size = _size;
|
||||
|
|
@ -205,8 +197,7 @@ do_page_in() {
|
|||
nassertv(_block != (VertexDataBlock *)NULL);
|
||||
nassertv(_reserved_size == _size);
|
||||
|
||||
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)_size);
|
||||
_resident_data = (unsigned char *)PANDA_MALLOC_ARRAY(_size);
|
||||
_resident_data = (unsigned char *)get_class_type().allocate_array(_size);
|
||||
nassertv(_resident_data != (unsigned char *)NULL);
|
||||
|
||||
memcpy(_resident_data, _block->get_pointer(true), _size);
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ public:
|
|||
void operator = (const VertexDataBuffer ©);
|
||||
INLINE ~VertexDataBuffer();
|
||||
|
||||
INLINE const unsigned char *get_read_pointer(bool force) const;
|
||||
INLINE unsigned char *get_write_pointer();
|
||||
INLINE const unsigned char *get_read_pointer(bool force) const RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
INLINE unsigned char *get_write_pointer() RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
|
||||
INLINE size_t get_size() const;
|
||||
INLINE size_t get_reserved_size() const;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
TypeHandle MeshDrawer::_type_handle;
|
||||
|
||||
PN_stdfloat randFloat() {
|
||||
return ((PN_stdfloat) rand() / (PN_stdfloat) 0x7fffffff);
|
||||
return ((PN_stdfloat)rand() / (PN_stdfloat)RAND_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,39 +42,43 @@ PN_stdfloat randFloat() {
|
|||
void MeshDrawer::generator(int budget) {
|
||||
// create enough triangles for budget:
|
||||
_vdata = new GeomVertexData(_root.get_name(), GeomVertexFormat::get_v3n3c4t2(), Geom::UH_static);//UH_dynamic);
|
||||
GeomVertexWriter *tvertex = new GeomVertexWriter(_vdata, "vertex");
|
||||
GeomVertexWriter *tnormal = new GeomVertexWriter(_vdata, "normal");
|
||||
GeomVertexWriter *tuv = new GeomVertexWriter(_vdata, "texcoord");
|
||||
GeomVertexWriter *tcolor = new GeomVertexWriter(_vdata, "color");
|
||||
_prim = new GeomTriangles(Geom::UH_static);
|
||||
_vdata->unclean_set_num_rows(budget * 3);
|
||||
|
||||
// iterate and fill _up a geom with random data so that it will not be
|
||||
// optimized out by panda3d system
|
||||
for(int i = 0; i < budget; i++) {
|
||||
for( int vert = 0; vert < 3; vert++) {
|
||||
LVector3 vec3 = LVector3(randFloat()+1000,randFloat(),randFloat())*.001;
|
||||
LVector4 vec4 = LVector4(1,1,1,randFloat());
|
||||
LVector2 vec2 = LVector2(0,randFloat());
|
||||
tvertex->add_data3(vec3);
|
||||
tcolor->add_data4(vec4);
|
||||
tuv->add_data2(vec2);
|
||||
tnormal->add_data3(vec3);
|
||||
{
|
||||
GeomVertexWriter tvertex(_vdata, "vertex");
|
||||
GeomVertexWriter tnormal(_vdata, "normal");
|
||||
GeomVertexWriter tuv(_vdata, "texcoord");
|
||||
GeomVertexWriter tcolor(_vdata, "color");
|
||||
|
||||
// iterate and fill _up a geom with random data so that it will not be
|
||||
// optimized out by panda3d system
|
||||
for (int i = 0; i < budget; i++) {
|
||||
for (int vert = 0; vert < 3; vert++) {
|
||||
LVector3 vec3 = LVector3(randFloat()+1000,randFloat(),randFloat())*.001;
|
||||
LVector4 vec4 = LVector4(1,1,1,randFloat());
|
||||
LVector2 vec2 = LVector2(0,randFloat());
|
||||
tvertex.set_data3(vec3);
|
||||
tcolor.set_data4(vec4);
|
||||
tuv.set_data2(vec2);
|
||||
tnormal.set_data3(vec3);
|
||||
}
|
||||
}
|
||||
_prim->add_vertices(i * 3, i * 3 + 1, i * 3 + 2);
|
||||
}
|
||||
|
||||
// create our node and attach it to this node path
|
||||
_prim = new GeomTriangles(Geom::UH_static);
|
||||
_prim->add_next_vertices(budget * 3);
|
||||
_prim->close_primitive();
|
||||
_geom = new Geom(_vdata);
|
||||
_geom->add_primitive(_prim);
|
||||
_geomnode = new GeomNode("__MeshDrawer_GeomNode");
|
||||
if (_geomnode == NULL) {
|
||||
_geomnode = new GeomNode("__MeshDrawer_GeomNode");
|
||||
_root.attach_new_node(_geomnode);
|
||||
} else {
|
||||
_geomnode->remove_all_geoms();
|
||||
}
|
||||
_geomnode->add_geom(_geom);
|
||||
_root.attach_new_node(_geomnode);
|
||||
_last_clear_index = budget;
|
||||
|
||||
delete tvertex;
|
||||
delete tnormal;
|
||||
delete tuv;
|
||||
delete tcolor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -451,8 +455,9 @@ link_segment(const LVector3 &pos, const LVector4 &frame,
|
|||
LVector3 cam_stop3d = _camera.get_relative_point(_render, stop);
|
||||
LPoint2 cam_stop2d = LVector2();
|
||||
|
||||
PT(Camera) camera = DCAST(Camera, _camera.node());
|
||||
PT(Lens) lens = camera->get_lens();
|
||||
const Camera *camera;
|
||||
DCAST_INTO_V(camera, _camera.node());
|
||||
const Lens *lens = camera->get_lens();
|
||||
|
||||
lens->project(cam_start3d, cam_start2d);
|
||||
lens->project(cam_stop3d, cam_stop2d);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ private:
|
|||
#endif // HAVE_EIGEN
|
||||
|
||||
// This is as good a place as any to define this alignment macro.
|
||||
#if defined(LINMATH_ALIGN) && defined(HAVE_EIGEN) && defined(__AVX__)
|
||||
#if defined(LINMATH_ALIGN) && defined(HAVE_EIGEN) && defined(__AVX__) && defined(STDFLOAT_DOUBLE)
|
||||
#define ALIGN_LINMATH ALIGN_32BYTE
|
||||
#elif defined(LINMATH_ALIGN)
|
||||
#define ALIGN_LINMATH ALIGN_16BYTE
|
||||
|
|
|
|||
|
|
@ -163,7 +163,9 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "HermiteCurve");
|
||||
PiecewiseCurve::init_type();
|
||||
register_type(_type_handle, "HermiteCurve",
|
||||
PiecewiseCurve::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
* @date 2001-03-04
|
||||
*/
|
||||
|
||||
#ifndef NODEPATHCOLLECTION_H
|
||||
#define NODEPATHCOLLECTION_H
|
||||
#ifndef PARAMETRICCURVECOLLECTION_H
|
||||
#define PARAMETRICCURVECOLLECTION_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -659,6 +659,8 @@ PUBLISHED:
|
|||
INLINE void set_shader_input(CPT_InternalName id, PN_stdfloat n1, PN_stdfloat n2=0,
|
||||
PN_stdfloat n3=0, PN_stdfloat n4=0, int priority=0);
|
||||
|
||||
EXTENSION(void set_shader_inputs(PyObject *args, PyObject *kwargs));
|
||||
|
||||
void clear_shader_input(CPT_InternalName id);
|
||||
void set_instance_count(int instance_count);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "nodePath_ext.h"
|
||||
#include "typedWritable_ext.h"
|
||||
#include "shaderAttrib.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
|
|
@ -24,6 +25,35 @@ extern struct Dtool_PyTypedObject Dtool_LPoint3d;
|
|||
#else
|
||||
extern struct Dtool_PyTypedObject Dtool_LPoint3f;
|
||||
#endif
|
||||
extern struct Dtool_PyTypedObject Dtool_Texture;
|
||||
extern struct Dtool_PyTypedObject Dtool_NodePath;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_float;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_double;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_int;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4i;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3i;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2i;
|
||||
extern struct Dtool_PyTypedObject Dtool_ShaderBuffer;
|
||||
extern struct Dtool_PyTypedObject Dtool_ParamValueBase;
|
||||
#endif // CPPPARSER
|
||||
|
||||
/**
|
||||
|
|
@ -211,6 +241,192 @@ py_decode_NodePath_from_bam_stream_persist(PyObject *unpickler, const string &da
|
|||
return NodePath::decode_from_bam_stream(data, reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple shader inputs at the same time. This can be significantly
|
||||
* more efficient if many inputs need to be set at the same time.
|
||||
*/
|
||||
void Extension<NodePath>::
|
||||
set_shader_inputs(PyObject *args, PyObject *kwargs) {
|
||||
if (PyObject_Size(args) > 0) {
|
||||
Dtool_Raise_TypeError("NodePath.set_shader_inputs takes only keyword arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
PT(PandaNode) node = _this->node();
|
||||
CPT(RenderAttrib) prev_attrib = node->get_attrib(ShaderAttrib::get_class_slot());
|
||||
PT(ShaderAttrib) attrib;
|
||||
if (prev_attrib == nullptr) {
|
||||
attrib = new ShaderAttrib();
|
||||
} else {
|
||||
attrib = new ShaderAttrib(*(const ShaderAttrib *)prev_attrib.p());
|
||||
}
|
||||
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
while (PyDict_Next(kwargs, &pos, &key, &value)) {
|
||||
char *buffer;
|
||||
Py_ssize_t length;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
buffer = (char *)PyUnicode_AsUTF8AndSize(key, &length);
|
||||
if (buffer == nullptr) {
|
||||
#else
|
||||
if (PyString_AsStringAndSize(key, &buffer, &length) == -1) {
|
||||
#endif
|
||||
Dtool_Raise_TypeError("NodePath.set_shader_inputs accepts only string keywords");
|
||||
return;
|
||||
}
|
||||
|
||||
CPT_InternalName name(string(buffer, length));
|
||||
ShaderInput *input = nullptr;
|
||||
|
||||
if (PyTuple_CheckExact(value)) {
|
||||
// A tuple is interpreted as a vector.
|
||||
Py_ssize_t size = PyTuple_GET_SIZE(value);
|
||||
if (size > 4) {
|
||||
Dtool_Raise_TypeError("NodePath.set_shader_inputs tuple input should not have more than 4 scalars");
|
||||
return;
|
||||
}
|
||||
// If any of them is a float, we are storing it as a float vector.
|
||||
bool is_float = false;
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
if (PyFloat_CheckExact(PyTuple_GET_ITEM(value, i))) {
|
||||
is_float = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_float) {
|
||||
LVecBase4 vec(0);
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
vec[i] = (PN_stdfloat)PyFloat_AsDouble(PyTuple_GET_ITEM(value, i));
|
||||
}
|
||||
input = new ShaderInput(name, vec);
|
||||
} else {
|
||||
LVecBase4i vec(0);
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
vec[i] = (int)PyLong_AsLong(PyTuple_GET_ITEM(value, i));
|
||||
}
|
||||
input = new ShaderInput(name, vec);
|
||||
}
|
||||
|
||||
} else if (DtoolCanThisBeAPandaInstance(value)) {
|
||||
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)value;
|
||||
void *ptr;
|
||||
|
||||
if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_Texture))) {
|
||||
input = new ShaderInput(name, (Texture *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_NodePath))) {
|
||||
input = new ShaderInput(name, *(const NodePath *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_float))) {
|
||||
input = new ShaderInput(name, *(const PTA_float *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_double))) {
|
||||
input = new ShaderInput(name, *(const PTA_double *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_int))) {
|
||||
input = new ShaderInput(name, *(const PTA_int *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4f))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase4f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3f))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase3f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2f))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase2f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4f))) {
|
||||
input = new ShaderInput(name, *(const PTA_LMatrix4f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3f))) {
|
||||
input = new ShaderInput(name, *(const PTA_LMatrix3f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4d))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase4d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3d))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase3d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2d))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase2d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4d))) {
|
||||
input = new ShaderInput(name, *(const PTA_LMatrix4d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3d))) {
|
||||
input = new ShaderInput(name, *(const PTA_LMatrix3d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4i))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase4i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3i))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase3i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2i))) {
|
||||
input = new ShaderInput(name, *(const PTA_LVecBase2i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4f))) {
|
||||
input = new ShaderInput(name, *(const LVecBase4f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3f))) {
|
||||
input = new ShaderInput(name, *(const LVecBase3f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2f))) {
|
||||
input = new ShaderInput(name, *(const LVecBase2f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4d))) {
|
||||
input = new ShaderInput(name, *(const LVecBase4d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3d))) {
|
||||
input = new ShaderInput(name, *(const LVecBase3d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2d))) {
|
||||
input = new ShaderInput(name, *(const LVecBase2d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4i))) {
|
||||
input = new ShaderInput(name, *(const LVecBase4i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3i))) {
|
||||
input = new ShaderInput(name, *(const LVecBase3i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2i))) {
|
||||
input = new ShaderInput(name, *(const LVecBase2i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ShaderBuffer))) {
|
||||
input = new ShaderInput(name, (ShaderBuffer *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ParamValueBase))) {
|
||||
input = new ShaderInput(name, (ParamValueBase *)ptr);
|
||||
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown type passed to NodePath.set_shader_inputs");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (PyFloat_Check(value)) {
|
||||
input = new ShaderInput(name, LVecBase4(PyFloat_AS_DOUBLE(value), 0, 0, 0));
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
} else if (PyInt_Check(value)) {
|
||||
input = new ShaderInput(name, LVecBase4i((int)PyInt_AS_LONG(value), 0, 0, 0));
|
||||
#endif
|
||||
|
||||
} else if (PyLong_Check(value)) {
|
||||
input = new ShaderInput(name, LVecBase4i((int)PyLong_AsLong(value), 0, 0, 0));
|
||||
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown type passed to NodePath.set_shader_inputs");
|
||||
return;
|
||||
}
|
||||
|
||||
attrib->_inputs[move(name)] = input;
|
||||
}
|
||||
|
||||
node->set_attrib(ShaderAttrib::return_new(attrib));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tight bounds as a 2-tuple of LPoint3 objects. This is a
|
||||
* convenience function for Python users, among which the use of
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ public:
|
|||
// This is defined to implement cycle detection in Python tags.
|
||||
INLINE int __traverse__(visitproc visit, void *arg);
|
||||
|
||||
void set_shader_inputs(PyObject *args, PyObject *kwargs);
|
||||
|
||||
PyObject *get_tight_bounds(const NodePath &other = NodePath()) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -799,12 +799,10 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedWritable::init_type();
|
||||
ReferenceCount::init_type();
|
||||
TypedWritableReferenceCount::init_type();
|
||||
Namable::init_type();
|
||||
register_type(_type_handle, "PandaNode",
|
||||
TypedWritable::get_class_type(),
|
||||
ReferenceCount::get_class_type(),
|
||||
TypedWritableReferenceCount::get_class_type(),
|
||||
Namable::get_class_type());
|
||||
CData::init_type();
|
||||
Down::init_type();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "pta_LVecBase4.h"
|
||||
#include "pta_LVecBase3.h"
|
||||
#include "pta_LVecBase2.h"
|
||||
#include "extension.h"
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -147,6 +148,8 @@ private:
|
|||
typedef pmap<CPT_InternalName, CPT(ShaderInput)> Inputs;
|
||||
Inputs _inputs;
|
||||
|
||||
friend class Extension<NodePath>;
|
||||
|
||||
PUBLISHED:
|
||||
static int get_class_slot() {
|
||||
return _attrib_slot;
|
||||
|
|
|
|||
|
|
@ -151,9 +151,9 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedObject::init_type();
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "ShaderGenerator",
|
||||
TypedObject::get_class_type());
|
||||
TypedReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
@ -173,9 +173,9 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedObject::init_type();
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "ShaderGenerator",
|
||||
TypedObject::get_class_type());
|
||||
TypedReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
|
|
@ -2612,12 +2612,10 @@ setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels) {
|
|||
|
||||
if (gltex->total_bytecount != total_bytecount) {
|
||||
if (gltex->allocated_buffer != NULL) {
|
||||
PANDA_FREE_ARRAY(gltex->allocated_buffer);
|
||||
TinyTextureContext::get_class_type().dec_memory_usage(TypeHandle::MC_array, gltex->total_bytecount);
|
||||
TinyTextureContext::get_class_type().deallocate_array(gltex->allocated_buffer);
|
||||
}
|
||||
gltex->allocated_buffer = PANDA_MALLOC_ARRAY(total_bytecount);
|
||||
gltex->allocated_buffer = TinyTextureContext::get_class_type().allocate_array(total_bytecount);
|
||||
gltex->total_bytecount = total_bytecount;
|
||||
TinyTextureContext::get_class_type().inc_memory_usage(TypeHandle::MC_array, total_bytecount);
|
||||
}
|
||||
|
||||
char *next_buffer = (char *)gltex->allocated_buffer;
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ TinyTextureContext::
|
|||
GLTexture *gltex = &_gltex;
|
||||
if (gltex->allocated_buffer != NULL) {
|
||||
nassertv(gltex->num_levels != 0);
|
||||
TinyTextureContext::get_class_type().dec_memory_usage(TypeHandle::MC_array, gltex->total_bytecount);
|
||||
PANDA_FREE_ARRAY(gltex->allocated_buffer);
|
||||
get_class_type().deallocate_array(gltex->allocated_buffer);
|
||||
gltex->allocated_buffer = NULL;
|
||||
gltex->total_bytecount = 0;
|
||||
gltex->num_levels = 0;
|
||||
|
|
@ -51,8 +50,7 @@ evict_lru() {
|
|||
GLTexture *gltex = &_gltex;
|
||||
if (gltex->allocated_buffer != NULL) {
|
||||
nassertv(gltex->num_levels != 0);
|
||||
TinyTextureContext::get_class_type().dec_memory_usage(TypeHandle::MC_array, gltex->total_bytecount);
|
||||
PANDA_FREE_ARRAY(gltex->allocated_buffer);
|
||||
get_class_type().deallocate_array(gltex->allocated_buffer);
|
||||
gltex->allocated_buffer = NULL;
|
||||
gltex->total_bytecount = 0;
|
||||
gltex->num_levels = 0;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,7 @@
|
|||
|
||||
#include "psapi.h"
|
||||
#include "powrprof.h"
|
||||
|
||||
#ifdef _WIN64
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
TypeHandle WinGraphicsPipe::_type_handle;
|
||||
|
||||
|
|
@ -99,443 +96,6 @@ void get_memory_information (DisplayInformation *display_information) {
|
|||
}
|
||||
}
|
||||
|
||||
typedef union {
|
||||
uint64_t long_integer;
|
||||
}
|
||||
LONG_INTEGER;
|
||||
|
||||
uint64_t cpu_time_function (void) {
|
||||
#ifdef _WIN64
|
||||
return __rdtsc();
|
||||
#else
|
||||
LONG_INTEGER long_integer;
|
||||
LONG_INTEGER *long_integer_pointer;
|
||||
|
||||
long_integer_pointer = &long_integer;
|
||||
|
||||
__asm {
|
||||
mov ebx,[long_integer_pointer]
|
||||
rdtsc
|
||||
mov [ebx + 0], eax
|
||||
mov [ebx + 4], edx
|
||||
}
|
||||
|
||||
return long_integer.long_integer;
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
unsigned char al;
|
||||
unsigned char ah;
|
||||
};
|
||||
unsigned int eax;
|
||||
};
|
||||
unsigned int ebx;
|
||||
unsigned int ecx;
|
||||
unsigned int edx;
|
||||
};
|
||||
} CPU_ID_REGISTERS;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
int maximum_cpu_id_input;
|
||||
char cpu_vendor [16];
|
||||
};
|
||||
|
||||
CPU_ID_REGISTERS cpu_id_registers_0;
|
||||
};
|
||||
|
||||
union {
|
||||
CPU_ID_REGISTERS cpu_id_registers_1;
|
||||
|
||||
struct {
|
||||
// eax
|
||||
union {
|
||||
unsigned int eax;
|
||||
unsigned int version_information;
|
||||
struct {
|
||||
unsigned int stepping_id : 4;
|
||||
unsigned int model : 4;
|
||||
unsigned int family : 4;
|
||||
unsigned int processor_type : 2;
|
||||
unsigned int reserved_0 : 2;
|
||||
unsigned int extended_model_id : 4;
|
||||
unsigned int extended_family_id : 8;
|
||||
unsigned int reserved_1 : 4;
|
||||
};
|
||||
};
|
||||
|
||||
// ebx
|
||||
union {
|
||||
unsigned int ebx;
|
||||
struct {
|
||||
unsigned int brand_index : 8;
|
||||
unsigned int clflush : 8;
|
||||
unsigned int maximum_logical_processors : 8;
|
||||
unsigned int initial_apic_id : 8;
|
||||
};
|
||||
};
|
||||
|
||||
// ecx
|
||||
union {
|
||||
unsigned int ecx;
|
||||
struct {
|
||||
unsigned int sse3 : 1;
|
||||
unsigned int reserved_1_to_2 : 2;
|
||||
unsigned int monitor : 1;
|
||||
unsigned int ds_cpl : 1;
|
||||
unsigned int vmx : 1;
|
||||
unsigned int reserved_6 : 1;
|
||||
unsigned int est : 1;
|
||||
unsigned int tm2 : 1;
|
||||
unsigned int reserved_9 : 1;
|
||||
unsigned int cnxt_id : 1;
|
||||
unsigned int reserved_11_to_12 : 2;
|
||||
unsigned int cmpxchg16b : 1;
|
||||
unsigned int xtpr_disable : 1;
|
||||
unsigned int reserved_15_to_31 : 17;
|
||||
};
|
||||
};
|
||||
|
||||
// edx
|
||||
union {
|
||||
unsigned int edx;
|
||||
struct {
|
||||
unsigned int fpu : 1;
|
||||
unsigned int vme : 1;
|
||||
unsigned int de : 1;
|
||||
unsigned int pse : 1;
|
||||
unsigned int tsc : 1;
|
||||
unsigned int msr : 1;
|
||||
unsigned int pae : 1;
|
||||
unsigned int mce : 1;
|
||||
unsigned int cx8 : 1;
|
||||
unsigned int apic : 1;
|
||||
unsigned int reserved_10 : 1;
|
||||
unsigned int sep : 1;
|
||||
unsigned int mtrr : 1;
|
||||
unsigned int pge : 1;
|
||||
unsigned int mca : 1;
|
||||
unsigned int cmov : 1;
|
||||
unsigned int pat : 1;
|
||||
unsigned int pse_36 : 1;
|
||||
unsigned int psn : 1;
|
||||
unsigned int cflush : 1;
|
||||
unsigned int reserved_20 : 1;
|
||||
unsigned int ds : 1;
|
||||
unsigned int acpi : 1;
|
||||
unsigned int mmx : 1;
|
||||
unsigned int fxsr : 1;
|
||||
unsigned int sse : 1;
|
||||
unsigned int sse2 : 1;
|
||||
unsigned int ss : 1;
|
||||
unsigned int htt : 1;
|
||||
unsigned int tm : 1;
|
||||
unsigned int reserved_30 : 1;
|
||||
unsigned int pbe : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#define MAXIMUM_2 8
|
||||
#define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof(CPU_ID_REGISTERS))
|
||||
|
||||
union {
|
||||
CPU_ID_REGISTERS cpu_id_registers_2;
|
||||
unsigned char character_array_2 [MAXIMUM_CHARACTERS];
|
||||
CPU_ID_REGISTERS cpu_id_registers_2_array [MAXIMUM_2];
|
||||
};
|
||||
|
||||
union {
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000000;
|
||||
};
|
||||
|
||||
union {
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000001;
|
||||
};
|
||||
|
||||
union {
|
||||
char cpu_brand_string [sizeof(CPU_ID_REGISTERS) * 3];
|
||||
struct {
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000002;
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000003;
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000004;
|
||||
};
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int eax;
|
||||
unsigned int ebx;
|
||||
union {
|
||||
unsigned int ecx;
|
||||
struct {
|
||||
unsigned int l1_data_cache_line_size : 8;
|
||||
unsigned int l1_data_reserved_8_to_15 : 8;
|
||||
unsigned int l1_data_associativity : 8;
|
||||
unsigned int l1_data_cache_size : 8;
|
||||
};
|
||||
};
|
||||
union {
|
||||
unsigned int edx;
|
||||
struct {
|
||||
unsigned int l1_code_cache_line_size : 8;
|
||||
unsigned int l1_code_reserved_8_to_15 : 8;
|
||||
unsigned int l1_code_associativity : 8;
|
||||
unsigned int l1_code_cache_size : 8;
|
||||
};
|
||||
};
|
||||
};
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000005;
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
unsigned int eax;
|
||||
unsigned int ebx;
|
||||
union {
|
||||
unsigned int ecx;
|
||||
struct {
|
||||
unsigned int l2_cache_line_size : 8;
|
||||
unsigned int l2_reserved_8_to_11 : 4;
|
||||
unsigned int l2_associativity : 4;
|
||||
unsigned int l2_cache_size : 16;
|
||||
};
|
||||
};
|
||||
unsigned int edx;
|
||||
};
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000006;
|
||||
};
|
||||
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000008;
|
||||
|
||||
unsigned int cache_line_size;
|
||||
unsigned int log_base_2_cache_line_size;
|
||||
} CPU_ID;
|
||||
|
||||
typedef struct {
|
||||
CPU_ID_REGISTERS cpu_id_registers_0;
|
||||
CPU_ID_REGISTERS cpu_id_registers_1;
|
||||
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000000;
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000001;
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000002;
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000003;
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000004;
|
||||
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000006;
|
||||
|
||||
CPU_ID_REGISTERS cpu_id_registers_0x80000008;
|
||||
} CPU_ID_BINARY_DATA;
|
||||
|
||||
void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_binary_data) {
|
||||
cpu_id_binary_data->cpu_id_registers_0 = cpu_id->cpu_id_registers_0;
|
||||
cpu_id_binary_data->cpu_id_registers_1 = cpu_id->cpu_id_registers_1;
|
||||
cpu_id_binary_data->cpu_id_registers_0x80000000 = cpu_id->cpu_id_registers_0x80000000;
|
||||
cpu_id_binary_data->cpu_id_registers_0x80000001 = cpu_id->cpu_id_registers_0x80000001;
|
||||
cpu_id_binary_data->cpu_id_registers_0x80000002 = cpu_id->cpu_id_registers_0x80000002;
|
||||
cpu_id_binary_data->cpu_id_registers_0x80000003 = cpu_id->cpu_id_registers_0x80000003;
|
||||
cpu_id_binary_data->cpu_id_registers_0x80000004 = cpu_id->cpu_id_registers_0x80000004;
|
||||
cpu_id_binary_data->cpu_id_registers_0x80000006 = cpu_id->cpu_id_registers_0x80000006;
|
||||
cpu_id_binary_data->cpu_id_registers_0x80000008 = cpu_id->cpu_id_registers_0x80000008;
|
||||
}
|
||||
|
||||
void cpu_id_binary_data_to_cpu_id (CPU_ID_BINARY_DATA *cpu_id_binary_data, CPU_ID *cpu_id) {
|
||||
memset (cpu_id, 0, sizeof(CPU_ID));
|
||||
|
||||
cpu_id->cpu_id_registers_0 = cpu_id_binary_data->cpu_id_registers_0;
|
||||
cpu_id->cpu_id_registers_1 = cpu_id_binary_data->cpu_id_registers_1;
|
||||
cpu_id->cpu_id_registers_0x80000000 = cpu_id_binary_data->cpu_id_registers_0x80000000;
|
||||
cpu_id->cpu_id_registers_0x80000001 = cpu_id_binary_data->cpu_id_registers_0x80000001;
|
||||
cpu_id->cpu_id_registers_0x80000002 = cpu_id_binary_data->cpu_id_registers_0x80000002;
|
||||
cpu_id->cpu_id_registers_0x80000003 = cpu_id_binary_data->cpu_id_registers_0x80000003;
|
||||
cpu_id->cpu_id_registers_0x80000004 = cpu_id_binary_data->cpu_id_registers_0x80000004;
|
||||
cpu_id->cpu_id_registers_0x80000006 = cpu_id_binary_data->cpu_id_registers_0x80000006;
|
||||
cpu_id->cpu_id_registers_0x80000008 = cpu_id_binary_data->cpu_id_registers_0x80000008;
|
||||
}
|
||||
|
||||
int cpuid(int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
|
||||
int state;
|
||||
|
||||
state = false;
|
||||
__try {
|
||||
if (input_eax == 0) {
|
||||
// the order of ecx and edx is swapped when saved to make a proper
|
||||
// vendor string
|
||||
#ifdef _WIN64
|
||||
__cpuid((int*)cpu_id_registers, input_eax);
|
||||
unsigned int tmp = cpu_id_registers->edx;
|
||||
cpu_id_registers->edx = cpu_id_registers->ecx;
|
||||
cpu_id_registers->ecx = tmp;
|
||||
#else
|
||||
__asm {
|
||||
mov eax, [input_eax]
|
||||
mov edi, [cpu_id_registers]
|
||||
|
||||
cpuid
|
||||
|
||||
mov [edi + 0], eax
|
||||
mov [edi + 4], ebx
|
||||
mov [edi + 8], edx
|
||||
mov [edi + 12], ecx
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifdef _WIN64
|
||||
__cpuid((int*)cpu_id_registers, input_eax);
|
||||
#else
|
||||
__asm {
|
||||
mov eax, [input_eax]
|
||||
mov edi, [cpu_id_registers]
|
||||
|
||||
cpuid
|
||||
|
||||
mov [edi + 0], eax
|
||||
mov [edi + 4], ebx
|
||||
mov [edi + 8], ecx
|
||||
mov [edi + 12], edx
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
state = true;
|
||||
}
|
||||
__except (1) {
|
||||
state = false;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void parse_cpu_id(CPU_ID *cpu_id) {
|
||||
printf("CPUID\n");
|
||||
printf(" vendor = %s\n", cpu_id->cpu_vendor);
|
||||
printf(" brand string %s\n", cpu_id->cpu_brand_string);
|
||||
printf(" maximum_cpu_id_input = %u\n", cpu_id->maximum_cpu_id_input);
|
||||
printf(" maximum extended information = 0x%X\n", cpu_id->cpu_id_registers_0x80000000.eax);
|
||||
|
||||
printf(" MMX = %u\n", cpu_id->mmx);
|
||||
printf(" SSE = %u\n", cpu_id->sse);
|
||||
printf(" SSE2 = %u\n", cpu_id->sse2);
|
||||
printf(" SSE3 = %u\n", cpu_id->sse3);
|
||||
|
||||
printf(" EST = %u\n", cpu_id->est);
|
||||
|
||||
if (cpu_id->maximum_cpu_id_input >= 1) {
|
||||
printf(" version_information\n");
|
||||
printf(" stepping_id %u\n", cpu_id->stepping_id);
|
||||
printf(" model %u\n", cpu_id->model);
|
||||
printf(" family %u\n", cpu_id->family);
|
||||
printf(" processor_type %u\n", cpu_id->processor_type);
|
||||
printf(" extended_model_id %u\n", cpu_id->extended_model_id);
|
||||
printf(" extended_family_id %u\n", cpu_id->extended_family_id);
|
||||
|
||||
printf(" brand_index %u\n", cpu_id->brand_index);
|
||||
printf(" clflush %u\n", cpu_id->clflush);
|
||||
printf(" maximum_logical_processors %u\n", cpu_id->maximum_logical_processors);
|
||||
printf(" initial_apic_id %u\n", cpu_id->initial_apic_id);
|
||||
|
||||
// printf(" cache_line_size %u\n", cpu_id->cache_line_size); printf("
|
||||
// log_base_2_cache_line_size %u\n", cpu_id->log_base_2_cache_line_size);
|
||||
}
|
||||
|
||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) {
|
||||
printf(" l1_data_cache_line_size %d\n", cpu_id->l1_data_cache_line_size);
|
||||
printf(" l1_data_associativity %d\n", cpu_id->l1_data_associativity);
|
||||
printf(" l1_data_cache_size %dK\n", cpu_id->l1_data_cache_size);
|
||||
|
||||
printf(" l1_code_cache_line_size %d\n", cpu_id->l1_code_cache_line_size);
|
||||
printf(" l1_code_associativity %d\n", cpu_id->l1_code_associativity);
|
||||
printf(" l1_code_cache_size %dK\n", cpu_id->l1_code_cache_size);
|
||||
}
|
||||
|
||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) {
|
||||
printf(" l2_cache_line_size %d\n", cpu_id->l2_cache_line_size);
|
||||
printf(" l2_associativity %d\n", cpu_id->l2_associativity);
|
||||
printf(" l2_cache_size %dK\n", cpu_id->l2_cache_size);
|
||||
}
|
||||
}
|
||||
|
||||
int initialize_cpu_id(CPU_ID *cpu_id) {
|
||||
int debug = false;
|
||||
memset(cpu_id, 0, sizeof(CPU_ID));
|
||||
|
||||
if (cpuid(0, &cpu_id->cpu_id_registers_0)) {
|
||||
if (cpu_id->maximum_cpu_id_input >= 1) {
|
||||
cpuid(1, &cpu_id->cpu_id_registers_1);
|
||||
}
|
||||
if (cpu_id->maximum_cpu_id_input >= 2) {
|
||||
unsigned int index;
|
||||
|
||||
cpuid(2, &cpu_id->cpu_id_registers_2);
|
||||
if (debug) {
|
||||
printf(" al = %u\n", cpu_id->cpu_id_registers_2.al);
|
||||
}
|
||||
|
||||
for (index = 1; index < cpu_id->cpu_id_registers_2.al && index < MAXIMUM_2; index++) {
|
||||
cpuid(2, &cpu_id->cpu_id_registers_2_array [index]);
|
||||
}
|
||||
|
||||
for (index = 1; index < MAXIMUM_CHARACTERS; index++) {
|
||||
if (cpu_id->character_array_2 [index]) {
|
||||
if (debug) {
|
||||
printf(" cache/TLB byte = %X\n", cpu_id->character_array_2 [index]);
|
||||
}
|
||||
switch (cpu_id->character_array_2 [index]) {
|
||||
case 0x0A:
|
||||
case 0x0C:
|
||||
cpu_id->cache_line_size = 32;
|
||||
cpu_id->log_base_2_cache_line_size = 5;
|
||||
break;
|
||||
|
||||
case 0x2C:
|
||||
case 0x60:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
cpu_id->cache_line_size = 64;
|
||||
cpu_id->log_base_2_cache_line_size = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpuid(0x80000000, &cpu_id->cpu_id_registers_0x80000000);
|
||||
|
||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000001) {
|
||||
cpuid(0x80000001, &cpu_id->cpu_id_registers_0x80000001);
|
||||
}
|
||||
|
||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000004) {
|
||||
cpuid(0x80000002, &cpu_id->cpu_id_registers_0x80000002);
|
||||
cpuid(0x80000003, &cpu_id->cpu_id_registers_0x80000003);
|
||||
cpuid(0x80000004, &cpu_id->cpu_id_registers_0x80000004);
|
||||
}
|
||||
|
||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) {
|
||||
cpuid(0x80000005, &cpu_id->cpu_id_registers_0x80000005);
|
||||
}
|
||||
|
||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) {
|
||||
cpuid(0x80000006, &cpu_id->cpu_id_registers_0x80000006);
|
||||
}
|
||||
|
||||
if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000008) {
|
||||
cpuid(0x80000008, &cpu_id->cpu_id_registers_0x80000008);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int update_cpu_frequency_function(int processor_number, DisplayInformation *display_information) {
|
||||
int update;
|
||||
|
||||
|
|
@ -776,9 +336,6 @@ lookup_cpu_data() {
|
|||
// set callback for memory function
|
||||
_display_information->_get_memory_information_function = get_memory_information;
|
||||
|
||||
// set callback for cpu time function
|
||||
_display_information->_cpu_time_function = cpu_time_function;
|
||||
|
||||
// determine CPU frequency
|
||||
uint64_t time;
|
||||
uint64_t end_time;
|
||||
|
|
@ -803,12 +360,12 @@ lookup_cpu_data() {
|
|||
if (QueryPerformanceFrequency(&frequency)) {
|
||||
if (frequency.QuadPart > 0) {
|
||||
if (QueryPerformanceCounter (&counter)) {
|
||||
time = cpu_time_function();
|
||||
time = __rdtsc();
|
||||
end.QuadPart = counter.QuadPart + frequency.QuadPart;
|
||||
while (QueryPerformanceCounter (&counter) && counter.QuadPart < end.QuadPart) {
|
||||
|
||||
}
|
||||
end_time = cpu_time_function();
|
||||
end_time = __rdtsc();
|
||||
|
||||
_display_information->_cpu_frequency = end_time - time;
|
||||
}
|
||||
|
|
@ -821,54 +378,6 @@ lookup_cpu_data() {
|
|||
sprintf(string, "CPU frequency: %I64d\n", _display_information->_cpu_frequency);
|
||||
windisplay_cat.info() << string;
|
||||
|
||||
|
||||
// CPUID
|
||||
CPU_ID cpu_id;
|
||||
|
||||
windisplay_cat.info() << "start CPU ID\n";
|
||||
|
||||
if (initialize_cpu_id(&cpu_id)) {
|
||||
CPU_ID_BINARY_DATA *cpu_id_binary_data;
|
||||
|
||||
cpu_id_binary_data = new (CPU_ID_BINARY_DATA);
|
||||
if (cpu_id_binary_data) {
|
||||
cpu_id_to_cpu_id_binary_data(&cpu_id, cpu_id_binary_data);
|
||||
_display_information->_cpu_id_size = sizeof(CPU_ID_BINARY_DATA) / sizeof(unsigned int);
|
||||
_display_information->_cpu_id_data = (unsigned int *) cpu_id_binary_data;
|
||||
|
||||
_display_information->_cpu_vendor_string = strdup(cpu_id.cpu_vendor);
|
||||
_display_information->_cpu_brand_string = strdup(cpu_id.cpu_brand_string);
|
||||
_display_information->_cpu_version_information = cpu_id.version_information;
|
||||
_display_information->_cpu_brand_index = cpu_id.brand_index;
|
||||
|
||||
if (windisplay_cat.is_debug()) {
|
||||
windisplay_cat.debug()
|
||||
<< hex << _display_information->_cpu_id_version << dec << "|";
|
||||
|
||||
int index;
|
||||
for (index = 0; index < _display_information->_cpu_id_size; ++index) {
|
||||
unsigned int data;
|
||||
data = _display_information->_cpu_id_data[index];
|
||||
|
||||
windisplay_cat.debug(false)
|
||||
<< hex << data << dec;
|
||||
if (index < _display_information->_cpu_id_size - 1) {
|
||||
windisplay_cat.debug(false)
|
||||
<< "|";
|
||||
}
|
||||
}
|
||||
windisplay_cat.debug(false)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (windisplay_cat.is_debug()) {
|
||||
parse_cpu_id(&cpu_id);
|
||||
}
|
||||
}
|
||||
|
||||
windisplay_cat.info() << "end CPU ID\n";
|
||||
|
||||
// Number of CPU's
|
||||
count_number_of_cpus(_display_information);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from direct.showbase.DirectObject import DirectObject
|
|||
from direct.task.Task import Task
|
||||
import sys
|
||||
|
||||
# First we define some contants for the colors
|
||||
# First we define some constants for the colors
|
||||
BLACK = (0, 0, 0, 1)
|
||||
WHITE = (1, 1, 1, 1)
|
||||
HIGHLIGHT = (0, 1, 1, 1)
|
||||
|
|
@ -33,7 +33,7 @@ PIECEBLACK = (.15, .15, .15, 1)
|
|||
# This is how we know where to position an object in 3D space based on a 2D mouse
|
||||
# position. It also assumes that we are dragging in the XY plane.
|
||||
#
|
||||
# This is derived from the mathmatical of a plane, solved for a given point
|
||||
# This is derived from the mathematical of a plane, solved for a given point
|
||||
def PointAtZ(z, point, vec):
|
||||
return point + vec * ((z - point.getZ()) / vec.getZ())
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ def PointAtZ(z, point, vec):
|
|||
def SquarePos(i):
|
||||
return LPoint3((i % 8) - 3.5, int(i // 8) - 3.5, 0)
|
||||
|
||||
# Helper function for determining wheter a square should be white or black
|
||||
# Helper function for determining whether a square should be white or black
|
||||
# The modulo operations (%) generate the every-other pattern of a chess-board
|
||||
def SquareColor(i):
|
||||
if (i + ((i // 8) % 2)) % 2:
|
||||
|
|
@ -84,7 +84,7 @@ class ChessboardDemo(ShowBase):
|
|||
# relative to it
|
||||
self.pickerNP = camera.attachNewNode(self.pickerNode)
|
||||
# Everything to be picked will use bit 1. This way if we were doing other
|
||||
# collision we could seperate it
|
||||
# collision we could separate it
|
||||
self.pickerNode.setFromCollideMask(BitMask32.bit(1))
|
||||
self.pickerRay = CollisionRay() # Make our ray
|
||||
# Add it to the collision node
|
||||
|
|
@ -96,7 +96,7 @@ class ChessboardDemo(ShowBase):
|
|||
# Now we create the chess board and its pieces
|
||||
|
||||
# We will attach all of the squares to their own root. This way we can do the
|
||||
# collision pass just on the sqaures and save the time of checking the rest
|
||||
# collision pass just on the squares and save the time of checking the rest
|
||||
# of the scene
|
||||
self.squareRoot = render.attachNewNode("squareRoot")
|
||||
|
||||
|
|
@ -240,7 +240,7 @@ class ChessboardDemo(ShowBase):
|
|||
render.setLight(render.attachNewNode(ambientLight))
|
||||
|
||||
|
||||
# Class for a piece. This just handels loading the model and setting initial
|
||||
# Class for a piece. This just handles loading the model and setting initial
|
||||
# position and color
|
||||
class Piece(object):
|
||||
def __init__(self, square, color):
|
||||
|
|
|
|||
Loading…
Reference in New Issue