Commit Graph

78 Commits

Author SHA1 Message Date
Mathias Agopian
befc1de389 improve a bit GLES error logging code.
no functionality changes, just easier to use when debugging.
2021-04-06 14:00:32 -07:00
Adrian Perez
a33c85bdd4 CString can construct from a string_view (#3677)
* CString can construct from a string_view

(string_views lack a null terminator)

* Update libs/utils/src/CString.cpp

Co-authored-by: Mathias Agopian <pixelflinger@gmail.com>
2021-03-23 00:46:18 -07:00
Mathias Agopian
e8b16d600e Fix a hang in JobSystem
The hang was caused by a subtle race. When a job is completed, its 
thread must signal all the threads that might be waiting on this job.
The signaling code was attempting to signal only the minimum number
of threads -- this was important especially in the case where no threads
were waiting, then the call to notify() could be avoided.

Unfortunately, for performance reasons we're not calling notify() with
the condition lock held, this meant that between the time the number of 
waiting threads was latched and the time of the notify() call, more
threads could enter their condition variable wait(), and it would
then be possible for these threads to wake up, instead of the thread
we were trying to wake up (the one waiting on the job).

It would then get stuck forever.

This bug was introduced in 2df639133b


Also add some debugging code for this kind of failure (disabled)
2021-03-17 13:44:30 -07:00
Mathias Agopian
cc13420e31 add missing includes
Should fix #3633
2021-03-15 22:45:31 -07:00
Mathias Agopian
41634a301e demangle callstacks in debug builds (unixes only)
This requires dladdr() and __cxa_demangle().
2021-03-13 23:22:01 -08:00
Mathias Agopian
bc6acd5c5a GL backend: fix race condition when asserting a handle exists 2021-02-22 23:25:43 -08:00
Mathias Agopian
f1fd96983b assert_invariant() now terminates the program in failure
rename logAndPanic to panicLog, since it doesn't actually panics.
2021-02-22 14:57:41 -08:00
Mathias Agopian
68e99240d0 don't use assert() inside filament
assert() is now replaced by assert_invariant() which has the same
prototype and (currently) behaves the same than assert().

<assert.h> should not be used anymore, and is replaced by 
<utils/debug.h>, which is where assert_invariant() is found.

The main motivation for this is to be able to set a breakpoint on the
assertion as lldb doesn't handle abort() very well, and doesn't
permit to inspect the stack trace.

A secondary motivation is to be able (at some point) to enable 
assertions without necessarily doing a debug build.
2021-02-16 20:30:04 -08:00
Philip Rideout
37768ed9e1 Various changes to help clients upgrade Filament.
The non-const getSkybox() method is especially useful to client code
that needs to change the clear color, but does not have direct
access to the Renderer object.
2020-10-13 10:10:59 -07:00
Philip Rideout
b82dca4fac JobSystem: work around hang on 2-CPU machines
If hardware_concurrency() returned 2 while UTILS_HAS_HYPER_THREADING was
enabled, `mThreadCount` was resulting in zero, so jobs (such as texture
decoding) would simply never start. This problem was noticed with
GitHub Actions.

I tested this fix locally by replacing `hardware_concurrency()` with
fixed values like 1 or 2, and verified that the hang went away.
2020-10-09 16:14:50 -07:00
Philip Rideout
ac07719414 CString should allow arbitrary data. 2020-09-24 09:53:59 -07:00
Pixelflinger
2312d483c1 fix typo and static analysis warnings in libutils 2020-09-15 15:43:03 -07:00
Ben Doherty
1a85c93894 Fix DEBUG identifier used in Log.h (#2895) 2020-07-30 16:43:42 -07:00
Pixelflinger
ec9fd58fc0 use more inclusive language 2020-07-22 15:20:54 -07:00
Pixelflinger
ee6ddf675e syscall (futex) errors are returned in errno
this fixes a problem where our implementation of Condition would not
handle timeouts properly
2020-06-06 15:50:38 -07:00
Mathias Agopian
ee3c3d0965 debug option to track Entities (#2526)
* debug option to track Entities

Set FILAMENT_UTILS_TRACK_ENTITIES to true when building libutils to
activate entity tracking. This adds two public methods:

getActiveEntities() and dumpActiveEntities() the later displays the
stack trace of where the remaining entities were allocated.

This is useful for tracking leaks.

* Update libs/utils/include/utils/EntityManager.h

Co-authored-by: Philip Rideout <philiprideout@gmail.com>

Co-authored-by: Philip Rideout <philiprideout@gmail.com>
2020-05-12 17:55:39 -07:00
Pixelflinger
fb0e89d969 fix a race-condition in JobSystem
mThreadMap needs to be protected as it's accessed from multiple threads.
2020-04-03 17:25:17 -07:00
Philip Rideout
c79f5a1a29 JobSystem: replace TLS with tid mapping. 2020-04-02 14:53:20 -07:00
Pixelflinger
4a5ce16322 Trivially make LinearAllocator 16 bytes instead of 24 2020-03-11 17:04:08 -07:00
Mathias Agopian
b71357a955 Allocators shouldn't crash when allocation fails
The allocator debug code didn't check that allocations where
successful before filling buffers.
2020-02-27 14:15:11 -08:00
Philip Rideout
cb953b4203 Remove usage of <regex> from Path.
There was actually no need to give special treatment to leading drive
designators since they effectively form the first path segment anyway.
To help prevent regressions, I added a few unit tests in a previous CL.

The motivation for the CL is to remove a dependency on `locale.cpp`,
which can result in shorter build times and reduced binary sizes.
2020-02-12 10:03:06 -08:00
Tim Psiaki
b030f67eb7 Make EntityManager and Panic dynamic-linkable. 2020-01-06 10:24:17 -08:00
Mathias Agopian
53ff133b03 fix a possible memory corruption in debug builds
TrackingPolicy::Debug didn't store the base pointer of the Area, and
instead relied on the first allocation to discover it, however, because
of alignment, the first allocation may not match the base pointer.
Because of that there could be an overflow in onRewind(), i.e. we
could rewind to a pointer before the (wrongly computed) base. This
overflow caused the debug memset to go awry and stomped on memory.

This is fixed by passing the base pointer to the constructor of the
TrackingPolicy. This base pointer could be nullptr with certain
allocators, but in that case, onReset/onRewind should never be called;
and this is enforced at compile time.

Also fixed a (luckily) harmless buffer overflow when preparing the
dynamic lights, if the number of lights wasn't a multiple of 4. This
was harmless because we use a linear allocator, so overflows are not 
really overflows.
2019-11-07 10:03:41 -08:00
Ben Doherty
20f4ec6576 Use platform-specific temporary directories for CircularBuffer (#1769) 2019-10-15 12:01:03 -07:00
Romain Guy
a67d92c2ca Lower limit from API 21 to API 19 (#1701)
* Lower limit from API 21 to API 19

This was requested by an internal application. API 19 is when OpenGL
ES 3.0 support was added so there is no good reason for us to not
support this API level. The only trick is to avoid referring to the
glTexStorage2DMultisample symbol directly as it only exists in 3.1.

* Compile out code we never use

* Use reflection to handle shared EGL contexts pre-API 21.

* Remove comment

* More fixes required to run on API level 19

- dlym() fails for ashmem on API 19, so we only try on API 26+ instead.
- Older emulation for OpenGL ES 3.0 returns error states for valid API calls so we need to clear the GL error bit before we create the GL driver.
- Activity lifecycle changes since API 19 would cause animations to keep running and to reference destroyed objects.
- EGLContext.getNativeHandle() is new in API 21, we need to use reflection on API 19. The new code path uses the class loading trick to avoid a bytecode verification error on API 19.

* Filament now runs properly on API level 19

This commit adds a new api_level() API to libutils which can be used to
query the platform's API level. On Android it works as expected, other
platforms currently return 0.
2019-09-28 14:13:06 +03:00
Mathias Agopian
b92c748fcc Use allocator Debug policy in more places 2019-08-28 19:06:54 -07:00
Mathias Agopian
844dde4e6d simple allocation debugger
This can be enabled by using the Tracking::Debug policy,
currently this just fills allocation on alloc() and free(),
which is useful to help detect access to uninitialized memory
and use after free.

Now enabled by default in libfilament allocators on debug builds.

This caught uninitialized access in the froxelizer.
2019-08-28 19:06:54 -07:00
Ben Doherty
d4943cc70b Add #include preprocessing to filamat and matc (#1541)
* Add #include preprocessing to filamat and matc

* Update RELEASE_NOTES

* Fix RELEASE_NOTES

* Use final instead of virtual / override

* Clarify comments

* Use pure virtual for includer functions

* Use a callback instead of an interface

* Rename Includer.h to IncludeCallback.h

* Update comment
2019-08-23 11:10:36 -07:00
Ben Doherty
bd22bed2fb Fix Windows test cases (#1537) 2019-08-20 15:36:22 -07:00
Pixelflinger
9bcf10cf44 fix thread count initialization
if hw thread count was 1, we'd end-up with 32 threads
2019-07-22 13:01:53 -07:00
Pixelflinger
261dafa924 Fix a possible infinite loop
In the case where we have 2 cores, we would spawn only one thread in
the thread pool. If that thread got to try to steal() from another
thread before the main thread was adopted, it would end-up always
trying to steal from itself and enter an infinite loop.

This seems to happen during windows builds.
2019-07-19 10:56:41 -07:00
Mathias Agopian
665703dbd8 parallel_for now creates jobs in reverse order
this is because the JobSystem's queue works as a LIFO, by creating
jobs in reverse (memory) order, we attempt to help streaming to
the d-cache on that threads -- until the point where
jobs are stolen. 

we also execute the last job immediately instead of creating a job
for it -- since we're already in a job.
2019-07-09 16:12:15 -07:00
Pixelflinger
8170ca7cd1 improve JobSystem::parallel_for + minor optimizations
- parallel_for doesn't use recursion anymore to create the "leaf"
jobs, this is now done linearly on N thread (one thread per CPU).
This uses less stack space, and reduces miss-predicted branches.

- remove almost all SYSTRACE calls because they have a huge impact
on things like parallel_for() and are misleading. They can be
enabled again by setting HEAVY_SYSTRACE to true.
2019-07-09 16:12:15 -07:00
Mathias Agopian
2df639133b improvements to JobSystem
- we simplify the waiting code by using only a single
condition variable instead of two.

- wait() now behaves just like a looper, it will process jobs until
the one it's waiting for finishes -- before it could just sit there
(the idea was that the job would finish quickly, but that's not always
the case).

- we also make sure to never call notify_n() when it's not needed.
We track how many waiters we have and use that to decide if we need
to notify().

notify is pretty slow on all architectures, even on linux it's always
a syscall, so it's better to avoid it.

- don't use stand-alone fences, makes things ugly for no real benefit

- refactored the code a bit, hopefully it's more clear.
2019-07-09 16:12:15 -07:00
Mathias Agopian
76027cab85 fix a JobSystem bug in waitAndRelease()
We were not checking for jobs to execute during waitAndRelease(), so
this thread would essentially not participate to the work pool.
2019-07-01 14:25:26 -07:00
Romain Guy
826d52bca2 Fix Windows build and warnings 2019-06-27 09:18:31 -07:00
Mathias Agopian
921c2bcd61 mitigate overhead of jobsystem
For jobs with that do very little work, the jobsystem can introduce
a lot of overhead, we mitigate this by:

- don't wake-up worker threads when scheduling several very small jobs,
like when scheduling the per-face jobs. 

- don't wait for per-face jobs to finish -- we only did that to avoid
a copy of the job's data.

- don't use multi-threading at all if the job has too little work. We
evaluate the work using the scanline length and number of samples.
2019-06-26 16:05:30 -07:00
Mathias Agopian
1716f9e7cd fix our ostream << hex << char
Even when hex modifier is used, 'char' should be printed as characters,
this is particularly relevant with 0.
e.g. out << (char)0, should write a nul terminator, not "0".
2019-05-23 21:46:28 -07:00
Ben Doherty
399f7c24ac Fix flaky sstream test (#1205) 2019-05-20 13:09:03 -06:00
Ben Doherty
daddc25de8 Remove std::sstream from filamat (#1176) 2019-05-13 13:56:15 -07:00
Mathias Agopian
1a313ed299 Use ASharedMemory on Android when available 2019-04-10 12:29:51 -07:00
prideout
b4270909c4 Reduce watermark console spew. 2019-03-14 16:18:28 -07:00
Mathias Agopian
2a72e8aee8 break dependency of Program on SamplerInterfaceBlock and SamplerBindingMap
Instead of passing SamplerInterfaceBlocks and a SamplerBindingMap to
Program, we now set a 'sampler group' per binding point:

Program::addSamplerGroup(...)

A sampler group here consists of a list of N 'Sampler' and a 'Sampler'
is just a unique name (unifrom name in the shader) and binding point in
the shader.

That's all the driver layer needs.

With this change we get rid of the code that re-created the uniform
names in the driver -- this should never have been done there. And we
also remove the hash-map lookups in vulkan and metal drivers.
2019-03-07 13:43:27 -08:00
Mathias Agopian
f2ba48f4a7 Program::shader() now only takes a void* + size
Program::shader() was taking a string before which didn't make sense
for spirv.  Now it's just a blob, in the case of GL/Metal, the blob
must be a null terminated c-string, and the size must include the
terminating null character.

This fixes an out-of-bound access in ShaderBuilder::getShader() (which
doesn't exist anymore), because it was creating a CString passing
a size that included the null terminating char, which is not was CString
expects. CString can now assert() in that case.


driver::Program now uses a std::vector<> for storage, which we should
fix at some point (b/c it's a public header). CString was not suited to
store binary blobs.
2019-03-04 19:00:26 -08:00
Adrian Perez
7ba46ef5f1 Add explicit includes for types not implied in all stdlib impls 2019-01-30 16:08:57 -08:00
Mathias Agopian
ae6ab66af4 fix #755: a race condition cousing a deadlock
This reverts a JobSystem optimization that attempted to avoid signaling
a condition when there was no waiters. Unfortunately, there was a
race that caused the the signaling thread to miss that the waiter flag
was set, thus not signaling.
2019-01-29 15:40:25 -08:00
Mathias Agopian
373e519292 slog.* << io::hex now prefixes values with 0x 2019-01-22 10:49:22 -08:00
Mathias Agopian
cfb9c03226 Improve JobSystem, especially under contention
- only signal waitAndRelease() when the corresponding job finishes and
only if there is waitAndRelease() active -- instead of signaling 
every time a job ends.

- don't surrender time slice when attempting to steal a job and it fails
as long as some queue has jobs.

- check that we have to wait, because taking the lock

- add a benchmark

This change more than doubles the amount of jobs we can handle per
second (~965,000 jobs/s on Pixel3)
2018-12-14 16:01:17 -08:00
Mathias Agopian
d6de2bf426 get rid of JobSystem::reset()
It was only used to clear the master job, instead the master job is
cleared when waited on.
2018-12-14 14:48:33 -08:00
Mathias Agopian
e38870ebf5 Improve JobSystem::wait
JobSystem::waitAndRelease used to spin to wait for the job to finish,
usually this wasn't a problem because the spinning thread was
able to handle other jobs. However, in cases where no job was
available it would actually spin in burn cpu cycles.

we now use a (separate) condition variable to handle that case.
2018-12-13 10:50:52 -08:00