Merge branch 'master' into deploy-ng
This commit is contained in:
commit
f16cd29971
|
|
@ -11,18 +11,32 @@ __all__ = [
|
|||
'interrupt_main',
|
||||
'exit', 'allocate_lock', 'get_ident',
|
||||
'stack_size',
|
||||
'force_yield', 'consider_yield',
|
||||
'forceYield', 'considerYield',
|
||||
'TIMEOUT_MAX'
|
||||
]
|
||||
|
||||
from panda3d import core
|
||||
import sys
|
||||
|
||||
if sys.platform == "win32":
|
||||
TIMEOUT_MAX = float(0xffffffff // 1000)
|
||||
else:
|
||||
TIMEOUT_MAX = float(0x7fffffffffffffff // 1000000000)
|
||||
|
||||
# These methods are defined in Panda, and are particularly useful if
|
||||
# you may be running in Panda's SIMPLE_THREADS compilation mode.
|
||||
forceYield = core.Thread.forceYield
|
||||
considerYield = core.Thread.considerYield
|
||||
force_yield = core.Thread.force_yield
|
||||
consider_yield = core.Thread.consider_yield
|
||||
|
||||
class error(Exception):
|
||||
pass
|
||||
forceYield = force_yield
|
||||
considerYield = consider_yield
|
||||
|
||||
if sys.version_info >= (3, 3):
|
||||
error = RuntimeError
|
||||
else:
|
||||
class error(Exception):
|
||||
pass
|
||||
|
||||
class LockType:
|
||||
""" Implements a mutex lock. Instead of directly subclassing
|
||||
|
|
@ -36,13 +50,18 @@ class LockType:
|
|||
self.__cvar = core.ConditionVar(self.__lock)
|
||||
self.__locked = False
|
||||
|
||||
def acquire(self, waitflag = 1):
|
||||
def acquire(self, waitflag = 1, timeout = -1):
|
||||
self.__lock.acquire()
|
||||
try:
|
||||
if self.__locked and not waitflag:
|
||||
return False
|
||||
while self.__locked:
|
||||
self.__cvar.wait()
|
||||
|
||||
if timeout >= 0:
|
||||
while self.__locked:
|
||||
self.__cvar.wait(timeout)
|
||||
else:
|
||||
while self.__locked:
|
||||
self.__cvar.wait()
|
||||
|
||||
self.__locked = True
|
||||
return True
|
||||
|
|
@ -202,12 +221,17 @@ def _get_thread_locals(thread, i):
|
|||
def _remove_thread_id(threadId):
|
||||
""" Removes the thread with the indicated ID from the thread list. """
|
||||
|
||||
# On interpreter shutdown, Python may set module globals to None.
|
||||
if _threadsLock is None or _threads is None:
|
||||
return
|
||||
|
||||
_threadsLock.acquire()
|
||||
try:
|
||||
thread, locals, wrapper = _threads[threadId]
|
||||
assert thread.getPythonIndex() == threadId
|
||||
del _threads[threadId]
|
||||
thread.setPythonIndex(-1)
|
||||
if threadId in _threads:
|
||||
thread, locals, wrapper = _threads[threadId]
|
||||
assert thread.getPythonIndex() == threadId
|
||||
del _threads[threadId]
|
||||
thread.setPythonIndex(-1)
|
||||
|
||||
finally:
|
||||
_threadsLock.release()
|
||||
|
|
|
|||
|
|
@ -35,11 +35,15 @@ __all__ = [
|
|||
'Event',
|
||||
'Timer',
|
||||
'local',
|
||||
'current_thread', 'currentThread',
|
||||
'enumerate', 'active_count', 'activeCount',
|
||||
'current_thread',
|
||||
'main_thread',
|
||||
'enumerate', 'active_count',
|
||||
'settrace', 'setprofile', 'stack_size',
|
||||
'TIMEOUT_MAX',
|
||||
]
|
||||
|
||||
TIMEOUT_MAX = _thread.TIMEOUT_MAX
|
||||
|
||||
local = _thread._local
|
||||
_newname = _thread._newname
|
||||
|
||||
|
|
@ -98,7 +102,15 @@ class Thread(ThreadBase):
|
|||
self.__dict__['daemon'] = current.daemon
|
||||
self.__dict__['name'] = name
|
||||
|
||||
self.__thread = core.PythonThread(self.run, None, name, name)
|
||||
def call_run():
|
||||
# As soon as the thread is done, break the circular reference.
|
||||
try:
|
||||
self.run()
|
||||
finally:
|
||||
self.__thread = None
|
||||
_thread._remove_thread_id(self.ident)
|
||||
|
||||
self.__thread = core.PythonThread(call_run, None, name, name)
|
||||
threadId = _thread._add_thread(self.__thread, weakref.proxy(self))
|
||||
self.__dict__['ident'] = threadId
|
||||
|
||||
|
|
@ -109,16 +121,17 @@ class Thread(ThreadBase):
|
|||
_thread._remove_thread_id(self.ident)
|
||||
|
||||
def is_alive(self):
|
||||
return self.__thread.isStarted()
|
||||
thread = self.__thread
|
||||
return thread is not None and thread.is_started()
|
||||
|
||||
def isAlive(self):
|
||||
return self.__thread.isStarted()
|
||||
isAlive = is_alive
|
||||
|
||||
def start(self):
|
||||
if self.__thread.isStarted():
|
||||
thread = self.__thread
|
||||
if thread is None or thread.is_started():
|
||||
raise RuntimeError
|
||||
|
||||
if not self.__thread.start(core.TPNormal, True):
|
||||
if not thread.start(core.TPNormal, True):
|
||||
raise RuntimeError
|
||||
|
||||
def run(self):
|
||||
|
|
@ -132,8 +145,12 @@ class Thread(ThreadBase):
|
|||
def join(self, timeout = None):
|
||||
# We don't support a timed join here, sorry.
|
||||
assert timeout is None
|
||||
self.__thread.join()
|
||||
self.__thread = None
|
||||
thread = self.__thread
|
||||
if thread is not None:
|
||||
thread.join()
|
||||
# Clear the circular reference.
|
||||
self.__thread = None
|
||||
_thread._remove_thread_id(self.ident)
|
||||
|
||||
def setName(self, name):
|
||||
self.__dict__['name'] = name
|
||||
|
|
@ -379,6 +396,10 @@ def current_thread():
|
|||
t = core.Thread.getCurrentThread()
|
||||
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
|
||||
|
||||
def main_thread():
|
||||
t = core.Thread.getMainThread()
|
||||
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
|
||||
|
||||
currentThread = current_thread
|
||||
|
||||
def enumerate():
|
||||
|
|
@ -386,7 +407,7 @@ def enumerate():
|
|||
_thread._threadsLock.acquire()
|
||||
try:
|
||||
for thread, locals, wrapper in list(_thread._threads.values()):
|
||||
if wrapper and thread.isStarted():
|
||||
if wrapper and wrapper.is_alive():
|
||||
tlist.append(wrapper)
|
||||
return tlist
|
||||
finally:
|
||||
|
|
@ -394,6 +415,7 @@ def enumerate():
|
|||
|
||||
def active_count():
|
||||
return len(enumerate())
|
||||
|
||||
activeCount = active_count
|
||||
|
||||
_settrace_func = None
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ implementation. """
|
|||
|
||||
import sys as _sys
|
||||
|
||||
from direct.stdpy import thread
|
||||
from direct.stdpy import thread as _thread
|
||||
from direct.stdpy.thread import stack_size, _newname, _local as local
|
||||
from panda3d import core
|
||||
_sleep = core.Thread.sleep
|
||||
|
|
@ -23,16 +23,19 @@ _sleep = core.Thread.sleep
|
|||
from time import time as _time
|
||||
from traceback import format_exc as _format_exc
|
||||
|
||||
# Rename some stuff so "from threading import *" is safe
|
||||
__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
|
||||
'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
|
||||
'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
|
||||
__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread',
|
||||
'enumerate', 'main_thread', 'TIMEOUT_MAX',
|
||||
'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
|
||||
'Timer', 'ThreadError',
|
||||
'setprofile', 'settrace', 'local', 'stack_size']
|
||||
|
||||
_start_new_thread = thread.start_new_thread
|
||||
_allocate_lock = thread.allocate_lock
|
||||
_get_ident = thread.get_ident
|
||||
ThreadError = thread.error
|
||||
del thread
|
||||
# Rename some stuff so "from threading import *" is safe
|
||||
_start_new_thread = _thread.start_new_thread
|
||||
_allocate_lock = _thread.allocate_lock
|
||||
get_ident = _thread.get_ident
|
||||
ThreadError = _thread.error
|
||||
TIMEOUT_MAX = _thread.TIMEOUT_MAX
|
||||
del _thread
|
||||
|
||||
|
||||
# Debug support (adapted from ihooks.py).
|
||||
|
|
@ -446,7 +449,7 @@ class Thread(_Verbose):
|
|||
try:
|
||||
self.__started = True
|
||||
_active_limbo_lock.acquire()
|
||||
_active[_get_ident()] = self
|
||||
_active[get_ident()] = self
|
||||
del _limbo[self]
|
||||
_active_limbo_lock.release()
|
||||
if __debug__:
|
||||
|
|
@ -537,7 +540,7 @@ class Thread(_Verbose):
|
|||
_active_limbo_lock.acquire()
|
||||
try:
|
||||
try:
|
||||
del _active[_get_ident()]
|
||||
del _active[get_ident()]
|
||||
except KeyError:
|
||||
if 'dummy_threading' not in _sys.modules:
|
||||
raise
|
||||
|
|
@ -581,10 +584,12 @@ class Thread(_Verbose):
|
|||
assert self.__initialized, "Thread.__init__() not called"
|
||||
self.__name = str(name)
|
||||
|
||||
def isAlive(self):
|
||||
def is_alive(self):
|
||||
assert self.__initialized, "Thread.__init__() not called"
|
||||
return self.__started and not self.__stopped
|
||||
|
||||
isAlive = is_alive
|
||||
|
||||
def isDaemon(self):
|
||||
assert self.__initialized, "Thread.__init__() not called"
|
||||
return self.__daemonic
|
||||
|
|
@ -634,7 +639,7 @@ class _MainThread(Thread):
|
|||
Thread.__init__(self, name="MainThread")
|
||||
self._Thread__started = True
|
||||
_active_limbo_lock.acquire()
|
||||
_active[_get_ident()] = self
|
||||
_active[get_ident()] = self
|
||||
_active_limbo_lock.release()
|
||||
|
||||
def _set_daemon(self):
|
||||
|
|
@ -653,12 +658,6 @@ class _MainThread(Thread):
|
|||
self._note("%s: exiting", self)
|
||||
self._Thread__delete()
|
||||
|
||||
def _pickSomeNonDaemonThread():
|
||||
for t in enumerate():
|
||||
if not t.isDaemon() and t.isAlive():
|
||||
return t
|
||||
return None
|
||||
|
||||
|
||||
# Dummy thread class to represent threads not started here.
|
||||
# These aren't garbage collected when they die, nor can they be waited for.
|
||||
|
|
@ -680,7 +679,7 @@ class _DummyThread(Thread):
|
|||
|
||||
self._Thread__started = True
|
||||
_active_limbo_lock.acquire()
|
||||
_active[_get_ident()] = self
|
||||
_active[get_ident()] = self
|
||||
_active_limbo_lock.release()
|
||||
|
||||
def _set_daemon(self):
|
||||
|
|
@ -692,19 +691,23 @@ class _DummyThread(Thread):
|
|||
|
||||
# Global API functions
|
||||
|
||||
def currentThread():
|
||||
def current_thread():
|
||||
try:
|
||||
return _active[_get_ident()]
|
||||
return _active[get_ident()]
|
||||
except KeyError:
|
||||
##print "currentThread(): no current thread for", _get_ident()
|
||||
##print "current_thread(): no current thread for", get_ident()
|
||||
return _DummyThread()
|
||||
|
||||
def activeCount():
|
||||
currentThread = current_thread
|
||||
|
||||
def active_count():
|
||||
_active_limbo_lock.acquire()
|
||||
count = len(_active) + len(_limbo)
|
||||
_active_limbo_lock.release()
|
||||
return count
|
||||
|
||||
activeCount = active_count
|
||||
|
||||
def enumerate():
|
||||
_active_limbo_lock.acquire()
|
||||
active = list(_active.values()) + list(_limbo.values())
|
||||
|
|
@ -717,7 +720,21 @@ def enumerate():
|
|||
# and make it available for the interpreter
|
||||
# (Py_Main) as threading._shutdown.
|
||||
|
||||
_shutdown = _MainThread()._exitfunc
|
||||
_main_thread = _MainThread()
|
||||
_shutdown = _main_thread._exitfunc
|
||||
|
||||
def _pickSomeNonDaemonThread():
|
||||
for t in enumerate():
|
||||
if not t.isDaemon() and t.isAlive():
|
||||
return t
|
||||
return None
|
||||
|
||||
def main_thread():
|
||||
"""Return the main thread object.
|
||||
In normal conditions, the main thread is the thread from which the
|
||||
Python interpreter was started.
|
||||
"""
|
||||
return _main_thread
|
||||
|
||||
# get thread-local implementation, either from the thread
|
||||
# module, or from the python fallback
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -4051,6 +4051,10 @@ name:
|
|||
| KW_STATIC
|
||||
{
|
||||
$$ = new CPPIdentifier("static", @1);
|
||||
}
|
||||
| KW_DEFAULT
|
||||
{
|
||||
$$ = new CPPIdentifier("default", @1);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ typedef struct _object PyObject;
|
|||
|
||||
#ifdef __WORDSIZE
|
||||
#define NATIVE_WORDSIZE __WORDSIZE
|
||||
#elif defined(_LP64)
|
||||
#elif defined(_LP64) || defined(_WIN64)
|
||||
#define NATIVE_WORDSIZE 64
|
||||
#else
|
||||
#define NATIVE_WORDSIZE 32
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ using namespace std;
|
|||
#define ALWAYS_INLINE inline
|
||||
#define TYPENAME typename
|
||||
#define CONSTEXPR constexpr
|
||||
#define ALWAYS_INLINE_CONSTEXPR constexpr
|
||||
#define NOEXCEPT noexcept
|
||||
#define FINAL final
|
||||
#define OVERRIDE override
|
||||
#define MOVE(x) x
|
||||
#define DEFAULT_CTOR = default
|
||||
#define DEFAULT_DTOR = default
|
||||
|
|
@ -166,7 +166,6 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
|
|||
# endif
|
||||
# if __has_extension(cxx_override_control) && (__cplusplus >= 201103L)
|
||||
# define FINAL final
|
||||
# define OVERRIDE override
|
||||
# endif
|
||||
# if __has_extension(cxx_defaulted_functions)
|
||||
# define DEFAULT_CTOR = default
|
||||
|
|
@ -197,7 +196,6 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
|
|||
// Starting at GCC 4.7
|
||||
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
|
||||
# define FINAL final
|
||||
# define OVERRIDE override
|
||||
# endif
|
||||
|
||||
// GCC defines several macros which we can query. List of all supported
|
||||
|
|
@ -211,11 +209,9 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
|
|||
# define NOEXCEPT noexcept
|
||||
# define USE_MOVE_SEMANTICS
|
||||
# define FINAL final
|
||||
# define OVERRIDE override
|
||||
# define MOVE(x) move(x)
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Visual Studio 2010
|
||||
# define NOEXCEPT throw()
|
||||
# define OVERRIDE override
|
||||
# define USE_MOVE_SEMANTICS
|
||||
# define FINAL sealed
|
||||
# define MOVE(x) move(x)
|
||||
|
|
@ -231,6 +227,9 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
|
|||
// Fallbacks if features are not supported
|
||||
#ifndef CONSTEXPR
|
||||
# define CONSTEXPR INLINE
|
||||
# define ALWAYS_INLINE_CONSTEXPR ALWAYS_INLINE
|
||||
#else
|
||||
# define ALWAYS_INLINE_CONSTEXPR ALWAYS_INLINE CONSTEXPR
|
||||
#endif
|
||||
#ifndef NOEXCEPT
|
||||
# define NOEXCEPT
|
||||
|
|
@ -241,9 +240,6 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
|
|||
#ifndef FINAL
|
||||
# define FINAL
|
||||
#endif
|
||||
#ifndef OVERRIDE
|
||||
# define OVERRIDE
|
||||
#endif
|
||||
#ifndef DEFAULT_CTOR
|
||||
# define DEFAULT_CTOR {}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -202,13 +202,11 @@ MemoryHook() {
|
|||
|
||||
#endif // WIN32
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_total_heap_single_size = 0;
|
||||
_total_heap_array_size = 0;
|
||||
_requested_heap_size = 0;
|
||||
_total_mmap_size = 0;
|
||||
_max_heap_size = ~(size_t)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -216,19 +214,16 @@ MemoryHook() {
|
|||
*/
|
||||
MemoryHook::
|
||||
MemoryHook(const MemoryHook ©) :
|
||||
_page_size(copy._page_size)
|
||||
{
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_total_heap_single_size = copy._total_heap_single_size;
|
||||
_total_heap_array_size = copy._total_heap_array_size;
|
||||
_requested_heap_size = copy._requested_heap_size;
|
||||
_total_mmap_size = copy._total_mmap_size;
|
||||
_max_heap_size = copy._max_heap_size;
|
||||
#endif
|
||||
_page_size(copy._page_size),
|
||||
_total_heap_single_size(copy._total_heap_single_size),
|
||||
_total_heap_array_size(copy._total_heap_array_size),
|
||||
_requested_heap_size(copy._requested_heap_size),
|
||||
_total_mmap_size(copy._total_mmap_size),
|
||||
_max_heap_size(copy._max_heap_size) {
|
||||
|
||||
((MutexImpl &)copy._lock).acquire();
|
||||
copy._lock.acquire();
|
||||
_deleted_chains = copy._deleted_chains;
|
||||
((MutexImpl &)copy._lock).release();
|
||||
copy._lock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -631,7 +626,6 @@ alloc_fail(size_t attempted_size) {
|
|||
abort();
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
/**
|
||||
* This callback method is called whenever the total allocated heap size
|
||||
* exceeds _max_heap_size. It's mainly intended for reporting memory leaks,
|
||||
|
|
@ -642,6 +636,7 @@ alloc_fail(size_t attempted_size) {
|
|||
*/
|
||||
void MemoryHook::
|
||||
overflow_heap_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_max_heap_size = ~(size_t)0;
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ public:
|
|||
|
||||
INLINE static size_t get_ptr_size(void *ptr);
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
protected:
|
||||
TVOLATILE AtomicAdjust::Integer _total_heap_single_size;
|
||||
TVOLATILE AtomicAdjust::Integer _total_heap_array_size;
|
||||
|
|
@ -79,7 +78,6 @@ protected:
|
|||
size_t _max_heap_size;
|
||||
|
||||
virtual void overflow_heap_size();
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
private:
|
||||
size_t _page_size;
|
||||
|
|
@ -87,7 +85,7 @@ private:
|
|||
typedef map<size_t, DeletedBufferChain *> DeletedChains;
|
||||
DeletedChains _deleted_chains;
|
||||
|
||||
MutexImpl _lock;
|
||||
mutable MutexImpl _lock;
|
||||
};
|
||||
|
||||
#include "memoryHook.I"
|
||||
|
|
|
|||
|
|
@ -26,9 +26,7 @@ TypeRegistryNode(TypeHandle handle, const string &name, TypeHandle &ref) :
|
|||
_handle(handle), _name(name), _ref(ref)
|
||||
{
|
||||
clear_subtree();
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
memset(_memory_usage, 0, sizeof(_memory_usage));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -47,9 +47,7 @@ public:
|
|||
Classes _parent_classes;
|
||||
Classes _child_classes;
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit];
|
||||
#endif
|
||||
|
||||
static bool _paranoid_inheritance;
|
||||
|
||||
|
|
|
|||
|
|
@ -341,6 +341,22 @@ ns_get_environment_variable(const string &var) const {
|
|||
}
|
||||
}
|
||||
|
||||
#elif !defined(__APPLE__)
|
||||
// Similarly, we define fallbacks on POSIX systems for the variables defined
|
||||
// in the XDG Base Directory specification, so that they can be safely used
|
||||
// in Config.prc files.
|
||||
if (var == "XDG_CONFIG_HOME") {
|
||||
Filename home_dir = Filename::get_home_directory();
|
||||
return home_dir.get_fullpath() + "/.config";
|
||||
|
||||
} else if (var == "XDG_CACHE_HOME") {
|
||||
Filename home_dir = Filename::get_home_directory();
|
||||
return home_dir.get_fullpath() + "/.cache";
|
||||
|
||||
} else if (var == "XDG_DATA_HOME") {
|
||||
Filename home_dir = Filename::get_home_directory();
|
||||
return home_dir.get_fullpath() + "/.local/share";
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
return string();
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ PUBLISHED:
|
|||
|
||||
static Filename get_cwd();
|
||||
|
||||
MAKE_SEQ_PROPERTY(args, get_num_args, get_arg);
|
||||
MAKE_PROPERTY(binary_name, get_binary_name, set_binary_name);
|
||||
MAKE_PROPERTY(dtool_name, get_dtool_name, set_dtool_name);
|
||||
MAKE_PROPERTY(cwd, get_cwd);
|
||||
|
||||
private:
|
||||
bool ns_has_environment_variable(const string &var) const;
|
||||
string ns_get_environment_variable(const string &var) const;
|
||||
|
|
|
|||
|
|
@ -600,8 +600,14 @@ get_user_appdata_directory() {
|
|||
user_appdata_directory.set_basename("files");
|
||||
|
||||
#else
|
||||
// Posix case.
|
||||
user_appdata_directory = get_home_directory();
|
||||
// Posix case. We follow the XDG base directory spec.
|
||||
struct stat st;
|
||||
const char *datadir = getenv("XDG_DATA_HOME");
|
||||
if (datadir != nullptr && stat(datadir, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
user_appdata_directory = datadir;
|
||||
} else {
|
||||
user_appdata_directory = Filename(get_home_directory(), ".local/share");
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
|
|
@ -649,9 +655,10 @@ get_common_appdata_directory() {
|
|||
common_appdata_directory.set_dirname(_internal_data_dir);
|
||||
common_appdata_directory.set_basename("files");
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
common_appdata_directory = "/usr/local/share";
|
||||
#else
|
||||
// Posix case.
|
||||
common_appdata_directory = "/var";
|
||||
common_appdata_directory = "/usr/share";
|
||||
#endif // WIN32
|
||||
|
||||
if (common_appdata_directory.empty()) {
|
||||
|
|
|
|||
|
|
@ -47,20 +47,20 @@ load_dso(const DSearchPath &path, const Filename &filename) {
|
|||
if (!abspath.is_regular_file()) {
|
||||
return NULL;
|
||||
}
|
||||
string os_specific = abspath.to_os_specific();
|
||||
wstring os_specific_w = abspath.to_os_specific_w();
|
||||
|
||||
// Try using LoadLibraryEx, if possible.
|
||||
typedef HMODULE (WINAPI *tLoadLibraryEx)(LPCTSTR, HANDLE, DWORD);
|
||||
typedef HMODULE (WINAPI *tLoadLibraryEx)(LPCWSTR, HANDLE, DWORD);
|
||||
tLoadLibraryEx pLoadLibraryEx;
|
||||
HINSTANCE hLib = LoadLibrary("kernel32.dll");
|
||||
if (hLib) {
|
||||
pLoadLibraryEx = (tLoadLibraryEx)GetProcAddress(hLib, "LoadLibraryExA");
|
||||
pLoadLibraryEx = (tLoadLibraryEx)GetProcAddress(hLib, "LoadLibraryExW");
|
||||
if (pLoadLibraryEx) {
|
||||
return pLoadLibraryEx(os_specific.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
return pLoadLibraryEx(os_specific_w.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
return LoadLibrary(os_specific.c_str());
|
||||
return LoadLibraryW(os_specific_w.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -48,6 +48,21 @@ PUBLISHED:
|
|||
|
||||
static string get_platform();
|
||||
|
||||
MAKE_PROPERTY(version_string, get_version_string);
|
||||
MAKE_PROPERTY(major_version, get_major_version);
|
||||
MAKE_PROPERTY(minor_version, get_minor_version);
|
||||
MAKE_PROPERTY(sequence_version, get_sequence_version);
|
||||
MAKE_PROPERTY(official_version, is_official_version);
|
||||
|
||||
MAKE_PROPERTY(memory_alignment, get_memory_alignment);
|
||||
|
||||
MAKE_PROPERTY(distributor, get_distributor);
|
||||
MAKE_PROPERTY(compiler, get_compiler);
|
||||
MAKE_PROPERTY(build_date, get_build_date);
|
||||
MAKE_PROPERTY(git_commit, get_git_commit);
|
||||
|
||||
MAKE_PROPERTY(platform, get_platform);
|
||||
|
||||
bool has_system(const string &system) const;
|
||||
size_t get_num_systems() const;
|
||||
string get_system(size_t n) const;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ PUBLISHED:
|
|||
|
||||
INLINE static void set_default_encoding(Encoding encoding);
|
||||
INLINE static Encoding get_default_encoding();
|
||||
MAKE_PROPERTY(default_encoding, get_default_encoding, set_default_encoding);
|
||||
|
||||
INLINE void set_text(const string &text);
|
||||
INLINE void set_text(const string &text, Encoding encoding);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,8 @@ Property(const InterrogateElement &ielement) :
|
|||
_setter(NULL),
|
||||
_has_function(NULL),
|
||||
_clear_function(NULL),
|
||||
_deleter(NULL)
|
||||
_deleter(NULL),
|
||||
_has_this(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ public:
|
|||
Function *_has_function;
|
||||
Function *_clear_function;
|
||||
Function *_deleter;
|
||||
bool _has_this;
|
||||
};
|
||||
typedef vector<Property *> Properties;
|
||||
|
||||
|
|
|
|||
|
|
@ -2623,7 +2623,8 @@ write_module_class(ostream &out, Object *obj) {
|
|||
for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
|
||||
Property *property = (*pit);
|
||||
const InterrogateElement &ielem = property->_ielement;
|
||||
if (property->_getter == NULL || !is_function_legal(property->_getter)) {
|
||||
if (!property->_has_this ||
|
||||
property->_getter == NULL || !is_function_legal(property->_getter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -3169,6 +3170,45 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
}
|
||||
|
||||
// Also add the static properties, which can't be added via getset.
|
||||
Properties::const_iterator pit;
|
||||
for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
|
||||
Property *property = (*pit);
|
||||
const InterrogateElement &ielem = property->_ielement;
|
||||
if (property->_has_this ||
|
||||
property->_getter == NULL || !is_function_legal(property->_getter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string name1 = methodNameFromCppName(ielem.get_name(), "", false);
|
||||
// string name2 = methodNameFromCppName(ielem.get_name(), "", true);
|
||||
|
||||
string getter = "&Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter";
|
||||
string setter = "NULL";
|
||||
if (property->_length_function == NULL &&
|
||||
property->_setter != NULL && is_function_legal(property->_setter)) {
|
||||
setter = "&Dtool_" + ClassName + "_" + ielem.get_name() + "_Setter";
|
||||
}
|
||||
|
||||
out << " static const PyGetSetDef def_" << name1 << " = {(char *)\"" << name1 << "\", " << getter << ", " << setter;
|
||||
|
||||
if (ielem.has_comment()) {
|
||||
out << ", (char *)\n";
|
||||
output_quoted(out, 4, ielem.get_comment());
|
||||
out << ",\n ";
|
||||
} else {
|
||||
out << ", NULL, ";
|
||||
}
|
||||
|
||||
// Extra void* argument; we don't make use of it.
|
||||
out << "NULL};\n";
|
||||
|
||||
out << " PyDict_SetItemString(dict, \"" << name1 << "\", Dtool_NewStaticProperty(&Dtool_" << ClassName << "._PyType, &def_" << name1 << "));\n";
|
||||
/* Alternative spelling:
|
||||
out << " PyDict_SetItemString(\"" << name2 << "\", &def_" << name1 << ");\n";
|
||||
*/
|
||||
}
|
||||
|
||||
out << " if (PyType_Ready((PyTypeObject *)&Dtool_" << ClassName << ") < 0) {\n"
|
||||
" Dtool_Raise_TypeError(\"PyType_Ready(" << ClassName << ")\");\n"
|
||||
" return;\n"
|
||||
|
|
@ -6443,11 +6483,15 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
"/**\n"
|
||||
" * sequence getter for property " << cClassName << "::" << ielem.get_name() << "\n"
|
||||
" */\n"
|
||||
"static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getitem(PyObject *self, Py_ssize_t index) {\n"
|
||||
" " << cClassName << " *local_this = NULL;\n"
|
||||
" if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n"
|
||||
" return NULL;\n"
|
||||
" }\n";
|
||||
"static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getitem(PyObject *self, Py_ssize_t index) {\n";
|
||||
if (property->_getter->_has_this ||
|
||||
(property->_has_function && property->_has_function->_has_this)) {
|
||||
out <<
|
||||
" " << cClassName << " *local_this = NULL;\n"
|
||||
" if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n"
|
||||
" return NULL;\n"
|
||||
" }\n";
|
||||
}
|
||||
|
||||
// This is a getitem of a sequence type. This means we *need* to raise
|
||||
// IndexError if we're out of bounds.
|
||||
|
|
@ -6458,8 +6502,12 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
out << " }\n";
|
||||
|
||||
if (property->_has_function != NULL) {
|
||||
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "(index)) {\n"
|
||||
<< " Py_INCREF(Py_None);\n"
|
||||
if (property->_has_function->_has_this) {
|
||||
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "(index)) {\n";
|
||||
} else {
|
||||
out << " if (!" << cClassName << "::" << property->_has_function->_ifunc.get_name() << "(index)) {\n";
|
||||
}
|
||||
out << " Py_INCREF(Py_None);\n"
|
||||
<< " return Py_None;\n"
|
||||
<< " }\n";
|
||||
}
|
||||
|
|
@ -6494,16 +6542,22 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
// Write out a setitem if this is not a read-only property.
|
||||
if (property->_setter != NULL) {
|
||||
out << "static int Dtool_" + ClassName + "_" + ielem.get_name() + "_Setitem(PyObject *self, Py_ssize_t index, PyObject *arg) {\n";
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
|
||||
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
if (property->_has_this) {
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
|
||||
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
}
|
||||
|
||||
out << " if (arg == (PyObject *)NULL) {\n";
|
||||
if (property->_deleter != NULL) {
|
||||
out << " local_this->" << property->_deleter->_ifunc.get_name() << "(index);\n"
|
||||
<< " return 0;\n";
|
||||
if (property->_deleter->_has_this) {
|
||||
out << " local_this->" << property->_deleter->_ifunc.get_name() << "(index);\n";
|
||||
} else {
|
||||
out << " " << cClassName << "::" << property->_deleter->_ifunc.get_name() << "(index);\n";
|
||||
}
|
||||
out << " return 0;\n";
|
||||
} else {
|
||||
out << " Dtool_Raise_TypeError(\"can't delete " << ielem.get_name() << "[] attribute\");\n"
|
||||
" return -1;\n";
|
||||
|
|
@ -6511,9 +6565,13 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
out << " }\n";
|
||||
|
||||
if (property->_clear_function != NULL) {
|
||||
out << " if (arg == Py_None) {\n"
|
||||
<< " local_this->" << property->_clear_function->_ifunc.get_name() << "(index);\n"
|
||||
<< " return 0;\n"
|
||||
out << " if (arg == Py_None) {\n";
|
||||
if (property->_clear_function->_has_this) {
|
||||
out << " local_this->" << property->_clear_function->_ifunc.get_name() << "(index);\n";
|
||||
} else {
|
||||
out << " " << cClassName << "::" << property->_clear_function->_ifunc.get_name() << "(index);\n";
|
||||
}
|
||||
out << " return 0;\n"
|
||||
<< " }\n";
|
||||
}
|
||||
|
||||
|
|
@ -6547,9 +6605,14 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
}
|
||||
|
||||
// Now write the getter, which returns a special wrapper object.
|
||||
out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n"
|
||||
" Py_INCREF(self);\n"
|
||||
" Dtool_SequenceWrapper *wrap = PyObject_New(Dtool_SequenceWrapper, &Dtool_SequenceWrapper_Type);\n"
|
||||
out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
|
||||
if (property->_has_this) {
|
||||
out << " nassertr(self != NULL, NULL);\n"
|
||||
" Py_INCREF(self);\n";
|
||||
} else {
|
||||
out << " Py_XINCREF(self);\n";
|
||||
}
|
||||
out << " Dtool_SequenceWrapper *wrap = PyObject_New(Dtool_SequenceWrapper, &Dtool_SequenceWrapper_Type);\n"
|
||||
" wrap->_base = self;\n"
|
||||
" wrap->_len_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Len;\n"
|
||||
" wrap->_getitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Getitem;\n";
|
||||
|
|
@ -6566,20 +6629,26 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
|
||||
FunctionRemap *remap = property->_getter->_remaps.front();
|
||||
|
||||
if (remap->_const_method) {
|
||||
out << " const " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
|
||||
} else {
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
|
||||
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
|
||||
if (remap->_has_this) {
|
||||
if (remap->_const_method) {
|
||||
out << " const " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
|
||||
} else {
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
|
||||
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
|
||||
}
|
||||
out << " return NULL;\n";
|
||||
out << " }\n\n";
|
||||
}
|
||||
out << " return NULL;\n";
|
||||
out << " }\n\n";
|
||||
|
||||
if (property->_has_function != NULL) {
|
||||
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "()) {\n"
|
||||
<< " Py_INCREF(Py_None);\n"
|
||||
if (remap->_has_this) {
|
||||
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "()) {\n";
|
||||
} else {
|
||||
out << " if (!" << cClassName << "::" << property->_has_function->_ifunc.get_name() << "()) {\n";
|
||||
}
|
||||
out << " Py_INCREF(Py_None);\n"
|
||||
<< " return Py_None;\n"
|
||||
<< " }\n";
|
||||
}
|
||||
|
|
@ -6596,16 +6665,21 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
// Write out a setter if this is not a read-only property.
|
||||
if (property->_setter != NULL) {
|
||||
out << "static int Dtool_" + ClassName + "_" + ielem.get_name() + "_Setter(PyObject *self, PyObject *arg, void *) {\n";
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
|
||||
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
if (remap->_has_this) {
|
||||
out << " " << cClassName << " *local_this = NULL;\n";
|
||||
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
|
||||
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
|
||||
out << " return -1;\n";
|
||||
out << " }\n\n";
|
||||
}
|
||||
|
||||
out << " if (arg == (PyObject *)NULL) {\n";
|
||||
if (property->_deleter != NULL) {
|
||||
if (property->_deleter != NULL && remap->_has_this) {
|
||||
out << " local_this->" << property->_deleter->_ifunc.get_name() << "();\n"
|
||||
<< " return 0;\n";
|
||||
} else if (property->_deleter != NULL) {
|
||||
out << " " << cClassName << "::" << property->_deleter->_ifunc.get_name() << "();\n"
|
||||
<< " return 0;\n";
|
||||
} else {
|
||||
out << " Dtool_Raise_TypeError(\"can't delete " << ielem.get_name() << " attribute\");\n"
|
||||
" return -1;\n";
|
||||
|
|
@ -6613,9 +6687,13 @@ write_getset(ostream &out, Object *obj, Property *property) {
|
|||
out << " }\n";
|
||||
|
||||
if (property->_clear_function != NULL) {
|
||||
out << " if (arg == Py_None) {\n"
|
||||
<< " local_this->" << property->_clear_function->_ifunc.get_name() << "();\n"
|
||||
<< " return 0;\n"
|
||||
out << " if (arg == Py_None) {\n";
|
||||
if (remap->_has_this) {
|
||||
out << " local_this->" << property->_clear_function->_ifunc.get_name() << "();\n";
|
||||
} else {
|
||||
out << " " << cClassName << "::" << property->_clear_function->_ifunc.get_name() << "();\n";
|
||||
}
|
||||
out << " return 0;\n"
|
||||
<< " }\n";
|
||||
}
|
||||
|
||||
|
|
@ -6744,6 +6822,7 @@ record_object(TypeIndex type_index) {
|
|||
Function *setter = record_function(itype, func_index);
|
||||
if (is_function_legal(setter)) {
|
||||
property->_setter = setter;
|
||||
property->_has_this |= setter->_has_this;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6752,6 +6831,7 @@ record_object(TypeIndex type_index) {
|
|||
Function *getter = record_function(itype, func_index);
|
||||
if (is_function_legal(getter)) {
|
||||
property->_getter = getter;
|
||||
property->_has_this |= getter->_has_this;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6760,6 +6840,7 @@ record_object(TypeIndex type_index) {
|
|||
Function *has_function = record_function(itype, func_index);
|
||||
if (is_function_legal(has_function)) {
|
||||
property->_has_function = has_function;
|
||||
property->_has_this |= has_function->_has_this;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6768,6 +6849,7 @@ record_object(TypeIndex type_index) {
|
|||
Function *clear_function = record_function(itype, func_index);
|
||||
if (is_function_legal(clear_function)) {
|
||||
property->_clear_function = clear_function;
|
||||
property->_has_this |= clear_function->_has_this;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6776,12 +6858,16 @@ record_object(TypeIndex type_index) {
|
|||
Function *del_function = record_function(itype, func_index);
|
||||
if (is_function_legal(del_function)) {
|
||||
property->_deleter = del_function;
|
||||
property->_has_this |= del_function->_has_this;
|
||||
}
|
||||
}
|
||||
|
||||
if (ielement.is_sequence()) {
|
||||
FunctionIndex func_index = ielement.get_length_function();
|
||||
property->_length_function = record_function(itype, func_index);
|
||||
if (property->_length_function != nullptr) {
|
||||
property->_has_this |= property->_length_function->_has_this;
|
||||
}
|
||||
}
|
||||
|
||||
if (property->_getter != NULL) {
|
||||
|
|
|
|||
|
|
@ -618,8 +618,11 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
|
|||
dtool_inited = true;
|
||||
|
||||
if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_SequenceWrapper)");
|
||||
return NULL;
|
||||
return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)");
|
||||
}
|
||||
|
||||
if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) {
|
||||
return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)");
|
||||
}
|
||||
|
||||
// Initialize the base class of everything.
|
||||
|
|
@ -1035,7 +1038,7 @@ bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds)
|
|||
static void Dtool_SequenceWrapper_dealloc(PyObject *self) {
|
||||
Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
|
||||
nassertv(wrap);
|
||||
Py_DECREF(wrap->_base);
|
||||
Py_XDECREF(wrap->_base);
|
||||
}
|
||||
|
||||
static Py_ssize_t Dtool_SequenceWrapper_length(PyObject *self) {
|
||||
|
|
@ -1131,4 +1134,136 @@ PyTypeObject Dtool_SequenceWrapper_Type = {
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a variant of the Python getset mechanism that permits static
|
||||
* properties.
|
||||
*/
|
||||
PyObject *
|
||||
Dtool_NewStaticProperty(PyTypeObject *type, const PyGetSetDef *getset) {
|
||||
PyGetSetDescrObject *descr;
|
||||
descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&Dtool_StaticProperty_Type, 0);
|
||||
if (descr != nullptr) {
|
||||
Py_XINCREF(type);
|
||||
descr->d_getset = (PyGetSetDef *)getset;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
descr->d_common.d_type = type;
|
||||
descr->d_common.d_name = PyUnicode_InternFromString(getset->name);
|
||||
#if PY_VERSION_HEX >= 0x03030000
|
||||
descr->d_common.d_qualname = nullptr;
|
||||
#endif
|
||||
#else
|
||||
descr->d_type = type;
|
||||
descr->d_name = PyString_InternFromString(getset->name);
|
||||
#endif
|
||||
}
|
||||
return (PyObject *)descr;
|
||||
}
|
||||
|
||||
static void
|
||||
Dtool_StaticProperty_dealloc(PyDescrObject *descr) {
|
||||
_PyObject_GC_UNTRACK(descr);
|
||||
Py_XDECREF(descr->d_type);
|
||||
Py_XDECREF(descr->d_name);
|
||||
//#if PY_MAJOR_VERSION >= 3
|
||||
// Py_XDECREF(descr->d_qualname);
|
||||
//#endif
|
||||
PyObject_GC_Del(descr);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Dtool_StaticProperty_repr(PyDescrObject *descr, const char *format) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyUnicode_FromFormat("<attribute '%V' of '%s'>", descr->d_name, "?", descr->d_type->tp_name);
|
||||
#else
|
||||
return PyString_FromFormat("<attribute '%V' of '%s'>", descr->d_name, "?", descr->d_type->tp_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
Dtool_StaticProperty_traverse(PyObject *self, visitproc visit, void *arg) {
|
||||
PyDescrObject *descr = (PyDescrObject *)self;
|
||||
Py_VISIT(descr->d_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Dtool_StaticProperty_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) {
|
||||
if (descr->d_getset->get != nullptr) {
|
||||
return descr->d_getset->get(obj, descr->d_getset->closure);
|
||||
} else {
|
||||
return PyErr_Format(PyExc_AttributeError,
|
||||
"attribute '%V' of type '%.100s' is not readable",
|
||||
((PyDescrObject *)descr)->d_name, "?",
|
||||
((PyDescrObject *)descr)->d_type->tp_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
Dtool_StaticProperty_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) {
|
||||
if (descr->d_getset->set != nullptr) {
|
||||
return descr->d_getset->set(obj, value, descr->d_getset->closure);
|
||||
} else {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"attribute '%V' of type '%.100s' is not writable",
|
||||
((PyDescrObject *)descr)->d_name, "?",
|
||||
((PyDescrObject *)descr)->d_type->tp_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
PyTypeObject Dtool_StaticProperty_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"getset_descriptor",
|
||||
sizeof(PyGetSetDescrObject),
|
||||
0, // tp_itemsize
|
||||
(destructor)Dtool_StaticProperty_dealloc,
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_reserved
|
||||
(reprfunc)Dtool_StaticProperty_repr,
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
PyObject_GenericGetAttr,
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT,
|
||||
0, // tp_doc
|
||||
Dtool_StaticProperty_traverse,
|
||||
0, // tp_clear
|
||||
0, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
0, // tp_methods
|
||||
0, // tp_members
|
||||
0, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
(descrgetfunc)Dtool_StaticProperty_get,
|
||||
(descrsetfunc)Dtool_StaticProperty_set,
|
||||
0, // tp_dictoffset
|
||||
0, // tp_init
|
||||
0, // tp_alloc
|
||||
0, // tp_new
|
||||
0, // tp_del
|
||||
0, // tp_is_gc
|
||||
0, // tp_bases
|
||||
0, // tp_mro
|
||||
0, // tp_cache
|
||||
0, // tp_subclasses
|
||||
0, // tp_weaklist
|
||||
0, // tp_del
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
0, // tp_version_tag
|
||||
#endif
|
||||
#if PY_VERSION_HEX >= 0x03040000
|
||||
0, // tp_finalize
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
|
|||
|
|
@ -471,6 +471,9 @@ struct Dtool_SequenceWrapper {
|
|||
};
|
||||
|
||||
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type;
|
||||
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type;
|
||||
|
||||
EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
|
||||
|
||||
/**
|
||||
* These functions check whether the arguments passed to a function conform to
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ extern "C" {
|
|||
EXPCL_PYSTUB int PyObject_Cmp(...);
|
||||
EXPCL_PYSTUB int PyObject_Compare(...);
|
||||
EXPCL_PYSTUB int PyObject_Free(...);
|
||||
EXPCL_PYSTUB int PyObject_GC_Del(...);
|
||||
EXPCL_PYSTUB int PyObject_GenericGetAttr(...);
|
||||
EXPCL_PYSTUB int PyObject_GenericSetAttr(...);
|
||||
EXPCL_PYSTUB int PyObject_GetAttrString(...);
|
||||
|
|
@ -223,6 +224,7 @@ extern "C" {
|
|||
EXPCL_PYSTUB extern void *PyExc_SystemExit;
|
||||
EXPCL_PYSTUB extern void *PyExc_TypeError;
|
||||
EXPCL_PYSTUB extern void *PyExc_ValueError;
|
||||
EXPCL_PYSTUB extern void *PyType_Type;
|
||||
EXPCL_PYSTUB extern void *_PyThreadState_Current;
|
||||
EXPCL_PYSTUB extern void *_Py_FalseStruct;
|
||||
EXPCL_PYSTUB extern void *_Py_NoneStruct;
|
||||
|
|
@ -324,6 +326,7 @@ int PyObject_CallObject(...) { return 0; }
|
|||
int PyObject_Cmp(...) { return 0; }
|
||||
int PyObject_Compare(...) { return 0; }
|
||||
int PyObject_Free(...) { return 0; }
|
||||
int PyObject_GC_Del(...) { return 0; }
|
||||
int PyObject_GenericGetAttr(...) { return 0; };
|
||||
int PyObject_GenericSetAttr(...) { return 0; };
|
||||
int PyObject_GetAttrString(...) { return 0; }
|
||||
|
|
@ -448,6 +451,7 @@ void *PyExc_StopIteration = (void *)NULL;
|
|||
void *PyExc_SystemExit = (void *)NULL;
|
||||
void *PyExc_TypeError = (void *)NULL;
|
||||
void *PyExc_ValueError = (void *)NULL;
|
||||
void *PyType_Type = (void *)NULL;
|
||||
void *_PyThreadState_Current = (void *)NULL;
|
||||
void *_Py_FalseStruct = (void *)NULL;
|
||||
void *_Py_NoneStruct = (void *)NULL;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ hardware-animated-vertices #f
|
|||
|
||||
# Enable the model-cache, but only for models, not textures.
|
||||
|
||||
model-cache-dir $HOME/.panda3d/cache
|
||||
model-cache-dir $XDG_CACHE_HOME/panda3d
|
||||
model-cache-textures #f
|
||||
|
||||
# This option specifies the default profiles for Cg shaders.
|
||||
|
|
|
|||
|
|
@ -1516,7 +1516,9 @@ def CompileLib(lib, obj, opts):
|
|||
if HasTargetArch():
|
||||
cmd += " /MACHINE:" + GetTargetArch().upper()
|
||||
cmd += ' /OUT:' + BracketNameWithQuotes(lib)
|
||||
for x in obj: cmd += ' ' + BracketNameWithQuotes(x)
|
||||
for x in obj:
|
||||
if not x.endswith('.lib'):
|
||||
cmd += ' ' + BracketNameWithQuotes(x)
|
||||
oscmd(cmd)
|
||||
else:
|
||||
# Choose Intel linker; from Jean-Claude
|
||||
|
|
@ -1569,6 +1571,21 @@ def CompileLink(dll, obj, opts):
|
|||
cmd += " /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO "
|
||||
cmd += ' /OUT:' + BracketNameWithQuotes(dll)
|
||||
|
||||
if not PkgSkip("PYTHON"):
|
||||
# If we're building without Python, don't pick it up implicitly.
|
||||
if "PYTHON" not in opts:
|
||||
pythonv = SDK["PYTHONVERSION"].replace('.', '')
|
||||
if optlevel <= 2:
|
||||
cmd += ' /NOD:{}d.lib'.format(pythonv)
|
||||
else:
|
||||
cmd += ' /NOD:{}.lib'.format(pythonv)
|
||||
|
||||
# Yes, we know we are importing "locally defined symbols".
|
||||
for x in obj:
|
||||
if x.endswith('libp3pystub.lib'):
|
||||
cmd += ' /ignore:4049,4217'
|
||||
break
|
||||
|
||||
# Set the subsystem. Specify that we want to target Windows XP.
|
||||
subsystem = GetValueOption(opts, "SUBSYSTEM:") or "CONSOLE"
|
||||
cmd += " /SUBSYSTEM:" + subsystem
|
||||
|
|
@ -2693,7 +2710,7 @@ if '__file__' in locals():
|
|||
import os
|
||||
|
||||
bindir = os.path.join(os.path.dirname(__file__), '..', 'bin')
|
||||
if os.path.isfile(os.path.join(bindir, 'libpanda.dll')):
|
||||
if os.path.isdir(bindir):
|
||||
if not os.environ.get('PATH'):
|
||||
os.environ['PATH'] = bindir
|
||||
else:
|
||||
|
|
@ -2811,12 +2828,12 @@ else:
|
|||
configprc = ReadFile("makepanda/config.in")
|
||||
|
||||
if (GetTarget() == 'windows'):
|
||||
configprc = configprc.replace("$HOME/.panda3d", "$USER_APPDATA/Panda3D-%s" % MAJOR_VERSION)
|
||||
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "$USER_APPDATA/Panda3D-%s" % MAJOR_VERSION)
|
||||
else:
|
||||
configprc = configprc.replace("aux-display pandadx9", "")
|
||||
|
||||
if (GetTarget() == 'darwin'):
|
||||
configprc = configprc.replace(".panda3d/cache", "Library/Caches/Panda3D-%s" % MAJOR_VERSION)
|
||||
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "Library/Caches/Panda3D-%s" % MAJOR_VERSION)
|
||||
|
||||
# OpenAL is not yet working well on OSX for us, so let's do this for now.
|
||||
configprc = configprc.replace("p3openal_audio", "p3fmod_audio")
|
||||
|
|
@ -4900,7 +4917,7 @@ if (PkgSkip("BULLET")==0 and not RUNTIME):
|
|||
#
|
||||
|
||||
if (PkgSkip("PHYSX")==0):
|
||||
OPTS=['DIR:panda/src/physx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC']
|
||||
OPTS=['DIR:panda/src/physx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC', 'PYTHON']
|
||||
TargetAdd('p3physx_composite.obj', opts=OPTS, input='p3physx_composite.cxx')
|
||||
|
||||
OPTS=['DIR:panda/src/physx', 'PHYSX', 'NOARCH:PPC', 'PYTHON']
|
||||
|
|
@ -4920,7 +4937,7 @@ if (PkgSkip("PHYSX")==0):
|
|||
TargetAdd('libpandaphysx.dll', input='pandaphysx_pandaphysx.obj')
|
||||
TargetAdd('libpandaphysx.dll', input='p3physx_composite.obj')
|
||||
TargetAdd('libpandaphysx.dll', input=COMMON_PANDA_LIBS)
|
||||
TargetAdd('libpandaphysx.dll', opts=['WINUSER', 'PHYSX', 'NOARCH:PPC'])
|
||||
TargetAdd('libpandaphysx.dll', opts=['WINUSER', 'PHYSX', 'NOARCH:PPC', 'PYTHON'])
|
||||
|
||||
OPTS=['DIR:panda/metalibs/pandaphysx', 'PHYSX', 'NOARCH:PPC', 'PYTHON']
|
||||
TargetAdd('physx_module.obj', input='libpandaphysx.in')
|
||||
|
|
|
|||
|
|
@ -2422,6 +2422,7 @@ def SetupVisualStudioEnviron():
|
|||
winsdk_ver = SDK["MSPLATFORM_VERSION"]
|
||||
if winsdk_ver.startswith('10.'):
|
||||
AddToPathEnv("PATH", SDK["MSPLATFORM"] + "bin\\" + arch)
|
||||
AddToPathEnv("PATH", SDK["MSPLATFORM"] + "bin\\" + winsdk_ver + "\\" + arch)
|
||||
|
||||
# Windows Kit 10 introduces the "universal CRT".
|
||||
inc_dir = SDK["MSPLATFORM"] + "Include\\" + winsdk_ver + "\\"
|
||||
|
|
@ -3157,6 +3158,17 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
|
|||
for d in CxxCalcDependencies(fullinput, ipath, []):
|
||||
t.deps[d] = 1
|
||||
|
||||
# If we are linking statically, add the source DLL's dynamic dependencies.
|
||||
if GetLinkAllStatic() and ORIG_EXT[fullinput] == '.lib' and fullinput in TARGET_TABLE:
|
||||
tdep = TARGET_TABLE[fullinput]
|
||||
for y in tdep.inputs:
|
||||
if ORIG_EXT[y] == '.lib':
|
||||
t.inputs.append(y)
|
||||
|
||||
for opt, _ in LIBNAMES + LIBDIRECTORIES + FRAMEWORKDIRECTORIES:
|
||||
if opt in tdep.opts and opt not in t.opts:
|
||||
t.opts.append(opt)
|
||||
|
||||
if x.endswith(".in"):
|
||||
# Mark the _igate.cxx file as a dependency also.
|
||||
outbase = os.path.basename(x)[:-3]
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ get_null_sound() {
|
|||
*
|
||||
*/
|
||||
int AudioManager::
|
||||
getSpeakerSetup() {
|
||||
get_speaker_setup() {
|
||||
// intentionally blank
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ getSpeakerSetup() {
|
|||
*
|
||||
*/
|
||||
void AudioManager::
|
||||
setSpeakerSetup(SpeakerModeCategory cat) {
|
||||
set_speaker_setup(SpeakerModeCategory cat) {
|
||||
// intentionally blank
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ PUBLISHED:
|
|||
SM_stream,
|
||||
};
|
||||
|
||||
virtual int getSpeakerSetup();
|
||||
virtual void setSpeakerSetup(SpeakerModeCategory cat);
|
||||
virtual int get_speaker_setup();
|
||||
virtual void set_speaker_setup(SpeakerModeCategory cat);
|
||||
virtual bool configure_filters(FilterProperties *config);
|
||||
|
||||
// Create an AudioManager for each category of sounds you have. E.g.
|
||||
|
|
@ -172,6 +172,7 @@ PUBLISHED:
|
|||
virtual PN_stdfloat audio_3d_get_drop_off_factor() const;
|
||||
|
||||
static Filename get_dls_pathname();
|
||||
MAKE_PROPERTY(dls_pathname, get_dls_pathname);
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out) const;
|
||||
|
|
|
|||
|
|
@ -447,7 +447,7 @@ get_sound(MovieAudio *source, bool positional, int) {
|
|||
* This is to query if you are using a MultiChannel Setup.
|
||||
*/
|
||||
int FmodAudioManager::
|
||||
getSpeakerSetup() {
|
||||
get_speaker_setup() {
|
||||
ReMutexHolder holder(_lock);
|
||||
FMOD_RESULT result;
|
||||
FMOD_SPEAKERMODE speakerMode;
|
||||
|
|
@ -502,7 +502,7 @@ getSpeakerSetup() {
|
|||
* init or re-init the AudioManagers after Panda is running.
|
||||
*/
|
||||
void FmodAudioManager::
|
||||
setSpeakerSetup(AudioManager::SpeakerModeCategory cat) {
|
||||
set_speaker_setup(AudioManager::SpeakerModeCategory cat) {
|
||||
ReMutexHolder holder(_lock);
|
||||
FMOD_RESULT result;
|
||||
FMOD_SPEAKERMODE speakerModeType = (FMOD_SPEAKERMODE)cat;
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ public:
|
|||
virtual PT(AudioSound) get_sound(const string&, bool positional = false, int mode=SM_heuristic);
|
||||
virtual PT(AudioSound) get_sound(MovieAudio *, bool positional = false, int mode=SM_heuristic);
|
||||
|
||||
virtual int getSpeakerSetup();
|
||||
virtual void setSpeakerSetup(SpeakerModeCategory cat);
|
||||
virtual int get_speaker_setup();
|
||||
virtual void set_speaker_setup(SpeakerModeCategory cat);
|
||||
|
||||
virtual void set_volume(PN_stdfloat);
|
||||
virtual PN_stdfloat get_volume() const;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ BulletHeightfieldShape(const BulletHeightfieldShape ©) :
|
|||
_num_rows(copy._num_rows),
|
||||
_num_cols(copy._num_cols) {
|
||||
|
||||
_data = new float[_num_rows * _num_cols];
|
||||
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(float));
|
||||
_data = new btScalar[_num_rows * _num_cols];
|
||||
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(btScalar));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +44,6 @@ operator = (const BulletHeightfieldShape ©) {
|
|||
_num_rows = copy._num_rows;
|
||||
_num_cols = copy._num_cols;
|
||||
|
||||
_data = new float[_num_rows * _num_cols];
|
||||
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(float));
|
||||
_data = new btScalar[_num_rows * _num_cols];
|
||||
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(btScalar));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ BulletHeightfieldShape(const PNMImage &image, PN_stdfloat max_height, BulletUpAx
|
|||
_num_rows = image.get_x_size();
|
||||
_num_cols = image.get_y_size();
|
||||
|
||||
_data = new float[_num_rows * _num_cols];
|
||||
_data = new btScalar[_num_rows * _num_cols];
|
||||
|
||||
for (int row=0; row < _num_rows; row++) {
|
||||
for (int column=0; column < _num_cols; column++) {
|
||||
|
|
@ -75,10 +75,10 @@ BulletHeightfieldShape(Texture *tex, PN_stdfloat max_height, BulletUpAxis up) {
|
|||
|
||||
_num_rows = tex->get_x_size() + 1;
|
||||
_num_cols = tex->get_y_size() + 1;
|
||||
_data = new float[_num_rows * _num_cols];
|
||||
_data = new btScalar[_num_rows * _num_cols];
|
||||
|
||||
PN_stdfloat step_x = 1.0 / (PN_stdfloat)tex->get_x_size();
|
||||
PN_stdfloat step_y = 1.0 / (PN_stdfloat)tex->get_y_size();
|
||||
btScalar step_x = 1.0 / (btScalar)tex->get_x_size();
|
||||
btScalar step_y = 1.0 / (btScalar)tex->get_y_size();
|
||||
|
||||
PT(TexturePeeker) peeker = tex->peek();
|
||||
LColor sample;
|
||||
|
|
@ -100,4 +100,4 @@ BulletHeightfieldShape(Texture *tex, PN_stdfloat max_height, BulletUpAxis up) {
|
|||
up,
|
||||
true, false);
|
||||
_shape->setUserPointer(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public:
|
|||
private:
|
||||
int _num_rows;
|
||||
int _num_cols;
|
||||
float *_data;
|
||||
btScalar *_data;
|
||||
btHeightfieldTerrainShape *_shape;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ void BulletTriangleMesh::
|
|||
preallocate(int num_verts, int num_indices) {
|
||||
_vertices.reserve(num_verts);
|
||||
_indices.reserve(num_indices);
|
||||
|
||||
btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
|
||||
mesh.m_vertexBase = (unsigned char*)&_vertices[0];
|
||||
mesh.m_triangleIndexBase = (unsigned char *)&_indices[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -160,12 +164,22 @@ add_geom(const Geom *geom, bool remove_duplicate_vertices, const TransformState
|
|||
_indices.reserve(_indices.size() + num_vertices);
|
||||
mesh.m_numTriangles += num_vertices / 3;
|
||||
|
||||
GeomVertexReader index(prim->get_vertices(), 0);
|
||||
while (!index.is_at_end()) {
|
||||
_indices.push_back(index_offset + index.get_data1i());
|
||||
CPT(GeomVertexArrayData) vertices = prim->get_vertices();
|
||||
if (vertices != nullptr) {
|
||||
GeomVertexReader index(move(vertices), 0);
|
||||
while (!index.is_at_end()) {
|
||||
_indices.push_back(index_offset + index.get_data1i());
|
||||
}
|
||||
} else {
|
||||
int index = index_offset + prim->get_first_vertex();
|
||||
int end_index = index + num_vertices;
|
||||
while (index < end_index) {
|
||||
_indices.push_back(index++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nassertv(mesh.m_numTriangles * 3 == _indices.size());
|
||||
|
||||
} else {
|
||||
// Collect points
|
||||
|
|
@ -193,12 +207,22 @@ add_geom(const Geom *geom, bool remove_duplicate_vertices, const TransformState
|
|||
_indices.reserve(_indices.size() + num_vertices);
|
||||
mesh.m_numTriangles += num_vertices / 3;
|
||||
|
||||
GeomVertexReader index(prim->get_vertices(), 0);
|
||||
while (!index.is_at_end()) {
|
||||
_indices.push_back(find_or_add_vertex(points[index.get_data1i()]));
|
||||
CPT(GeomVertexArrayData) vertices = prim->get_vertices();
|
||||
if (vertices != nullptr) {
|
||||
GeomVertexReader index(move(vertices), 0);
|
||||
while (!index.is_at_end()) {
|
||||
_indices.push_back(find_or_add_vertex(points[index.get_data1i()]));
|
||||
}
|
||||
} else {
|
||||
int index = prim->get_first_vertex();
|
||||
int end_index = index + num_vertices;
|
||||
while (index < end_index) {
|
||||
_indices.push_back(find_or_add_vertex(points[index]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nassertv(mesh.m_numTriangles * 3 == _indices.size());
|
||||
}
|
||||
|
||||
// Reset the pointers, since the vectors may have been reallocated.
|
||||
|
|
@ -282,7 +306,7 @@ unsigned int BulletTriangleMesh::
|
|||
find_or_add_vertex(const LVecBase3 &p) {
|
||||
btVector3 vertex = LVecBase3_to_btVector3(p);
|
||||
|
||||
for (unsigned int i = 0; i < _vertices.size(); ++i) {
|
||||
for (int i = 0; i < _vertices.size(); ++i) {
|
||||
if ((_vertices[i] - vertex).length2() <= _welding_distance) {
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,7 +277,21 @@ process_events() {
|
|||
break;
|
||||
}
|
||||
|
||||
[NSApp sendEvent: event];
|
||||
// If we're in fullscreen mode, send mouse events directly to the window.
|
||||
NSEventType type = [event type];
|
||||
if (_properties.get_fullscreen() && (
|
||||
type == NSLeftMouseDown || type == NSLeftMouseUp ||
|
||||
type == NSRightMouseDown || type == NSRightMouseUp ||
|
||||
type == NSOtherMouseDown || type == NSOtherMouseUp ||
|
||||
type == NSLeftMouseDragged ||
|
||||
type == NSRightMouseDragged ||
|
||||
type == NSOtherMouseDragged ||
|
||||
type == NSMouseMoved ||
|
||||
type == NSScrollWheel)) {
|
||||
[_window sendEvent: event];
|
||||
} else {
|
||||
[NSApp sendEvent: event];
|
||||
}
|
||||
}
|
||||
|
||||
if (_window != nil) {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ PUBLISHED:
|
|||
MAKE_PROPERTY(collider_sort, get_collider_sort, set_collider_sort);
|
||||
|
||||
INLINE static CollideMask get_default_collide_mask();
|
||||
MAKE_PROPERTY(default_collide_mask, get_default_collide_mask);
|
||||
|
||||
protected:
|
||||
virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ draw(bool force, Thread *current_thread) {
|
|||
data_reader.set_object(object->_munged_data);
|
||||
data_reader.check_array_readers();
|
||||
geom_reader.set_object(object->_geom);
|
||||
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
|
||||
geom_reader.draw(_gsg, &data_reader, force);
|
||||
} else {
|
||||
// It has a callback associated.
|
||||
object->draw_callback(_gsg, force, current_thread);
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ draw(bool force, Thread *current_thread) {
|
|||
data_reader.set_object(object->_munged_data);
|
||||
data_reader.check_array_readers();
|
||||
geom_reader.set_object(object->_geom);
|
||||
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
|
||||
geom_reader.draw(_gsg, &data_reader, force);
|
||||
} else {
|
||||
// It has a callback associated.
|
||||
object->draw_callback(_gsg, force, current_thread);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ draw(bool force, Thread *current_thread) {
|
|||
data_reader.set_object(object->_munged_data);
|
||||
data_reader.check_array_readers();
|
||||
geom_reader.set_object(object->_geom);
|
||||
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
|
||||
geom_reader.draw(_gsg, &data_reader, force);
|
||||
} else {
|
||||
// It has a callback associated.
|
||||
object->draw_callback(_gsg, force, current_thread);
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ draw(bool force, Thread *current_thread) {
|
|||
data_reader.set_object(object->_munged_data);
|
||||
data_reader.check_array_readers();
|
||||
geom_reader.set_object(object->_geom);
|
||||
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
|
||||
geom_reader.draw(_gsg, &data_reader, force);
|
||||
} else {
|
||||
// It has a callback associated.
|
||||
object->draw_callback(_gsg, force, current_thread);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ draw(bool force, Thread *current_thread) {
|
|||
data_reader.set_object(object->_munged_data);
|
||||
data_reader.check_array_readers();
|
||||
geom_reader.set_object(object->_geom);
|
||||
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
|
||||
geom_reader.draw(_gsg, &data_reader, force);
|
||||
} else {
|
||||
// It has a callback associated.
|
||||
object->draw_callback(_gsg, force, current_thread);
|
||||
|
|
|
|||
|
|
@ -581,9 +581,13 @@ get_quality(const FrameBufferProperties &reqs) const {
|
|||
}
|
||||
}
|
||||
|
||||
// Bonus for each depth bit. Extra: 2 per bit.
|
||||
// Bonus for each depth bit. Extra: 8 per bit.
|
||||
// Please note that the Intel Windows driver only gives extra depth in
|
||||
// combination with a stencil buffer, so we need 8 extra depth bits to
|
||||
// outweigh the penalty of 50 for the unwanted stencil buffer, otherwise we
|
||||
// will end up only getting 16-bit depth.
|
||||
if (reqs._property[FBP_depth_bits] != 0) {
|
||||
quality += 2 * _property[FBP_depth_bits];
|
||||
quality += 8 * _property[FBP_depth_bits];
|
||||
}
|
||||
|
||||
// Bonus for each multisample. Extra: 2 per sample.
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "ambientLight.h"
|
||||
#include "directionalLight.h"
|
||||
#include "pointLight.h"
|
||||
#include "sphereLight.h"
|
||||
#include "spotlight.h"
|
||||
#include "textureReloadRequest.h"
|
||||
#include "shaderAttrib.h"
|
||||
|
|
@ -1122,6 +1123,28 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
return &LMatrix4::ident_mat();
|
||||
}
|
||||
}
|
||||
case Shader::SMO_texscale_i: {
|
||||
const TexMatrixAttrib *tma;
|
||||
const TextureAttrib *ta;
|
||||
if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
|
||||
index < ta->get_num_on_stages()) {
|
||||
LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale();
|
||||
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,scale[0],scale[1],scale[2],0);
|
||||
return &t;
|
||||
} else {
|
||||
return &LMatrix4::ident_mat();
|
||||
}
|
||||
}
|
||||
case Shader::SMO_texcolor_i: {
|
||||
const TextureAttrib *ta;
|
||||
if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) {
|
||||
TextureStage *ts = ta->get_on_stage(index);
|
||||
t.set_row(3, ts->get_color());
|
||||
return &t;
|
||||
} else {
|
||||
return &LMatrix4::zeros_mat();
|
||||
}
|
||||
}
|
||||
case Shader::SMO_tex_is_alpha_i: {
|
||||
// This is a hack so we can support both F_alpha and other formats in the
|
||||
// default shader, to fix font rendering in GLES2
|
||||
|
|
@ -1156,9 +1179,14 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
|
||||
const PlaneNode *plane_node;
|
||||
DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat());
|
||||
LPlane p (plane_node->get_plane());
|
||||
p.xform(np.get_net_transform()->get_mat()); // World-space
|
||||
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
|
||||
|
||||
// Transform plane to world space
|
||||
CPT(TransformState) transform = np.get_net_transform();
|
||||
LPlane plane = plane_node->get_plane();
|
||||
if (!transform->is_identity()) {
|
||||
plane.xform(transform->get_mat());
|
||||
}
|
||||
t.set_row(3, plane);
|
||||
return &t;
|
||||
}
|
||||
case Shader::SMO_apiview_clipplane_i: {
|
||||
|
|
@ -1195,7 +1223,6 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
}
|
||||
case Shader::SMO_world_to_view: {
|
||||
return &(_scene_setup->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case Shader::SMO_view_to_world: {
|
||||
return &(_scene_setup->get_camera_transform()->get_mat());
|
||||
|
|
@ -1387,6 +1414,62 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
}
|
||||
return fetch_specified_member(NodePath(), name, t);
|
||||
}
|
||||
case Shader::SMO_light_source_i_packed: {
|
||||
// The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR
|
||||
const LightAttrib *target_light;
|
||||
_target_rs->get_attrib_def(target_light);
|
||||
|
||||
// We don't count ambient lights, which would be pretty silly to handle
|
||||
// via this mechanism.
|
||||
size_t num_lights = target_light->get_num_non_ambient_lights();
|
||||
if (index >= 0 && (size_t)index < num_lights) {
|
||||
NodePath np = target_light->get_on_light((size_t)index);
|
||||
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
|
||||
PandaNode *node = np.node();
|
||||
Light *light = node->as_light();
|
||||
nassertr(light != nullptr, &LMatrix4::zeros_mat());
|
||||
t.set_row(0, light->get_color());
|
||||
t.set_row(1, light->get_attenuation());
|
||||
|
||||
LMatrix4 mat = np.get_net_transform()->get_mat() *
|
||||
_scene_setup->get_world_transform()->get_mat();
|
||||
|
||||
if (node->is_of_type(DirectionalLight::get_class_type())) {
|
||||
LVecBase3 d = mat.xform_vec(((const DirectionalLight *)node)->get_direction());
|
||||
d.normalize();
|
||||
t.set_row(2, LVecBase4(d, 0));
|
||||
t.set_row(3, LVecBase4(-d, 0));
|
||||
|
||||
} else if (node->is_of_type(LightLensNode::get_class_type())) {
|
||||
const Lens *lens = ((const LightLensNode *)node)->get_lens();
|
||||
|
||||
LPoint3 p = mat.xform_point(lens->get_nodal_point());
|
||||
t.set_row(3, LVecBase4(p));
|
||||
|
||||
// For shadowed point light we need to store near/far.
|
||||
// For spotlight we need to store cutoff angle.
|
||||
if (node->is_of_type(Spotlight::get_class_type())) {
|
||||
PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
|
||||
LVecBase3 d = -(mat.xform_vec(lens->get_view_vector()));
|
||||
t.set_cell(1, 3, ((const Spotlight *)node)->get_exponent());
|
||||
t.set_row(2, LVecBase4(d, cutoff));
|
||||
|
||||
} else if (node->is_of_type(PointLight::get_class_type())) {
|
||||
t.set_cell(1, 3, lens->get_far());
|
||||
t.set_cell(3, 3, lens->get_near());
|
||||
|
||||
if (node->is_of_type(SphereLight::get_class_type())) {
|
||||
t.set_cell(2, 3, ((const SphereLight *)node)->get_radius());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (index == 0) {
|
||||
// Apply the default OpenGL lights otherwise.
|
||||
// Special exception for light 0, which defaults to white.
|
||||
t.set_row(0, _light_color_scale);
|
||||
}
|
||||
return &t;
|
||||
}
|
||||
default:
|
||||
nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
|
||||
return &LMatrix4::ident_mat();
|
||||
|
|
@ -2263,10 +2346,8 @@ finish_decal() {
|
|||
*/
|
||||
bool GraphicsStateGuardian::
|
||||
begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force) {
|
||||
_munger = munger;
|
||||
_data_reader = data_reader;
|
||||
|
||||
// Always draw if we have a shader, since the shader might use a different
|
||||
|
|
@ -2337,7 +2418,6 @@ draw_points(const GeomPrimitivePipelineReader *, bool) {
|
|||
*/
|
||||
void GraphicsStateGuardian::
|
||||
end_draw_primitives() {
|
||||
_munger = NULL;
|
||||
_data_reader = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -367,7 +367,6 @@ public:
|
|||
virtual void finish_decal();
|
||||
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force);
|
||||
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader,
|
||||
|
|
@ -496,9 +495,8 @@ protected:
|
|||
CPT(ShaderAttrib) _state_shader;
|
||||
CPT(ShaderAttrib) _target_shader;
|
||||
|
||||
// These are set by begin_draw_primitives(), and are only valid between
|
||||
// This is set by begin_draw_primitives(), and are only valid between
|
||||
// begin_draw_primitives() and end_draw_primitives().
|
||||
CPT(GeomMunger) _munger;
|
||||
const GeomVertexDataPipelineReader *_data_reader;
|
||||
|
||||
unsigned int _color_write_mask;
|
||||
|
|
|
|||
|
|
@ -343,28 +343,29 @@ munge_state_impl(const RenderState *state) {
|
|||
|
||||
#ifdef HAVE_CG
|
||||
if (_auto_shader) {
|
||||
CPT(RenderState) shader_state = munged_state->get_auto_shader_state();
|
||||
GraphicsStateGuardian *gsg = get_gsg();
|
||||
ShaderGenerator *shader_generator = gsg->get_shader_generator();
|
||||
if (shader_generator == nullptr) {
|
||||
shader_generator = new ShaderGenerator(gsg);
|
||||
gsg->set_shader_generator(shader_generator);
|
||||
}
|
||||
if (shader_state->_generated_shader == NULL) {
|
||||
if (munged_state->_generated_shader == nullptr) {
|
||||
// Cache the generated ShaderAttrib on the shader state.
|
||||
GeomVertexAnimationSpec spec;
|
||||
|
||||
// Currently we overload this flag to request vertex animation for the
|
||||
// shader generator.
|
||||
const ShaderAttrib *sattr;
|
||||
shader_state->get_attrib_def(sattr);
|
||||
munged_state->get_attrib_def(sattr);
|
||||
if (sattr->get_flag(ShaderAttrib::F_hardware_skinning)) {
|
||||
spec.set_hardware(4, true);
|
||||
}
|
||||
|
||||
shader_state->_generated_shader = shader_generator->synthesize_shader(shader_state, spec);
|
||||
munged_state->_generated_shader = shader_generator->synthesize_shader(munged_state, spec);
|
||||
}
|
||||
if (munged_state->_generated_shader != nullptr) {
|
||||
munged_state = munged_state->set_attrib(munged_state->_generated_shader);
|
||||
}
|
||||
munged_state = munged_state->set_attrib(shader_state->_generated_shader);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ PUBLISHED:
|
|||
static WindowProperties get_default();
|
||||
static void set_default(const WindowProperties &default_properties);
|
||||
static void clear_default();
|
||||
MAKE_PROPERTY(config_properties, get_config_properties);
|
||||
MAKE_PROPERTY(default, get_default, set_default);
|
||||
|
||||
static WindowProperties size(int x_size, int y_size);
|
||||
|
||||
|
|
|
|||
|
|
@ -1141,11 +1141,9 @@ end_frame(Thread *current_thread) {
|
|||
*/
|
||||
bool DXGraphicsStateGuardian9::
|
||||
begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger,
|
||||
data_reader, force)) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, data_reader, force)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ public:
|
|||
virtual void end_frame(Thread *current_thread);
|
||||
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force);
|
||||
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader,
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ PUBLISHED:
|
|||
INLINE EggLine &operator = (const EggLine ©);
|
||||
virtual ~EggLine();
|
||||
|
||||
virtual EggLine *make_copy() const OVERRIDE;
|
||||
virtual EggLine *make_copy() const override;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
|
||||
INLINE bool has_thick() const;
|
||||
INLINE double get_thick() const;
|
||||
|
|
@ -39,7 +39,7 @@ PUBLISHED:
|
|||
INLINE void clear_thick();
|
||||
|
||||
protected:
|
||||
virtual int get_num_lead_vertices() const OVERRIDE;
|
||||
virtual int get_num_lead_vertices() const override;
|
||||
|
||||
private:
|
||||
double _thick;
|
||||
|
|
@ -54,10 +54,10 @@ public:
|
|||
register_type(_type_handle, "EggLine",
|
||||
EggCompositePrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ PUBLISHED:
|
|||
INLINE EggNurbsCurve(const EggNurbsCurve ©);
|
||||
INLINE EggNurbsCurve &operator = (const EggNurbsCurve ©);
|
||||
|
||||
virtual EggNurbsCurve *make_copy() const OVERRIDE;
|
||||
virtual EggNurbsCurve *make_copy() const override;
|
||||
|
||||
void setup(int order, int num_knots);
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ PUBLISHED:
|
|||
INLINE double get_knot(int k) const;
|
||||
MAKE_SEQ(get_knots, get_num_knots, get_knot);
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
|
||||
MAKE_PROPERTY(order, get_order, set_order);
|
||||
MAKE_PROPERTY(degree, get_degree);
|
||||
|
|
@ -72,10 +72,10 @@ public:
|
|||
register_type(_type_handle, "EggNurbsCurve",
|
||||
EggCurve::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ PUBLISHED:
|
|||
INLINE EggNurbsSurface(const EggNurbsSurface ©);
|
||||
INLINE EggNurbsSurface &operator = (const EggNurbsSurface ©);
|
||||
|
||||
virtual EggNurbsSurface *make_copy() const OVERRIDE;
|
||||
virtual EggNurbsSurface *make_copy() const override;
|
||||
|
||||
void setup(int u_order, int v_order,
|
||||
int num_u_knots, int num_v_knots);
|
||||
|
|
@ -75,14 +75,14 @@ PUBLISHED:
|
|||
MAKE_SEQ(get_v_knots, get_num_v_knots, get_v_knot);
|
||||
INLINE EggVertex *get_cv(int ui, int vi) const;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
|
||||
public:
|
||||
Curves _curves_on_surface;
|
||||
Trims _trims;
|
||||
|
||||
protected:
|
||||
virtual void r_apply_texmats(EggTextureCollection &textures) OVERRIDE;
|
||||
virtual void r_apply_texmats(EggTextureCollection &textures) override;
|
||||
|
||||
private:
|
||||
typedef vector_double Knots;
|
||||
|
|
@ -101,10 +101,10 @@ public:
|
|||
register_type(_type_handle, "EggNurbsSurface",
|
||||
EggSurface::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ PUBLISHED:
|
|||
INLINE EggPatch(const EggPatch ©);
|
||||
INLINE EggPatch &operator = (const EggPatch ©);
|
||||
|
||||
virtual EggPatch *make_copy() const OVERRIDE;
|
||||
virtual EggPatch *make_copy() const override;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -41,10 +41,10 @@ public:
|
|||
register_type(_type_handle, "EggPatch",
|
||||
EggPrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ PUBLISHED:
|
|||
INLINE EggPoint(const EggPoint ©);
|
||||
INLINE EggPoint &operator = (const EggPoint ©);
|
||||
|
||||
virtual EggPoint *make_copy() const OVERRIDE;
|
||||
virtual EggPoint *make_copy() const override;
|
||||
|
||||
INLINE bool has_thick() const;
|
||||
INLINE double get_thick() const;
|
||||
|
|
@ -40,9 +40,9 @@ PUBLISHED:
|
|||
INLINE void set_perspective(bool perspective);
|
||||
INLINE void clear_perspective();
|
||||
|
||||
virtual bool cleanup() OVERRIDE;
|
||||
virtual bool cleanup() override;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
|
||||
private:
|
||||
enum Flags {
|
||||
|
|
@ -64,10 +64,10 @@ public:
|
|||
register_type(_type_handle, "EggPoint",
|
||||
EggPrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ PUBLISHED:
|
|||
INLINE EggPolygon(const EggPolygon ©);
|
||||
INLINE EggPolygon &operator = (const EggPolygon ©);
|
||||
|
||||
virtual EggPolygon *make_copy() const OVERRIDE;
|
||||
virtual EggPolygon *make_copy() const override;
|
||||
|
||||
virtual bool cleanup() OVERRIDE;
|
||||
virtual bool cleanup() override;
|
||||
|
||||
bool calculate_normal(LNormald &result, CoordinateSystem cs = CS_default) const;
|
||||
bool is_planar() const;
|
||||
|
|
@ -39,7 +39,7 @@ PUBLISHED:
|
|||
INLINE bool triangulate_into(EggGroupNode *container, bool convex_also) const;
|
||||
PT(EggPolygon) triangulate_in_place(bool convex_also);
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
|
||||
private:
|
||||
bool decomp_concave(EggGroupNode *container, int asum, int x, int y) const;
|
||||
|
|
@ -55,10 +55,10 @@ public:
|
|||
register_type(_type_handle, "EggPolygon",
|
||||
EggPrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ PUBLISHED:
|
|||
INLINE EggTriangleFan &operator = (const EggTriangleFan ©);
|
||||
virtual ~EggTriangleFan();
|
||||
|
||||
virtual EggTriangleFan *make_copy() const OVERRIDE;
|
||||
virtual EggTriangleFan *make_copy() const override;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void apply_first_attribute() OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
virtual void apply_first_attribute() override;
|
||||
|
||||
protected:
|
||||
virtual int get_num_lead_vertices() const OVERRIDE;
|
||||
virtual bool do_triangulate(EggGroupNode *container) const OVERRIDE;
|
||||
virtual int get_num_lead_vertices() const override;
|
||||
virtual bool do_triangulate(EggGroupNode *container) const override;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -47,10 +47,10 @@ public:
|
|||
register_type(_type_handle, "EggTriangleFan",
|
||||
EggCompositePrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ PUBLISHED:
|
|||
INLINE EggTriangleStrip &operator = (const EggTriangleStrip ©);
|
||||
virtual ~EggTriangleStrip();
|
||||
|
||||
virtual EggTriangleStrip *make_copy() const OVERRIDE;
|
||||
virtual EggTriangleStrip *make_copy() const override;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const OVERRIDE;
|
||||
virtual void write(ostream &out, int indent_level) const override;
|
||||
|
||||
protected:
|
||||
virtual int get_num_lead_vertices() const OVERRIDE;
|
||||
virtual bool do_triangulate(EggGroupNode *container) const OVERRIDE;
|
||||
virtual int get_num_lead_vertices() const override;
|
||||
virtual bool do_triangulate(EggGroupNode *container) const override;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -46,10 +46,10 @@ public:
|
|||
register_type(_type_handle, "EggTriangleStrip",
|
||||
EggCompositePrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {
|
||||
virtual TypeHandle force_init_type() override {
|
||||
init_type();
|
||||
return get_class_type();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ private:
|
|||
|
||||
#include "memoryInfo.I"
|
||||
|
||||
#else
|
||||
class MemoryInfo;
|
||||
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@
|
|||
* to true, indicating that this class will be in effect. If this returns
|
||||
* false, the user has indicated not to do any of this.
|
||||
*/
|
||||
INLINE bool MemoryUsage::
|
||||
ALWAYS_INLINE bool MemoryUsage::
|
||||
get_track_memory_usage() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return get_global_ptr()->_track_memory_usage;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -26,7 +30,19 @@ get_track_memory_usage() {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
record_pointer(ReferenceCount *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_record_pointer(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the given pointer has been recently allocated.
|
||||
*/
|
||||
INLINE void MemoryUsage::
|
||||
record_pointer(void *ptr, TypeHandle type) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_record_pointer(ptr, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,7 +53,9 @@ record_pointer(ReferenceCount *ptr) {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
update_type(ReferenceCount *ptr, TypeHandle type) {
|
||||
get_global_ptr()->ns_update_type(ptr, type);
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_update_type((void *)ptr, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -48,7 +66,21 @@ update_type(ReferenceCount *ptr, TypeHandle type) {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
|
||||
get_global_ptr()->ns_update_type(ptr, typed_ptr);
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_update_type((void *)ptr, typed_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the indicated type with the given pointer. This should be
|
||||
* called by functions (e.g. the constructor) that know more specifically
|
||||
* what type of thing we've got.
|
||||
*/
|
||||
INLINE void MemoryUsage::
|
||||
update_type(void *ptr, TypeHandle type) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_update_type(ptr, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -56,7 +88,9 @@ update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
remove_pointer(ReferenceCount *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_remove_pointer(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -65,7 +99,11 @@ remove_pointer(ReferenceCount *ptr) {
|
|||
*/
|
||||
INLINE bool MemoryUsage::
|
||||
is_tracking() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return get_global_ptr()->_track_memory_usage;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,7 +113,11 @@ is_tracking() {
|
|||
*/
|
||||
INLINE bool MemoryUsage::
|
||||
is_counting() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return get_global_ptr()->_count_memory_usage;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -84,7 +126,11 @@ is_counting() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_current_cpp_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return get_global_ptr()->_current_cpp_size;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,7 +139,11 @@ get_current_cpp_size() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_total_cpp_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return get_global_ptr()->_total_cpp_size;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -102,7 +152,11 @@ get_total_cpp_size() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_panda_heap_single_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_single_size);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -111,7 +165,11 @@ get_panda_heap_single_size() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_panda_heap_array_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_array_size);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,7 +179,7 @@ get_panda_heap_array_size() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_panda_heap_overhead() {
|
||||
#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
|
||||
#if defined(DO_MEMORY_USAGE) && (defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2))
|
||||
MemoryUsage *mu = get_global_ptr();
|
||||
return (size_t)(AtomicAdjust::get(mu->_requested_heap_size) - AtomicAdjust::get(mu->_total_heap_single_size) - AtomicAdjust::get(mu->_total_heap_array_size));
|
||||
#else
|
||||
|
|
@ -135,7 +193,11 @@ get_panda_heap_overhead() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_panda_mmap_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_mmap_size);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,6 +214,7 @@ get_panda_mmap_size() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_external_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
MemoryUsage *mu = get_global_ptr();
|
||||
if (mu->_count_memory_usage) {
|
||||
// We can only possibly know this with memory counting, which tracks every
|
||||
|
|
@ -169,6 +232,9 @@ get_external_size() {
|
|||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -177,6 +243,7 @@ get_external_size() {
|
|||
*/
|
||||
INLINE size_t MemoryUsage::
|
||||
get_total_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
MemoryUsage *mu = get_global_ptr();
|
||||
if (mu->_count_memory_usage) {
|
||||
return mu->_total_size + (size_t)mu->_requested_heap_size;
|
||||
|
|
@ -187,6 +254,9 @@ get_total_size() {
|
|||
return (size_t)(AtomicAdjust::get(mu->_total_heap_single_size) + AtomicAdjust::get(mu->_total_heap_array_size));
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -194,7 +264,11 @@ get_total_size() {
|
|||
*/
|
||||
INLINE int MemoryUsage::
|
||||
get_num_pointers() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return get_global_ptr()->ns_get_num_pointers();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -203,7 +277,9 @@ get_num_pointers() {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
get_pointers(MemoryUsagePointers &result) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_get_pointers(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -212,7 +288,9 @@ get_pointers(MemoryUsagePointers &result) {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_get_pointers_of_type(result, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -221,7 +299,9 @@ get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
get_pointers_of_age(MemoryUsagePointers &result, double from, double to) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_get_pointers_of_age(result, from, to);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -242,7 +322,9 @@ get_pointers_of_age(MemoryUsagePointers &result, double from, double to) {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
get_pointers_with_zero_count(MemoryUsagePointers &result) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_get_pointers_with_zero_count(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -253,7 +335,9 @@ get_pointers_with_zero_count(MemoryUsagePointers &result) {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
freeze() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_freeze();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -261,7 +345,9 @@ freeze() {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
show_current_types() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_show_current_types();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -270,7 +356,9 @@ show_current_types() {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
show_trend_types() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_show_trend_types();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -278,7 +366,9 @@ show_trend_types() {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
show_current_ages() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_show_current_ages();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -287,7 +377,9 @@ show_current_ages() {
|
|||
*/
|
||||
INLINE void MemoryUsage::
|
||||
show_trend_ages() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
get_global_ptr()->ns_show_trend_ages();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -295,6 +387,7 @@ show_trend_ages() {
|
|||
*/
|
||||
INLINE MemoryUsage *MemoryUsage::
|
||||
get_global_ptr() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
#ifdef __GNUC__
|
||||
// Tell the compiler that this is an unlikely branch.
|
||||
if (__builtin_expect(_global_ptr == nullptr, 0)) {
|
||||
|
|
@ -305,4 +398,7 @@ get_global_ptr() {
|
|||
}
|
||||
|
||||
return _global_ptr;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
*/
|
||||
|
||||
#include "memoryUsage.h"
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
||||
#include "memoryUsagePointers.h"
|
||||
#include "trueClock.h"
|
||||
#include "typedReferenceCount.h"
|
||||
|
|
@ -45,16 +42,17 @@ double MemoryUsage::AgeHistogram::_cutoff[MemoryUsage::AgeHistogram::num_buckets
|
|||
60.0,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a single entry to the histogram.
|
||||
*/
|
||||
void MemoryUsage::TypeHistogram::
|
||||
add_info(TypeHandle type, MemoryInfo *info) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_counts[type].add_info(info);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
// This class is a temporary class used only in TypeHistogram::show(), below,
|
||||
// to sort the types in descending order by counts.
|
||||
class TypeHistogramCountSorter {
|
||||
|
|
@ -71,12 +69,14 @@ public:
|
|||
MemoryUsagePointerCounts _count;
|
||||
TypeHandle _type;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Shows the contents of the histogram to nout.
|
||||
*/
|
||||
void MemoryUsage::TypeHistogram::
|
||||
show() const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
// First, copy the relevant information to a vector so we can sort by
|
||||
// counts. Don't use a pvector.
|
||||
typedef vector<TypeHistogramCountSorter> CountSorter;
|
||||
|
|
@ -99,6 +99,7 @@ show() const {
|
|||
}
|
||||
nout << " : " << (*vi)._count << "\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -122,9 +123,11 @@ AgeHistogram() {
|
|||
*/
|
||||
void MemoryUsage::AgeHistogram::
|
||||
add_info(double age, MemoryInfo *info) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
int bucket = choose_bucket(age);
|
||||
nassertv(bucket >= 0 && bucket < num_buckets);
|
||||
_counts[bucket].add_info(info);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -132,6 +135,7 @@ add_info(double age, MemoryInfo *info) {
|
|||
*/
|
||||
void MemoryUsage::AgeHistogram::
|
||||
show() const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
for (int i = 0; i < num_buckets - 1; i++) {
|
||||
nout << _cutoff[i] << " to " << _cutoff[i + 1] << " seconds old : ";
|
||||
_counts[i].output(nout);
|
||||
|
|
@ -140,6 +144,7 @@ show() const {
|
|||
nout << _cutoff[num_buckets - 1] << " seconds old and up : ";
|
||||
_counts[num_buckets - 1].output(nout);
|
||||
nout << "\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -147,9 +152,11 @@ show() const {
|
|||
*/
|
||||
void MemoryUsage::AgeHistogram::
|
||||
clear() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
for (int i = 0; i < num_buckets; i++) {
|
||||
_counts[i].clear();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -157,6 +164,7 @@ clear() {
|
|||
*/
|
||||
int MemoryUsage::AgeHistogram::
|
||||
choose_bucket(double age) const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
for (int i = num_buckets - 1; i >= 0; i--) {
|
||||
if (age >= _cutoff[i]) {
|
||||
return i;
|
||||
|
|
@ -164,6 +172,7 @@ choose_bucket(double age) const {
|
|||
}
|
||||
express_cat.error()
|
||||
<< "No suitable bucket for age " << age << "\n";
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -173,6 +182,7 @@ choose_bucket(double age) const {
|
|||
*/
|
||||
void *MemoryUsage::
|
||||
heap_alloc_single(size_t size) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
void *ptr;
|
||||
|
||||
if (_recursion_protect) {
|
||||
|
|
@ -202,6 +212,9 @@ heap_alloc_single(size_t size) {
|
|||
}
|
||||
|
||||
return ptr;
|
||||
#else
|
||||
return MemoryHook::heap_alloc_single(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -209,6 +222,7 @@ heap_alloc_single(size_t size) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
heap_free_single(void *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_recursion_protect) {
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
|
|
@ -231,6 +245,9 @@ heap_free_single(void *ptr) {
|
|||
MemoryHook::heap_free_single(ptr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
MemoryHook::heap_free_single(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -239,6 +256,7 @@ heap_free_single(void *ptr) {
|
|||
*/
|
||||
void *MemoryUsage::
|
||||
heap_alloc_array(size_t size) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
void *ptr;
|
||||
|
||||
if (_recursion_protect) {
|
||||
|
|
@ -268,6 +286,9 @@ heap_alloc_array(size_t size) {
|
|||
}
|
||||
|
||||
return ptr;
|
||||
#else
|
||||
return MemoryHook::heap_alloc_array(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -275,6 +296,7 @@ heap_alloc_array(size_t size) {
|
|||
*/
|
||||
void *MemoryUsage::
|
||||
heap_realloc_array(void *ptr, size_t size) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_recursion_protect) {
|
||||
ptr = MemoryHook::heap_realloc_array(ptr, size);
|
||||
if (express_cat.is_spam()) {
|
||||
|
|
@ -303,6 +325,9 @@ heap_realloc_array(void *ptr, size_t size) {
|
|||
}
|
||||
|
||||
return ptr;
|
||||
#else
|
||||
return MemoryHook::heap_realloc_array(ptr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -310,6 +335,7 @@ heap_realloc_array(void *ptr, size_t size) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
heap_free_array(void *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_recursion_protect) {
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
|
|
@ -332,6 +358,9 @@ heap_free_array(void *ptr) {
|
|||
MemoryHook::heap_free_array(ptr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
MemoryHook::heap_free_array(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -343,6 +372,7 @@ heap_free_array(void *ptr) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_recursion_protect || !_track_memory_usage) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -391,6 +421,7 @@ mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) {
|
|||
// We're removing this pointer from use.
|
||||
ns_remove_void_pointer(ptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined(WIN32_VC) || defined (WIN64_VC))&& defined(_DEBUG)
|
||||
|
|
@ -430,7 +461,23 @@ win32_malloc_hook(int alloc_type, void *ptr,
|
|||
*
|
||||
*/
|
||||
MemoryUsage::
|
||||
MemoryUsage(const MemoryHook ©) : MemoryHook(copy) {
|
||||
MemoryUsage(const MemoryHook ©) :
|
||||
MemoryHook(copy),
|
||||
_info_set_dirty(false),
|
||||
_freeze_index(0),
|
||||
_count(0),
|
||||
_current_cpp_size(0),
|
||||
_total_cpp_size(0),
|
||||
_total_size(0),
|
||||
|
||||
_track_memory_usage(false),
|
||||
_startup_track_memory_usage(false),
|
||||
_count_memory_usage(false),
|
||||
_report_memory_usage(false),
|
||||
_report_memory_interval(0.0),
|
||||
_last_report_time(0.0) {
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
// We must get these variables here instead of in config_express.cxx,
|
||||
// because we need to know it at static init time, and who knows when the
|
||||
// code in config_express will be executed.
|
||||
|
|
@ -456,9 +503,6 @@ MemoryUsage(const MemoryHook ©) : MemoryHook(copy) {
|
|||
("report-memory-interval", 5.0,
|
||||
PRC_DESC("This is the interval, in seconds, for reports of currently allocated "
|
||||
"memory, when report-memory-usage is true."));
|
||||
_last_report_time = 0.0;
|
||||
|
||||
_count_memory_usage = false;
|
||||
|
||||
int64_t max_heap_size = ConfigVariableInt64
|
||||
("max-heap-size", 0,
|
||||
|
|
@ -480,13 +524,7 @@ MemoryUsage(const MemoryHook ©) : MemoryHook(copy) {
|
|||
_CrtSetAllocHook(&win32_malloc_hook);
|
||||
_count_memory_usage = true;
|
||||
#endif
|
||||
|
||||
_info_set_dirty = false;
|
||||
_freeze_index = 0;
|
||||
_count = 0;
|
||||
_current_cpp_size = 0;
|
||||
_total_cpp_size = 0;
|
||||
_total_size = 0;
|
||||
#endif // DO_MEMORY_USAGE
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -494,9 +532,16 @@ MemoryUsage(const MemoryHook ©) : MemoryHook(copy) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
init_memory_usage() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
init_memory_hook();
|
||||
_global_ptr = new MemoryUsage(*memory_hook);
|
||||
memory_hook = _global_ptr;
|
||||
#else
|
||||
// If this gets called, we still need to initialize the global_ptr with a
|
||||
// stub even if we don't compile with memory usage tracking enabled, for ABI
|
||||
// stability. However, we won't replace the memory hook.
|
||||
_global_ptr = new MemoryUsage(*memory_hook);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -507,6 +552,7 @@ init_memory_usage() {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
overflow_heap_size() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
MemoryHook::overflow_heap_size();
|
||||
|
||||
express_cat.error()
|
||||
|
|
@ -524,6 +570,7 @@ overflow_heap_size() {
|
|||
// Turn on spamful debugging.
|
||||
_track_memory_usage = true;
|
||||
_report_memory_usage = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -531,12 +578,13 @@ overflow_heap_size() {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_record_pointer(ReferenceCount *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_track_memory_usage) {
|
||||
// We have to protect modifications to the table from recursive calls by
|
||||
// toggling _recursion_protect while we adjust it.
|
||||
_recursion_protect = true;
|
||||
pair<Table::iterator, bool> insert_result =
|
||||
_table.insert(Table::value_type((void *)ptr, (MemoryInfo *)NULL));
|
||||
_table.insert(Table::value_type((void *)ptr, nullptr));
|
||||
|
||||
// This shouldn't fail.
|
||||
assert(insert_result.first != _table.end());
|
||||
|
|
@ -575,6 +623,61 @@ ns_record_pointer(ReferenceCount *ptr) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that the given pointer has been recently allocated.
|
||||
*/
|
||||
void MemoryUsage::
|
||||
ns_record_pointer(void *ptr, TypeHandle type) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_track_memory_usage) {
|
||||
// We have to protect modifications to the table from recursive calls by
|
||||
// toggling _recursion_protect while we adjust it.
|
||||
_recursion_protect = true;
|
||||
pair<Table::iterator, bool> insert_result =
|
||||
_table.insert(Table::value_type(ptr, nullptr));
|
||||
|
||||
// This shouldn't fail.
|
||||
assert(insert_result.first != _table.end());
|
||||
|
||||
if (insert_result.second) {
|
||||
(*insert_result.first).second = new MemoryInfo;
|
||||
_info_set_dirty = true;
|
||||
++_count;
|
||||
}
|
||||
|
||||
MemoryInfo *info = (*insert_result.first).second;
|
||||
|
||||
// We should already have a pointer, thanks to a previous call to
|
||||
// mark_pointer().
|
||||
nassertv(info->_void_ptr == ptr && info->_ref_ptr == nullptr);
|
||||
|
||||
info->_void_ptr = ptr;
|
||||
info->_static_type = type;
|
||||
info->_dynamic_type = type;
|
||||
info->_time = TrueClock::get_global_ptr()->get_long_time();
|
||||
info->_freeze_index = _freeze_index;
|
||||
info->_flags |= MemoryInfo::F_reconsider_dynamic_type;
|
||||
|
||||
// We close the recursion_protect flag all the way down here, so that we
|
||||
// also protect ourselves against a possible recursive call in
|
||||
// TrueClock::get_global_ptr().
|
||||
_recursion_protect = false;
|
||||
|
||||
if (_report_memory_usage) {
|
||||
double now = TrueClock::get_global_ptr()->get_long_time();
|
||||
if (now - _last_report_time > _report_memory_interval) {
|
||||
_last_report_time = now;
|
||||
express_cat.info()
|
||||
<< "*** Current memory usage: " << get_total_size() << "\n";
|
||||
show_current_types();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -584,7 +687,8 @@ ns_record_pointer(ReferenceCount *ptr) {
|
|||
* only that it's a "ReferenceCount".
|
||||
*/
|
||||
void MemoryUsage::
|
||||
ns_update_type(ReferenceCount *ptr, TypeHandle type) {
|
||||
ns_update_type(void *ptr, TypeHandle type) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_track_memory_usage) {
|
||||
Table::iterator ti;
|
||||
ti = _table.find(ptr);
|
||||
|
|
@ -592,7 +696,7 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
|
|||
if (_startup_track_memory_usage) {
|
||||
express_cat.error()
|
||||
<< "Attempt to update type to " << type << " for unrecorded pointer "
|
||||
<< (void *)ptr << "!\n";
|
||||
<< ptr << "!\n";
|
||||
nassertv(false);
|
||||
}
|
||||
return;
|
||||
|
|
@ -605,6 +709,7 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
|
|||
|
||||
consolidate_void_ptr(info);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -614,7 +719,8 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
|
|||
* the pointer as a TypedObject it doesn't need any more help.
|
||||
*/
|
||||
void MemoryUsage::
|
||||
ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
|
||||
ns_update_type(void *ptr, TypedObject *typed_ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_track_memory_usage) {
|
||||
Table::iterator ti;
|
||||
ti = _table.find(ptr);
|
||||
|
|
@ -623,7 +729,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
|
|||
express_cat.error()
|
||||
<< "Attempt to update type to " << typed_ptr->get_type()
|
||||
<< " for unrecorded pointer "
|
||||
<< (void *)ptr << "!\n";
|
||||
<< ptr << "!\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -634,6 +740,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
|
|||
|
||||
consolidate_void_ptr(info);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -641,6 +748,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_remove_pointer(ReferenceCount *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_track_memory_usage) {
|
||||
Table::iterator ti;
|
||||
ti = _table.find(ptr);
|
||||
|
|
@ -705,6 +813,7 @@ ns_remove_pointer(ReferenceCount *ptr) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -713,6 +822,7 @@ ns_remove_pointer(ReferenceCount *ptr) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_record_void_pointer(void *ptr, size_t size) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_track_memory_usage) {
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
|
|
@ -724,7 +834,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
|
|||
|
||||
_recursion_protect = true;
|
||||
pair<Table::iterator, bool> insert_result =
|
||||
_table.insert(Table::value_type((void *)ptr, (MemoryInfo *)NULL));
|
||||
_table.insert(Table::value_type((void *)ptr, nullptr));
|
||||
|
||||
assert(insert_result.first != _table.end());
|
||||
|
||||
|
|
@ -761,6 +871,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
|
|||
// TrueClock::get_global_ptr().
|
||||
_recursion_protect = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -768,6 +879,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_remove_void_pointer(void *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (_track_memory_usage) {
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
|
|
@ -823,6 +935,7 @@ ns_remove_void_pointer(void *ptr) {
|
|||
_info_set_dirty = true;
|
||||
delete info;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -830,8 +943,12 @@ ns_remove_void_pointer(void *ptr) {
|
|||
*/
|
||||
int MemoryUsage::
|
||||
ns_get_num_pointers() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertr(_track_memory_usage, 0);
|
||||
return _count;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -840,6 +957,7 @@ ns_get_num_pointers() {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_get_pointers(MemoryUsagePointers &result) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertv(_track_memory_usage);
|
||||
result.clear();
|
||||
|
||||
|
|
@ -857,6 +975,7 @@ ns_get_pointers(MemoryUsagePointers &result) {
|
|||
now - info->_time);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -865,6 +984,7 @@ ns_get_pointers(MemoryUsagePointers &result) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertv(_track_memory_usage);
|
||||
result.clear();
|
||||
|
||||
|
|
@ -886,6 +1006,7 @@ ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -895,6 +1016,7 @@ ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
|
|||
void MemoryUsage::
|
||||
ns_get_pointers_of_age(MemoryUsagePointers &result,
|
||||
double from, double to) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertv(_track_memory_usage);
|
||||
result.clear();
|
||||
|
||||
|
|
@ -915,6 +1037,7 @@ ns_get_pointers_of_age(MemoryUsagePointers &result,
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -935,6 +1058,7 @@ ns_get_pointers_of_age(MemoryUsagePointers &result,
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertv(_track_memory_usage);
|
||||
result.clear();
|
||||
|
||||
|
|
@ -955,6 +1079,7 @@ ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -965,11 +1090,13 @@ ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_freeze() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_count = 0;
|
||||
_current_cpp_size = 0;
|
||||
_trend_types.clear();
|
||||
_trend_ages.clear();
|
||||
_freeze_index++;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -977,6 +1104,7 @@ ns_freeze() {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_show_current_types() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertv(_track_memory_usage);
|
||||
TypeHistogram hist;
|
||||
|
||||
|
|
@ -994,6 +1122,7 @@ ns_show_current_types() {
|
|||
}
|
||||
hist.show();
|
||||
_recursion_protect = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1002,7 +1131,9 @@ ns_show_current_types() {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_show_trend_types() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_trend_types.show();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1010,6 +1141,7 @@ ns_show_trend_types() {
|
|||
*/
|
||||
void MemoryUsage::
|
||||
ns_show_current_ages() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertv(_track_memory_usage);
|
||||
|
||||
AgeHistogram hist;
|
||||
|
|
@ -1026,6 +1158,7 @@ ns_show_current_ages() {
|
|||
|
||||
hist.show();
|
||||
_recursion_protect = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1037,6 +1170,8 @@ ns_show_trend_ages() {
|
|||
_trend_ages.show();
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
||||
/**
|
||||
* If the size information has not yet been determined for this pointer,
|
||||
* checks to see if it has possibly been recorded under the TypedObject
|
||||
|
|
@ -1126,5 +1261,4 @@ refresh_info_set() {
|
|||
_info_set_dirty = false;
|
||||
}
|
||||
|
||||
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@
|
|||
#define MEMORYUSAGE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
||||
#include "typedObject.h"
|
||||
#include "memoryInfo.h"
|
||||
#include "memoryUsagePointerCounts.h"
|
||||
|
|
@ -33,18 +30,22 @@ class MemoryUsagePointers;
|
|||
* every such object currently allocated.
|
||||
*
|
||||
* When compiled with NDEBUG set, this entire class does nothing and compiles
|
||||
* to nothing.
|
||||
* to a stub.
|
||||
*/
|
||||
class EXPCL_PANDAEXPRESS MemoryUsage : public MemoryHook {
|
||||
public:
|
||||
INLINE static bool get_track_memory_usage();
|
||||
ALWAYS_INLINE static bool get_track_memory_usage();
|
||||
|
||||
INLINE static void record_pointer(ReferenceCount *ptr);
|
||||
INLINE static void record_pointer(void *ptr, TypeHandle type);
|
||||
INLINE static void update_type(ReferenceCount *ptr, TypeHandle type);
|
||||
INLINE static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
|
||||
INLINE static void update_type(void *ptr, TypeHandle type);
|
||||
INLINE static void remove_pointer(ReferenceCount *ptr);
|
||||
|
||||
public:
|
||||
protected:
|
||||
// These are not marked public, but they can be accessed via the MemoryHook
|
||||
// base class.
|
||||
virtual void *heap_alloc_single(size_t size);
|
||||
virtual void heap_free_single(void *ptr);
|
||||
|
||||
|
|
@ -88,6 +89,19 @@ PUBLISHED:
|
|||
INLINE static void show_current_ages();
|
||||
INLINE static void show_trend_ages();
|
||||
|
||||
PUBLISHED:
|
||||
MAKE_PROPERTY(tracking, is_tracking);
|
||||
MAKE_PROPERTY(counting, is_counting);
|
||||
MAKE_PROPERTY(current_cpp_size, get_current_cpp_size);
|
||||
MAKE_PROPERTY(total_cpp_size, get_total_cpp_size);
|
||||
|
||||
MAKE_PROPERTY(panda_heap_single_size, get_panda_heap_single_size);
|
||||
MAKE_PROPERTY(panda_heap_array_size, get_panda_heap_array_size);
|
||||
MAKE_PROPERTY(panda_heap_overhead, get_panda_heap_overhead);
|
||||
MAKE_PROPERTY(panda_mmap_size, get_panda_mmap_size);
|
||||
MAKE_PROPERTY(external_size, get_external_size);
|
||||
MAKE_PROPERTY(total_size, get_total_size);
|
||||
|
||||
protected:
|
||||
virtual void overflow_heap_size();
|
||||
|
||||
|
|
@ -98,8 +112,9 @@ private:
|
|||
static void init_memory_usage();
|
||||
|
||||
void ns_record_pointer(ReferenceCount *ptr);
|
||||
void ns_update_type(ReferenceCount *ptr, TypeHandle type);
|
||||
void ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
|
||||
void ns_record_pointer(void *ptr, TypeHandle type);
|
||||
void ns_update_type(void *ptr, TypeHandle type);
|
||||
void ns_update_type(void *ptr, TypedObject *typed_ptr);
|
||||
void ns_remove_pointer(ReferenceCount *ptr);
|
||||
|
||||
void ns_record_void_pointer(void *ptr, size_t size);
|
||||
|
|
@ -120,8 +135,10 @@ private:
|
|||
void ns_show_current_ages();
|
||||
void ns_show_trend_ages();
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
void consolidate_void_ptr(MemoryInfo *info);
|
||||
void refresh_info_set();
|
||||
#endif
|
||||
|
||||
static MemoryUsage *_global_ptr;
|
||||
|
||||
|
|
@ -196,6 +213,4 @@ private:
|
|||
|
||||
#include "memoryUsage.I"
|
||||
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
*/
|
||||
|
||||
#include "memoryUsagePointerCounts.h"
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
||||
#include "memoryInfo.h"
|
||||
|
||||
/**
|
||||
|
|
@ -22,6 +19,7 @@
|
|||
*/
|
||||
void MemoryUsagePointerCounts::
|
||||
add_info(MemoryInfo *info) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_count++;
|
||||
|
||||
if (info->is_size_known()) {
|
||||
|
|
@ -29,6 +27,7 @@ add_info(MemoryInfo *info) {
|
|||
} else {
|
||||
_unknown_size_count++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -36,6 +35,7 @@ add_info(MemoryInfo *info) {
|
|||
*/
|
||||
void MemoryUsagePointerCounts::
|
||||
output(ostream &out) const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
out << _count << " pointers";
|
||||
if (_unknown_size_count < _count) {
|
||||
out << ", ";
|
||||
|
|
@ -48,6 +48,7 @@ output(ostream &out) const {
|
|||
out << " (" << _unknown_size_count << " of unknown size)";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -56,6 +57,7 @@ output(ostream &out) const {
|
|||
*/
|
||||
void MemoryUsagePointerCounts::
|
||||
output_bytes(ostream &out, size_t size) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (size < 4 * 1024) {
|
||||
out << size << " bytes";
|
||||
|
||||
|
|
@ -65,6 +67,5 @@ output_bytes(ostream &out, size_t size) {
|
|||
} else {
|
||||
out << size / (1024 * 1024) << " Mb";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
||||
class MemoryInfo;
|
||||
|
||||
/**
|
||||
|
|
@ -55,6 +53,4 @@ INLINE ostream &operator << (ostream &out, const MemoryUsagePointerCounts &c);
|
|||
|
||||
#include "memoryUsagePointerCounts.I"
|
||||
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,9 +12,6 @@
|
|||
*/
|
||||
|
||||
#include "memoryUsagePointers.h"
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
||||
#include "config_express.h"
|
||||
#include "referenceCount.h"
|
||||
#include "typedReferenceCount.h"
|
||||
|
|
@ -38,7 +35,11 @@ MemoryUsagePointers::
|
|||
*/
|
||||
size_t MemoryUsagePointers::
|
||||
get_num_pointers() const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return _entries.size();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -46,21 +47,26 @@ get_num_pointers() const {
|
|||
*/
|
||||
ReferenceCount *MemoryUsagePointers::
|
||||
get_pointer(size_t n) const {
|
||||
nassertr(n < get_num_pointers(), NULL);
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertr(n < get_num_pointers(), nullptr);
|
||||
return _entries[n]._ref_ptr;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nth pointer of the set, typecast to a TypedObject if possible.
|
||||
* If the pointer is not a TypedObject or if the cast cannot be made, returns
|
||||
* NULL.
|
||||
* nullptr.
|
||||
*/
|
||||
TypedObject *MemoryUsagePointers::
|
||||
get_typed_pointer(size_t n) const {
|
||||
nassertr(n < get_num_pointers(), NULL);
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertr(n < get_num_pointers(), nullptr);
|
||||
TypedObject *typed_ptr = _entries[n]._typed_ptr;
|
||||
|
||||
if (typed_ptr != (TypedObject *)NULL) {
|
||||
if (typed_ptr != nullptr) {
|
||||
return typed_ptr;
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +91,8 @@ get_typed_pointer(size_t n) const {
|
|||
type.is_derived_from(TypedReferenceCount::get_class_type())) {
|
||||
return (TypedReferenceCount *)ref_ptr;
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,8 +100,12 @@ get_typed_pointer(size_t n) const {
|
|||
*/
|
||||
TypeHandle MemoryUsagePointers::
|
||||
get_type(size_t n) const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertr(n < get_num_pointers(), TypeHandle::none());
|
||||
return _entries[n]._type;
|
||||
#else
|
||||
return TypeHandle::none();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -102,8 +113,12 @@ get_type(size_t n) const {
|
|||
*/
|
||||
string MemoryUsagePointers::
|
||||
get_type_name(size_t n) const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertr(n < get_num_pointers(), "");
|
||||
return get_type(n).get_name();
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -113,8 +128,12 @@ get_type_name(size_t n) const {
|
|||
*/
|
||||
double MemoryUsagePointers::
|
||||
get_age(size_t n) const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
nassertr(n < get_num_pointers(), 0.0);
|
||||
return _entries[n]._age;
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -122,7 +141,9 @@ get_age(size_t n) const {
|
|||
*/
|
||||
void MemoryUsagePointers::
|
||||
clear() {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
_entries.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -130,7 +151,9 @@ clear() {
|
|||
*/
|
||||
void MemoryUsagePointers::
|
||||
output(ostream &out) const {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
out << _entries.size() << " pointers.";
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -139,13 +162,12 @@ output(ostream &out) const {
|
|||
void MemoryUsagePointers::
|
||||
add_entry(ReferenceCount *ref_ptr, TypedObject *typed_ptr,
|
||||
TypeHandle type, double age) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
// We can't safely add pointers with a zero reference count. They might be
|
||||
// statically-allocated or something, and if we try to add them they'll try
|
||||
// to destruct when the PointerTo later goes away.
|
||||
if (ref_ptr->get_ref_count() != 0) {
|
||||
_entries.push_back(Entry(ref_ptr, typed_ptr, type, age));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@
|
|||
#define MEMORYUSAGEPOINTERS_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
|
||||
#include "typedObject.h"
|
||||
#include "pointerTo.h"
|
||||
#include "referenceCount.h"
|
||||
|
|
@ -53,7 +50,9 @@ PUBLISHED:
|
|||
string get_type_name(size_t n) const;
|
||||
double get_age(size_t n) const;
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
EXTENSION(PyObject *get_python_pointer(size_t n) const);
|
||||
#endif
|
||||
|
||||
void clear();
|
||||
|
||||
|
|
@ -94,6 +93,4 @@ INLINE ostream &operator << (ostream &out, const MemoryUsagePointers &mup) {
|
|||
|
||||
#include "memoryUsagePointers.I"
|
||||
|
||||
#endif // MEMORY_USAGE_POINTERS
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ PUBLISHED:
|
|||
void ls(ostream &out = cout) const;
|
||||
|
||||
static INLINE string get_magic_number();
|
||||
MAKE_PROPERTY(magic_number, get_magic_number);
|
||||
|
||||
void set_header_prefix(const string &header_prefix);
|
||||
INLINE const string &get_header_prefix() const;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,44 @@ rend() const {
|
|||
return _vector.rend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the iterator that marks the first element in the ordered vector.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
|
||||
cbegin() const {
|
||||
return _vector.begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the iterator that marks the end of the ordered vector.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
|
||||
cend() const {
|
||||
return _vector.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the iterator that marks the first element in the ordered vector,
|
||||
* when viewed in reverse order.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
|
||||
crbegin() const {
|
||||
return _vector.rbegin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the iterator that marks the end of the ordered vector, when viewed
|
||||
* in reverse order.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
|
||||
crend() const {
|
||||
return _vector.rend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nth element.
|
||||
*/
|
||||
|
|
@ -127,6 +165,54 @@ operator [] (TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE n) const {
|
|||
return _vector[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the first element.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::REFERENCE ordered_vector<Key, Compare, Vector>::
|
||||
front() {
|
||||
#ifdef _DEBUG
|
||||
assert(!_vector.empty());
|
||||
#endif
|
||||
return _vector[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a const reference to the first element.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REFERENCE ordered_vector<Key, Compare, Vector>::
|
||||
front() const {
|
||||
#ifdef _DEBUG
|
||||
assert(!_vector.empty());
|
||||
#endif
|
||||
return _vector[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the first element.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::REFERENCE ordered_vector<Key, Compare, Vector>::
|
||||
back() {
|
||||
#ifdef _DEBUG
|
||||
assert(!_vector.empty());
|
||||
#endif
|
||||
return _vector[_vector.size() - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a const reference to the last element.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REFERENCE ordered_vector<Key, Compare, Vector>::
|
||||
back() const {
|
||||
#ifdef _DEBUG
|
||||
assert(!_vector.empty());
|
||||
#endif
|
||||
return _vector[_vector.size() - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the ordered vector.
|
||||
*/
|
||||
|
|
@ -530,6 +616,18 @@ push_back(const value_type &key) {
|
|||
_vector.push_back(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new element to the end of the vector without regard for proper
|
||||
* sorting. This is a bad idea to do except to populate the vector the first
|
||||
* time; be sure to call sort() after you have added all the elements.
|
||||
*/
|
||||
template<class Key, class Compare, class Vector>
|
||||
INLINE void ordered_vector<Key, Compare, Vector>::
|
||||
push_back(value_type &&key) {
|
||||
TAU_PROFILE("ordered_vector::push_back()", " ", TAU_USER);
|
||||
_vector.push_back(move(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last element at the end of the vector.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -147,10 +147,21 @@ public:
|
|||
INLINE CONST_REVERSE_ITERATOR rbegin() const;
|
||||
INLINE CONST_REVERSE_ITERATOR rend() const;
|
||||
|
||||
INLINE CONST_ITERATOR cbegin() const;
|
||||
INLINE CONST_ITERATOR cend() const;
|
||||
INLINE CONST_REVERSE_ITERATOR crbegin() const;
|
||||
INLINE CONST_REVERSE_ITERATOR crend() const;
|
||||
|
||||
// Random access.
|
||||
INLINE reference operator [] (SIZE_TYPE n);
|
||||
INLINE const_reference operator [] (SIZE_TYPE n) const;
|
||||
|
||||
INLINE reference front();
|
||||
INLINE const_reference front() const;
|
||||
|
||||
INLINE reference back();
|
||||
INLINE const_reference back() const;
|
||||
|
||||
// Size information.
|
||||
INLINE SIZE_TYPE size() const;
|
||||
INLINE SIZE_TYPE max_size() const;
|
||||
|
|
@ -201,6 +212,7 @@ public:
|
|||
bool verify_list_nonunique() const;
|
||||
|
||||
INLINE void push_back(const VALUE_TYPE &key);
|
||||
INLINE void push_back(VALUE_TYPE &&key);
|
||||
INLINE void pop_back();
|
||||
INLINE void resize(SIZE_TYPE n);
|
||||
INLINE void resize(SIZE_TYPE n, const VALUE_TYPE &value);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class PointerTo : public PointerToBase<T> {
|
|||
public:
|
||||
typedef TYPENAME PointerToBase<T>::To To;
|
||||
PUBLISHED:
|
||||
ALWAYS_INLINE CONSTEXPR PointerTo() NOEXCEPT DEFAULT_CTOR;
|
||||
ALWAYS_INLINE_CONSTEXPR PointerTo() NOEXCEPT DEFAULT_CTOR;
|
||||
ALWAYS_INLINE PointerTo(To *ptr) NOEXCEPT;
|
||||
INLINE PointerTo(const PointerTo<T> ©);
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ class ConstPointerTo : public PointerToBase<T> {
|
|||
public:
|
||||
typedef TYPENAME PointerToBase<T>::To To;
|
||||
PUBLISHED:
|
||||
ALWAYS_INLINE CONSTEXPR ConstPointerTo() NOEXCEPT DEFAULT_CTOR;
|
||||
ALWAYS_INLINE_CONSTEXPR ConstPointerTo() NOEXCEPT DEFAULT_CTOR;
|
||||
ALWAYS_INLINE ConstPointerTo(const To *ptr) NOEXCEPT;
|
||||
INLINE ConstPointerTo(const PointerTo<T> ©);
|
||||
INLINE ConstPointerTo(const ConstPointerTo<T> ©);
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ reassign(const PointerToBase<To> ©) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
/**
|
||||
* Ensures that the MemoryUsage record for the pointer has the right type of
|
||||
* object, if we know the type ourselves.
|
||||
|
|
@ -149,6 +148,7 @@ reassign(const PointerToBase<To> ©) {
|
|||
template<class T>
|
||||
INLINE void PointerToBase<T>::
|
||||
update_type(To *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
if (MemoryUsage::get_track_memory_usage()) {
|
||||
TypeHandle type = get_type_handle(To);
|
||||
if (type == TypeHandle::none()) {
|
||||
|
|
@ -159,9 +159,8 @@ update_type(To *ptr) {
|
|||
MemoryUsage::update_type(ptr, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenient way to set the PointerTo object to NULL. (Assignment to a NULL
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public:
|
|||
typedef T To;
|
||||
|
||||
protected:
|
||||
ALWAYS_INLINE CONSTEXPR PointerToBase() NOEXCEPT DEFAULT_CTOR;
|
||||
ALWAYS_INLINE_CONSTEXPR PointerToBase() NOEXCEPT DEFAULT_CTOR;
|
||||
INLINE PointerToBase(To *ptr);
|
||||
INLINE PointerToBase(const PointerToBase<T> ©);
|
||||
INLINE ~PointerToBase();
|
||||
|
|
@ -44,9 +44,7 @@ protected:
|
|||
INLINE void reassign(To *ptr);
|
||||
INLINE void reassign(const PointerToBase<To> ©);
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
INLINE void update_type(To *ptr);
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
// No assignment or retrieval functions are declared in PointerToBase,
|
||||
// because we will have to specialize on const vs. non-const later.
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@ reassign(const ThreadSafePointerToBase<To> ©) {
|
|||
reassign((To *)copy._void_ptr);
|
||||
}
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
/**
|
||||
* Ensures that the MemoryUsage record for the pointer has the right type of
|
||||
* object, if we know the type ourselves.
|
||||
|
|
@ -97,6 +96,7 @@ reassign(const ThreadSafePointerToBase<To> ©) {
|
|||
template<class T>
|
||||
void ThreadSafePointerToBase<T>::
|
||||
update_type(To *ptr) {
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
TypeHandle type = get_type_handle(To);
|
||||
if (type == TypeHandle::none()) {
|
||||
do_init_type(To);
|
||||
|
|
@ -105,9 +105,8 @@ update_type(To *ptr) {
|
|||
if (type != TypeHandle::none()) {
|
||||
MemoryUsage::update_type(ptr, type);
|
||||
}
|
||||
}
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenient way to set the ThreadSafePointerTo object to NULL. (Assignment
|
||||
|
|
|
|||
|
|
@ -40,9 +40,7 @@ protected:
|
|||
INLINE void reassign(To *ptr);
|
||||
INLINE void reassign(const ThreadSafePointerToBase<To> ©);
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
void update_type(To *ptr);
|
||||
#endif // DO_MEMORY_USAGE
|
||||
|
||||
// No assignment or retrieval functions are declared in
|
||||
// ThreadSafePointerToBase, because we will have to specialize on const vs.
|
||||
|
|
|
|||
|
|
@ -150,7 +150,16 @@ copy_file(VirtualFile *new_file) {
|
|||
// Different mount point, or the mount doesn't support copying. Do it by
|
||||
// hand.
|
||||
ostream *out = new_file->open_write_file(false, true);
|
||||
if (out == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
istream *in = open_read_file(false);
|
||||
if (in == nullptr) {
|
||||
new_file->close_write_file(out);
|
||||
new_file->delete_file();
|
||||
return false;
|
||||
}
|
||||
|
||||
static const size_t buffer_size = 4096;
|
||||
char buffer[buffer_size];
|
||||
|
|
|
|||
|
|
@ -1226,6 +1226,24 @@ do_get_file(const Filename &filename, int open_flags) const {
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(NDEBUG)
|
||||
if (!found_file) {
|
||||
// The file could not be found. Perhaps this is because the user passed
|
||||
// in a Windows-style path where a Unix-style path was expected?
|
||||
if (filename.length() > 2 && isalpha(filename[0]) && filename[1] == ':' &&
|
||||
(filename[2] == '\\' || filename[2] == '/')) {
|
||||
|
||||
Filename corrected_fn = Filename::from_os_specific(filename);
|
||||
if (corrected_fn.exists()) {
|
||||
express_cat.warning()
|
||||
<< "Filename uses Windows-style path: " << filename << "\n";
|
||||
express_cat.warning()
|
||||
<< " expected Unix-style path: " << corrected_fn << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return found_file;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,37 +10,3 @@
|
|||
* @author rdb
|
||||
* @date 2014-06-27
|
||||
*/
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
|
||||
/**
|
||||
* Returns true if the shader is "valid", ie, if the compilation was
|
||||
* successful. The compilation could fail if there is a syntax error in the
|
||||
* shader, or if the current video card isn't shader-capable, or if no shader
|
||||
* languages are compiled into panda.
|
||||
*/
|
||||
INLINE bool CLP(CgShaderContext)::
|
||||
valid() {
|
||||
if (_shader->get_error_flag()) return false;
|
||||
if (_shader->get_language() != Shader::SL_Cg) return false;
|
||||
return (_cg_program != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the shader may need to access standard vertex attributes as
|
||||
* passed by glVertexPointer and the like.
|
||||
*/
|
||||
INLINE bool CLP(CgShaderContext)::
|
||||
uses_standard_vertex_arrays() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always true, for now.
|
||||
*/
|
||||
INLINE bool CLP(CgShaderContext)::
|
||||
uses_custom_vertex_arrays() {
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // OPENGLES_1
|
||||
|
|
|
|||
|
|
@ -357,6 +357,20 @@ release_resources() {
|
|||
_glgsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the shader is "valid", ie, if the compilation was
|
||||
* successful. The compilation could fail if there is a syntax error in the
|
||||
* shader, or if the current video card isn't shader-capable, or if no shader
|
||||
* languages are compiled into panda.
|
||||
*/
|
||||
bool CLP(CgShaderContext)::
|
||||
valid() {
|
||||
if (_shader == nullptr || _shader->get_error_flag()) {
|
||||
return false;
|
||||
}
|
||||
return (_cg_program != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is to be called to enable a new shader. It also initializes
|
||||
* all of the shader's input parameters.
|
||||
|
|
|
|||
|
|
@ -33,25 +33,25 @@ public:
|
|||
~CLP(CgShaderContext)();
|
||||
ALLOC_DELETED_CHAIN(CLP(CgShaderContext));
|
||||
|
||||
INLINE bool valid(void);
|
||||
void bind() OVERRIDE;
|
||||
void unbind() OVERRIDE;
|
||||
bool valid(void) override;
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *modelview_transform,
|
||||
const TransformState *camera_transform,
|
||||
const TransformState *projection_transform) OVERRIDE;
|
||||
const TransformState *projection_transform) override;
|
||||
|
||||
void issue_parameters(int altered) OVERRIDE;
|
||||
void issue_parameters(int altered) override;
|
||||
void update_transform_table(const TransformTable *table);
|
||||
void update_slider_table(const SliderTable *table);
|
||||
void disable_shader_vertex_arrays() OVERRIDE;
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) OVERRIDE;
|
||||
void disable_shader_texture_bindings() OVERRIDE;
|
||||
void update_shader_texture_bindings(ShaderContext *prev) OVERRIDE;
|
||||
void disable_shader_vertex_arrays() override;
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) override;
|
||||
void disable_shader_texture_bindings() override;
|
||||
void update_shader_texture_bindings(ShaderContext *prev) override;
|
||||
|
||||
INLINE bool uses_standard_vertex_arrays(void);
|
||||
INLINE bool uses_custom_vertex_arrays(void);
|
||||
bool uses_standard_vertex_arrays(void) override { return false; }
|
||||
bool uses_custom_vertex_arrays(void) override { return true; }
|
||||
|
||||
// Special values for location to indicate conventional attrib slots.
|
||||
enum ConventionalAttrib {
|
||||
|
|
@ -95,10 +95,10 @@ public:
|
|||
register_type(_type_handle, CLASSPREFIX_QUOTED "CgShaderContext",
|
||||
ShaderContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {init_type(); return get_class_type();}
|
||||
virtual TypeHandle force_init_type() override {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
|
|
|||
|
|
@ -2135,7 +2135,7 @@ reset() {
|
|||
_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)
|
||||
get_extension_func("glGenerateMipmap");
|
||||
_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)
|
||||
get_extension_func("glRenderbufferStorageMultisampleEXT");
|
||||
get_extension_func("glRenderbufferStorageMultisample");
|
||||
_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)
|
||||
get_extension_func("glBlitFramebuffer");
|
||||
|
||||
|
|
@ -3934,7 +3934,6 @@ end_frame(Thread *current_thread) {
|
|||
*/
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force) {
|
||||
#ifndef NDEBUG
|
||||
|
|
@ -3953,7 +3952,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader, force)) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, data_reader, force)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
|
||||
|
|
@ -4018,10 +4017,10 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
GeomContext *gc = geom_reader->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(gc != (GeomContext *)NULL, false);
|
||||
CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
|
||||
const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
|
||||
//const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
|
||||
|
||||
UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
|
||||
if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
|
||||
if (ggc->get_display_list(_geom_display_list, nullptr, modified)) {
|
||||
// If it hasn't been modified, just play the display list again.
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
|
|
|
|||
|
|
@ -284,7 +284,6 @@ public:
|
|||
virtual void end_frame(Thread *current_thread);
|
||||
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force);
|
||||
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader,
|
||||
|
|
|
|||
|
|
@ -10,38 +10,3 @@
|
|||
* @author jyelon
|
||||
* @date 2005-09-01
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns true if the shader is "valid", ie, if the compilation was
|
||||
* successful. The compilation could fail if there is a syntax error in the
|
||||
* shader, or if the current video card isn't shader-capable, or if no shader
|
||||
* languages are compiled into panda.
|
||||
*/
|
||||
INLINE bool CLP(ShaderContext)::
|
||||
valid() {
|
||||
if (_shader->get_error_flag()) return false;
|
||||
if (_shader->get_language() != Shader::SL_GLSL) {
|
||||
return false;
|
||||
}
|
||||
if (_glsl_program != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the shader may need to access standard vertex attributes as
|
||||
* passed by glVertexPointer and the like.
|
||||
*/
|
||||
INLINE bool CLP(ShaderContext)::
|
||||
uses_standard_vertex_arrays() {
|
||||
return _uses_standard_vertex_arrays;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always true, for now.
|
||||
*/
|
||||
INLINE bool CLP(ShaderContext)::
|
||||
uses_custom_vertex_arrays() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1431,7 +1431,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
|
|||
bind._arg[0] = NULL;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
|
||||
bind._part[1] = Shader::SMO_mat_constant_x_attrib;
|
||||
bind._arg[1] = InternalName::make("shadowViewMatrix");
|
||||
bind._arg[1] = iname->get_parent()->append("shadowViewMatrix");
|
||||
bind._dep[1] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform;
|
||||
} else {
|
||||
bind._part[0] = Shader::SMO_mat_constant_x_attrib;
|
||||
|
|
@ -1821,6 +1821,20 @@ release_resources() {
|
|||
_glgsg->report_my_gl_errors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the shader is "valid", ie, if the compilation was
|
||||
* successful. The compilation could fail if there is a syntax error in the
|
||||
* shader, or if the current video card isn't shader-capable, or if no shader
|
||||
* languages are compiled into panda.
|
||||
*/
|
||||
bool CLP(ShaderContext)::
|
||||
valid() {
|
||||
if (_shader->get_error_flag()) {
|
||||
return false;
|
||||
}
|
||||
return (_glsl_program != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is to be called to enable a new shader. It also initializes
|
||||
* all of the shader's input parameters.
|
||||
|
|
@ -2177,7 +2191,7 @@ update_slider_table(const SliderTable *table) {
|
|||
*/
|
||||
void CLP(ShaderContext)::
|
||||
disable_shader_vertex_arrays() {
|
||||
if (!valid()) {
|
||||
if (_glsl_program == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2200,7 +2214,7 @@ disable_shader_vertex_arrays() {
|
|||
*/
|
||||
bool CLP(ShaderContext)::
|
||||
update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
||||
if (!valid()) {
|
||||
if (_glsl_program == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2373,7 +2387,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
|||
*/
|
||||
void CLP(ShaderContext)::
|
||||
disable_shader_texture_bindings() {
|
||||
if (!valid()) {
|
||||
if (_glsl_program == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2473,7 +2487,7 @@ void CLP(ShaderContext)::
|
|||
update_shader_texture_bindings(ShaderContext *prev) {
|
||||
// if (prev) { prev->disable_shader_texture_bindings(); }
|
||||
|
||||
if (!valid()) {
|
||||
if (_glsl_program == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,26 +40,30 @@ public:
|
|||
void reflect_uniform(int i, char *name_buffer, GLsizei name_buflen);
|
||||
bool get_sampler_texture_type(int &out, GLenum param_type);
|
||||
|
||||
INLINE bool valid(void);
|
||||
void bind() OVERRIDE;
|
||||
void unbind() OVERRIDE;
|
||||
bool valid(void) override;
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *modelview_transform,
|
||||
const TransformState *camera_transform,
|
||||
const TransformState *projection_transform) OVERRIDE;
|
||||
const TransformState *projection_transform) override;
|
||||
|
||||
void issue_parameters(int altered) OVERRIDE;
|
||||
void issue_parameters(int altered) override;
|
||||
void update_transform_table(const TransformTable *table);
|
||||
void update_slider_table(const SliderTable *table);
|
||||
void disable_shader_vertex_arrays() OVERRIDE;
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) OVERRIDE;
|
||||
void disable_shader_texture_bindings() OVERRIDE;
|
||||
void update_shader_texture_bindings(ShaderContext *prev) OVERRIDE;
|
||||
void update_shader_buffer_bindings(ShaderContext *prev) OVERRIDE;
|
||||
void disable_shader_vertex_arrays() override;
|
||||
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) override;
|
||||
void disable_shader_texture_bindings() override;
|
||||
void update_shader_texture_bindings(ShaderContext *prev) override;
|
||||
void update_shader_buffer_bindings(ShaderContext *prev) override;
|
||||
|
||||
INLINE bool uses_standard_vertex_arrays(void);
|
||||
INLINE bool uses_custom_vertex_arrays(void);
|
||||
bool uses_standard_vertex_arrays(void) override {
|
||||
return _uses_standard_vertex_arrays;
|
||||
}
|
||||
bool uses_custom_vertex_arrays(void) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _validated;
|
||||
|
|
@ -128,10 +132,10 @@ public:
|
|||
register_type(_type_handle, CLASSPREFIX_QUOTED "ShaderContext",
|
||||
ShaderContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const OVERRIDE {
|
||||
virtual TypeHandle get_type() const override {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() OVERRIDE {init_type(); return get_class_type();}
|
||||
virtual TypeHandle force_init_type() override {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
|
|
|||
|
|
@ -683,6 +683,7 @@ unify_in_place(int max_indices, bool preserve_order) {
|
|||
int num_vertices = copy_primitives * total_vertices_per_primitive;
|
||||
nassertv(num_vertices > 0);
|
||||
{
|
||||
smaller->set_index_type(reader.get_index_type());
|
||||
GeomVertexArrayDataHandle writer(smaller->modify_vertices(), current_thread);
|
||||
writer.unclean_set_num_rows(num_vertices);
|
||||
memcpy(writer.get_write_pointer(), ptr, stride * (size_t)(num_vertices - num_unused_vertices_per_primitive));
|
||||
|
|
@ -1211,14 +1212,13 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
|||
* is passed true, it will wait for the data to become resident if necessary.
|
||||
*/
|
||||
bool Geom::
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data, bool force,
|
||||
Thread *current_thread) const {
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomVertexData *vertex_data,
|
||||
bool force, Thread *current_thread) const {
|
||||
GeomPipelineReader geom_reader(this, current_thread);
|
||||
GeomVertexDataPipelineReader data_reader(vertex_data, current_thread);
|
||||
data_reader.check_array_readers();
|
||||
|
||||
return geom_reader.draw(gsg, munger, &data_reader, force);
|
||||
return geom_reader.draw(gsg, &data_reader, force);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1749,10 +1749,10 @@ check_valid(const GeomVertexDataPipelineReader *data_reader) const {
|
|||
* The implementation of Geom::draw().
|
||||
*/
|
||||
bool GeomPipelineReader::
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
|
||||
draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomVertexDataPipelineReader *data_reader, bool force) const {
|
||||
PStatTimer timer(Geom::_draw_primitive_setup_pcollector);
|
||||
bool all_ok = gsg->begin_draw_primitives(this, munger, data_reader, force);
|
||||
bool all_ok = gsg->begin_draw_primitives(this, data_reader, force);
|
||||
if (all_ok) {
|
||||
Geom::Primitives::const_iterator pi;
|
||||
for (pi = _cdata->_primitives.begin();
|
||||
|
|
|
|||
|
|
@ -153,7 +153,6 @@ PUBLISHED:
|
|||
|
||||
public:
|
||||
bool draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data,
|
||||
bool force, Thread *current_thread) const;
|
||||
|
||||
|
|
@ -429,7 +428,7 @@ public:
|
|||
INLINE GeomContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg) const;
|
||||
|
||||
bool draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
|
||||
bool draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -178,11 +178,9 @@ private:
|
|||
static TypeHandle _texcoord_type_handle;
|
||||
};
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
// We can safely redefine this as a no-op.
|
||||
template<>
|
||||
INLINE void PointerToBase<InternalName>::update_type(To *ptr) {}
|
||||
#endif
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const InternalName &tcn);
|
||||
|
||||
|
|
|
|||
|
|
@ -327,3 +327,11 @@ INLINE void Material::
|
|||
set_attrib_lock() {
|
||||
_flags |= F_attrib_lock;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE int Material::
|
||||
get_flags() const {
|
||||
return _flags;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ PUBLISHED:
|
|||
MAKE_PROPERTY(twoside, get_twoside, set_twoside);
|
||||
|
||||
public:
|
||||
INLINE int get_flags() const;
|
||||
|
||||
enum Flags {
|
||||
F_ambient = 0x001,
|
||||
F_diffuse = 0x002,
|
||||
|
|
@ -157,8 +159,6 @@ private:
|
|||
|
||||
int _flags;
|
||||
|
||||
friend class MaterialAttrib;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
|
|
|
|||
|
|
@ -450,9 +450,11 @@ cp_dependency(ShaderMatInput inp) {
|
|||
}
|
||||
}
|
||||
if ((inp == SMO_light_ambient) ||
|
||||
(inp == SMO_light_source_i_attrib)) {
|
||||
dep |= SSD_light;
|
||||
if (inp == SMO_light_source_i_attrib) {
|
||||
(inp == SMO_light_source_i_attrib) ||
|
||||
(inp == SMO_light_source_i_packed)) {
|
||||
dep |= SSD_light | SSD_frame;
|
||||
if (inp == SMO_light_source_i_attrib ||
|
||||
inp == SMO_light_source_i_packed) {
|
||||
dep |= SSD_view_transform;
|
||||
}
|
||||
}
|
||||
|
|
@ -465,7 +467,7 @@ cp_dependency(ShaderMatInput inp) {
|
|||
(inp == SMO_apiview_clipplane_i)) {
|
||||
dep |= SSD_clip_planes;
|
||||
}
|
||||
if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i) {
|
||||
if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i || inp == SMO_texscale_i) {
|
||||
dep |= SSD_tex_matrix;
|
||||
}
|
||||
if ((inp == SMO_window_size) ||
|
||||
|
|
@ -483,7 +485,7 @@ cp_dependency(ShaderMatInput inp) {
|
|||
(inp == SMO_apiclip_to_apiview)) {
|
||||
dep |= SSD_projection;
|
||||
}
|
||||
if (inp == SMO_tex_is_alpha_i) {
|
||||
if (inp == SMO_tex_is_alpha_i || inp == SMO_texcolor_i) {
|
||||
dep |= SSD_texture | SSD_frame;
|
||||
}
|
||||
|
||||
|
|
@ -734,6 +736,29 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (pieces[0] == "mat" && pieces[1] == "shadow") {
|
||||
if ((!cp_errchk_parameter_words(p,3))||
|
||||
(!cp_errchk_parameter_in(p)) ||
|
||||
(!cp_errchk_parameter_uniform(p))||
|
||||
(!cp_errchk_parameter_float(p,16,16))) {
|
||||
return false;
|
||||
}
|
||||
ShaderMatSpec bind;
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_whole;
|
||||
bind._func = SMF_compose;
|
||||
bind._part[1] = SMO_light_source_i_attrib;
|
||||
bind._arg[1] = InternalName::make("shadowViewMatrix");
|
||||
bind._part[0] = SMO_view_to_apiview;
|
||||
bind._arg[0] = NULL;
|
||||
bind._index = atoi(pieces[2].c_str());
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
// Implement some macros. Macros work by altering the contents of the
|
||||
// 'pieces' array, and then falling through.
|
||||
|
||||
|
|
@ -833,7 +858,13 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
|||
|
||||
ShaderMatSpec bind;
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_whole;
|
||||
bind._func = SMF_compose;
|
||||
bind._part[1] = SMO_light_source_i_attrib;
|
||||
bind._arg[1] = InternalName::make("shadowViewMatrix");
|
||||
bind._part[0] = SMO_view_to_apiview;
|
||||
bind._arg[0] = NULL;
|
||||
bind._index = atoi(pieces[2].c_str());
|
||||
|
||||
int next = 1;
|
||||
pieces.push_back("");
|
||||
|
|
@ -958,6 +989,30 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
|||
bind._arg[0] = NULL;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
} else if (pieces[1].compare(0, 5, "light") == 0) {
|
||||
if (!cp_errchk_parameter_float(p,16,16)) {
|
||||
return false;
|
||||
}
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_transpose;
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_light_source_i_packed;
|
||||
bind._arg[0] = NULL;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._index = atoi(pieces[1].c_str() + 5);
|
||||
} else if (pieces[1].compare(0, 5, "lspec") == 0) {
|
||||
if (!cp_errchk_parameter_float(p,3,4)) {
|
||||
return false;
|
||||
}
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_row3;
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_light_source_i_attrib;
|
||||
bind._arg[0] = InternalName::make("specular");
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._index = atoi(pieces[1].c_str() + 5);
|
||||
} else {
|
||||
cp_report_error(p,"Unknown attr parameter.");
|
||||
return false;
|
||||
|
|
@ -1094,6 +1149,52 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (pieces[0] == "texscale") {
|
||||
if ((!cp_errchk_parameter_words(p,2))||
|
||||
(!cp_errchk_parameter_in(p)) ||
|
||||
(!cp_errchk_parameter_uniform(p))||
|
||||
(!cp_errchk_parameter_float(p,3,4))) {
|
||||
return false;
|
||||
}
|
||||
ShaderMatSpec bind;
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_row3;
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_texscale_i;
|
||||
bind._arg[0] = NULL;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._index = atoi(pieces[1].c_str());
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pieces[0] == "texcolor") {
|
||||
if ((!cp_errchk_parameter_words(p,2))||
|
||||
(!cp_errchk_parameter_in(p)) ||
|
||||
(!cp_errchk_parameter_uniform(p))||
|
||||
(!cp_errchk_parameter_float(p,3,4))) {
|
||||
return false;
|
||||
}
|
||||
ShaderMatSpec bind;
|
||||
bind._id = p._id;
|
||||
bind._piece = SMP_row3;
|
||||
bind._func = SMF_first;
|
||||
bind._part[0] = SMO_texcolor_i;
|
||||
bind._arg[0] = NULL;
|
||||
bind._part[1] = SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._index = atoi(pieces[1].c_str());
|
||||
|
||||
cp_optimize_mat_spec(bind);
|
||||
_mat_spec.push_back(bind);
|
||||
_mat_deps |= bind._dep[0] | bind._dep[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pieces[0] == "plane") {
|
||||
if ((!cp_errchk_parameter_words(p,2))||
|
||||
(!cp_errchk_parameter_in(p)) ||
|
||||
|
|
@ -1233,9 +1334,9 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
|
|||
}
|
||||
ShaderTexSpec bind;
|
||||
bind._id = p._id;
|
||||
bind._name = InternalName::make(pieces[1])->append("shadowMap");
|
||||
bind._stage = -1;
|
||||
bind._part = STO_named_input;
|
||||
bind._name = nullptr;
|
||||
bind._stage = atoi(pieces[1].c_str());
|
||||
bind._part = STO_light_i_shadow_map;
|
||||
switch (p._type) {
|
||||
case SAT_sampler2d: bind._desired_type = Texture::TT_2d_texture; break;
|
||||
case SAT_sampler_cube: bind._desired_type = Texture::TT_cube_map; break;
|
||||
|
|
|
|||
|
|
@ -202,6 +202,17 @@ public:
|
|||
// Hack for text rendering. Don't use in user shaders.
|
||||
SMO_tex_is_alpha_i,
|
||||
|
||||
SMO_transform_i,
|
||||
SMO_slider_i,
|
||||
|
||||
SMO_light_source_i_packed,
|
||||
|
||||
// Texture scale component of texture matrix.
|
||||
SMO_texscale_i,
|
||||
|
||||
// Color of an M_blend texture stage.
|
||||
SMO_texcolor_i,
|
||||
|
||||
SMO_INVALID
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -201,6 +201,8 @@ PUBLISHED:
|
|||
|
||||
MAKE_PROPERTY(tex_view_offset, get_tex_view_offset, set_tex_view_offset);
|
||||
|
||||
MAKE_PROPERTY(default, get_default);
|
||||
|
||||
public:
|
||||
INLINE static UpdateSeq get_sort_seq();
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ PUBLISHED:
|
|||
|
||||
INLINE static void set_mode(Mode mode);
|
||||
INLINE static Mode get_mode();
|
||||
MAKE_PROPERTY(mode, get_mode, set_mode);
|
||||
|
||||
INLINE static int garbage_collect();
|
||||
INLINE static void list_contents(ostream &out);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ PUBLISHED:
|
|||
INLINE static SimpleLru *get_global_lru(RamClass rclass);
|
||||
INLINE static SimpleLru *get_pending_lru();
|
||||
INLINE static VertexDataSaveFile *get_save_file();
|
||||
MAKE_PROPERTY(save_file, get_save_file);
|
||||
|
||||
INLINE bool save_to_disk();
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ public:
|
|||
// friends of this class.
|
||||
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader,
|
||||
bool force)=0;
|
||||
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)=0;
|
||||
|
|
|
|||
|
|
@ -83,11 +83,9 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
// We can safely redefine this as a no-op.
|
||||
template<>
|
||||
INLINE void PointerToBase<GeometricBoundingVolume>::update_type(To *ptr) {}
|
||||
#endif
|
||||
|
||||
#include "geometricBoundingVolume.I"
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,23 @@ PUBLISHED:
|
|||
|
||||
void reset_bound(const NodePath &rel_to);
|
||||
|
||||
PUBLISHED:
|
||||
MAKE_PROPERTY(curve, get_curve, set_curve);
|
||||
MAKE_PROPERTY(render_mode, get_render_mode, set_render_mode);
|
||||
MAKE_PROPERTY(uv_mode, get_uv_mode, set_uv_mode);
|
||||
MAKE_PROPERTY(uv_direction, get_uv_direction, set_uv_direction);
|
||||
MAKE_PROPERTY(uv_scale, get_uv_scale, set_uv_scale);
|
||||
MAKE_PROPERTY(normal_mode, get_normal_mode, set_normal_mode);
|
||||
MAKE_PROPERTY(tube_up, get_tube_up, set_tube_up);
|
||||
MAKE_PROPERTY(use_vertex_color, get_use_vertex_color, set_use_vertex_color);
|
||||
MAKE_PROPERTY(vertex_color_dimension, get_vertex_color_dimension);
|
||||
MAKE_PROPERTY(num_subdiv, get_num_subdiv, set_num_subdiv);
|
||||
MAKE_PROPERTY(num_slices, get_num_slices, set_num_slices);
|
||||
MAKE_PROPERTY(use_vertex_thickness, get_use_vertex_thickness, set_use_vertex_thickness);
|
||||
MAKE_PROPERTY(vertex_thickness_dimension, get_vertex_thickness_dimension);
|
||||
MAKE_PROPERTY(thickness, get_thickness, set_thickness);
|
||||
MAKE_PROPERTY2(matrix, has_matrix, get_matrix, set_matrix, clear_matrix);
|
||||
|
||||
protected:
|
||||
virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
|
||||
int &internal_vertices,
|
||||
|
|
|
|||
|
|
@ -94,22 +94,6 @@ get_hash_impl() const {
|
|||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPT(RenderAttrib) AlphaTestAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
// This is only important if the shader subsumes the alpha test, which only
|
||||
// happens if there is an AuxBitplaneAttrib with ABO_glow.
|
||||
const AuxBitplaneAttrib *aux;
|
||||
if (!state->get_attrib(aux) ||
|
||||
(aux->get_outputs() & AuxBitplaneAttrib::ABO_glow) == 0) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the BamReader how to create objects of type AlphaTestAttrib.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ public:
|
|||
protected:
|
||||
virtual int compare_to_impl(const RenderAttrib *other) const;
|
||||
virtual size_t get_hash_impl() const;
|
||||
virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const;
|
||||
|
||||
private:
|
||||
PandaCompareFunc _mode;
|
||||
|
|
@ -59,6 +58,7 @@ PUBLISHED:
|
|||
virtual int get_slot() const {
|
||||
return get_class_slot();
|
||||
}
|
||||
MAKE_PROPERTY(class_slot, get_class_slot);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ PUBLISHED:
|
|||
virtual int get_slot() const {
|
||||
return get_class_slot();
|
||||
}
|
||||
MAKE_PROPERTY(class_slot, get_class_slot);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ PUBLISHED:
|
|||
virtual int get_slot() const {
|
||||
return get_class_slot();
|
||||
}
|
||||
MAKE_PROPERTY(class_slot, get_class_slot);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
|
|
|||
|
|
@ -97,14 +97,6 @@ get_hash_impl() const {
|
|||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
CPT(RenderAttrib) AuxBitplaneAttrib::
|
||||
get_auto_shader_attrib_impl(const RenderState *state) const {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the BamReader how to create objects of type AuxBitplaneAttrib.
|
||||
*/
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue