Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "TextureSync.h"
|
|
|
|
|
|
|
|
#include <unordered_set>
|
|
|
|
|
2018-08-01 17:44:33 +00:00
|
|
|
#include "base/process_util.h"
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
#include "chrome/common/mach_ipc_mac.h"
|
|
|
|
#include "mozilla/ipc/SharedMemoryBasic.h"
|
|
|
|
#include "mozilla/layers/CompositorThread.h"
|
|
|
|
#include "mozilla/StaticMonitor.h"
|
|
|
|
#include "mozilla/StaticPtr.h"
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
# define LOG_ERROR(str, args...) \
|
|
|
|
PR_BEGIN_MACRO \
|
|
|
|
mozilla::SmprintfPointer msg = mozilla::Smprintf(str, ##args); \
|
|
|
|
NS_WARNING(msg.get()); \
|
|
|
|
PR_END_MACRO
|
|
|
|
#else
|
|
|
|
# define LOG_ERROR(str, args...) \
|
|
|
|
do { /* nothing */ \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
namespace layers {
|
|
|
|
|
|
|
|
// Hold raw pointers and trust that TextureSourceProviders will be
|
|
|
|
// unregistered in their destructors - we don't want to keep these
|
|
|
|
// alive, and destroying them from the main thread will be an
|
|
|
|
// error anyway.
|
|
|
|
StaticAutoPtr<nsTArray<TextureSourceProvider*>> gTextureSourceProviders;
|
|
|
|
|
|
|
|
static std::map<pid_t, std::unordered_set<uint64_t>> gProcessTextureIds;
|
|
|
|
static StaticMonitor gTextureLockMonitor;
|
|
|
|
|
|
|
|
const int kSendMessageTimeout = 1000;
|
|
|
|
const int kTextureLockTimeout = 32; // We really don't want to wait more than
|
|
|
|
// two frames for a texture to unlock. This
|
|
|
|
// will in any case be very uncommon.
|
|
|
|
|
|
|
|
struct WaitForTexturesReply {
|
|
|
|
bool success;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct WaitForTexturesRequest {
|
|
|
|
pid_t pid;
|
|
|
|
};
|
|
|
|
|
2019-02-17 22:25:01 +00:00
|
|
|
static std::unordered_set<uint64_t>* GetLockedTextureIdsForProcess(pid_t pid) {
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
gTextureLockMonitor.AssertCurrentThreadOwns();
|
|
|
|
|
|
|
|
if (gProcessTextureIds.find(pid) == gProcessTextureIds.end()) {
|
|
|
|
gProcessTextureIds[pid] = std::unordered_set<uint64_t>();
|
|
|
|
}
|
|
|
|
|
|
|
|
return &gProcessTextureIds.at(pid);
|
|
|
|
}
|
|
|
|
|
2019-02-17 22:25:01 +00:00
|
|
|
static bool WaitForTextureIdsToUnlock(pid_t pid,
|
|
|
|
const Span<const uint64_t>& textureIds) {
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
{
|
|
|
|
StaticMonitorAutoLock lock(gTextureLockMonitor);
|
|
|
|
std::unordered_set<uint64_t>* freedTextureIds =
|
|
|
|
GetLockedTextureIdsForProcess(pid);
|
|
|
|
|
|
|
|
TimeStamp start = TimeStamp::Now();
|
|
|
|
while (true) {
|
|
|
|
bool allCleared = true;
|
|
|
|
for (uint64_t textureId : textureIds) {
|
|
|
|
if (freedTextureIds->find(textureId) != freedTextureIds->end()) {
|
|
|
|
allCleared = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (allCleared) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lock.Wait(TimeDuration::FromMilliseconds(kTextureLockTimeout)) ==
|
|
|
|
CVStatus::Timeout) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-11-28 09:16:55 +00:00
|
|
|
// In case the monitor gets signaled multiple times, each less than
|
|
|
|
// kTextureLockTimeout. This ensures that the total time we wait is
|
|
|
|
// < 2 * kTextureLockTimeout
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
if ((TimeStamp::Now() - start).ToMilliseconds() >
|
|
|
|
(double)kTextureLockTimeout) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-17 22:25:01 +00:00
|
|
|
static void CheckTexturesForUnlock() {
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
if (gTextureSourceProviders) {
|
|
|
|
for (auto it = gTextureSourceProviders->begin();
|
|
|
|
it != gTextureSourceProviders->end(); ++it) {
|
|
|
|
(*it)->TryUnlockTextures();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::DispatchCheckTexturesForUnlock() {
|
|
|
|
RefPtr<Runnable> task =
|
|
|
|
NS_NewRunnableFunction("CheckTexturesForUnlock", &CheckTexturesForUnlock);
|
|
|
|
CompositorThreadHolder::Loop()->PostTask(task.forget());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::HandleWaitForTexturesMessage(MachReceiveMessage* rmsg,
|
|
|
|
ipc::MemoryPorts* ports) {
|
|
|
|
WaitForTexturesRequest* req =
|
|
|
|
reinterpret_cast<WaitForTexturesRequest*>(rmsg->GetData());
|
|
|
|
uint64_t* textureIds = (uint64_t*)(req + 1);
|
|
|
|
uint32_t textureIdsLength =
|
|
|
|
(rmsg->GetDataLength() - sizeof(WaitForTexturesRequest)) /
|
|
|
|
sizeof(uint64_t);
|
|
|
|
|
|
|
|
bool success = WaitForTextureIdsToUnlock(
|
|
|
|
req->pid, MakeSpan<uint64_t>(textureIds, textureIdsLength));
|
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
LOG_ERROR("Waiting for textures to unlock failed.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
MachSendMessage msg(ipc::kReturnWaitForTexturesMsg);
|
|
|
|
WaitForTexturesReply replydata;
|
|
|
|
replydata.success = success;
|
|
|
|
msg.SetData(&replydata, sizeof(WaitForTexturesReply));
|
|
|
|
kern_return_t err = ports->mSender->SendMessage(msg, kSendMessageTimeout);
|
|
|
|
if (KERN_SUCCESS != err) {
|
|
|
|
LOG_ERROR("SendMessage failed 0x%x %s\n", err, mach_error_string(err));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::RegisterTextureSourceProvider(
|
|
|
|
TextureSourceProvider* textureSourceProvider) {
|
|
|
|
if (!gTextureSourceProviders) {
|
|
|
|
gTextureSourceProviders = new nsTArray<TextureSourceProvider*>();
|
|
|
|
}
|
|
|
|
MOZ_RELEASE_ASSERT(!gTextureSourceProviders->Contains(textureSourceProvider));
|
|
|
|
gTextureSourceProviders->AppendElement(textureSourceProvider);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::UnregisterTextureSourceProvider(
|
|
|
|
TextureSourceProvider* textureSourceProvider) {
|
|
|
|
if (gTextureSourceProviders) {
|
|
|
|
MOZ_ASSERT(gTextureSourceProviders->Contains(textureSourceProvider));
|
|
|
|
gTextureSourceProviders->RemoveElement(textureSourceProvider);
|
|
|
|
if (gTextureSourceProviders->Length() == 0) {
|
|
|
|
gTextureSourceProviders = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::SetTexturesLocked(pid_t pid,
|
|
|
|
const nsTArray<uint64_t>& textureIds) {
|
|
|
|
StaticMonitorAutoLock mal(gTextureLockMonitor);
|
|
|
|
std::unordered_set<uint64_t>* lockedTextureIds =
|
|
|
|
GetLockedTextureIdsForProcess(pid);
|
|
|
|
for (uint64_t textureId : textureIds) {
|
|
|
|
lockedTextureIds->insert(textureId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::SetTexturesUnlocked(pid_t pid,
|
|
|
|
const nsTArray<uint64_t>& textureIds) {
|
|
|
|
bool oneErased = false;
|
|
|
|
{
|
|
|
|
StaticMonitorAutoLock mal(gTextureLockMonitor);
|
|
|
|
std::unordered_set<uint64_t>* lockedTextureIds =
|
|
|
|
GetLockedTextureIdsForProcess(pid);
|
|
|
|
for (uint64_t textureId : textureIds) {
|
|
|
|
if (lockedTextureIds->erase(textureId)) {
|
|
|
|
oneErased = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (oneErased) {
|
|
|
|
gTextureLockMonitor.NotifyAll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::Shutdown() {
|
|
|
|
{
|
|
|
|
StaticMonitorAutoLock lock(gTextureLockMonitor);
|
|
|
|
|
|
|
|
for (auto& lockedTextureIds : gProcessTextureIds) {
|
|
|
|
lockedTextureIds.second.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gTextureLockMonitor.NotifyAll();
|
|
|
|
|
|
|
|
{
|
|
|
|
StaticMonitorAutoLock lock(gTextureLockMonitor);
|
|
|
|
gProcessTextureIds.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::UpdateTextureLocks(base::ProcessId aProcessId) {
|
2018-08-01 17:44:33 +00:00
|
|
|
if (aProcessId == base::GetCurrentProcId()) {
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
DispatchCheckTexturesForUnlock();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MachSendMessage smsg(ipc::kUpdateTextureLocksMsg);
|
|
|
|
smsg.SetData(&aProcessId, sizeof(aProcessId));
|
|
|
|
ipc::SharedMemoryBasic::SendMachMessage(aProcessId, smsg, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextureSync::WaitForTextures(base::ProcessId aProcessId,
|
|
|
|
const nsTArray<uint64_t>& textureIds) {
|
2018-08-01 17:44:33 +00:00
|
|
|
if (aProcessId == base::GetCurrentProcId()) {
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
bool success =
|
|
|
|
WaitForTextureIdsToUnlock(aProcessId, MakeSpan<uint64_t>(textureIds));
|
|
|
|
if (!success) {
|
|
|
|
LOG_ERROR("Failed waiting for textures to unlock.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
MachSendMessage smsg(ipc::kWaitForTexturesMsg);
|
|
|
|
size_t messageSize =
|
|
|
|
sizeof(WaitForTexturesRequest) + textureIds.Length() * sizeof(uint64_t);
|
|
|
|
UniquePtr<uint8_t[]> messageData = MakeUnique<uint8_t[]>(messageSize);
|
|
|
|
WaitForTexturesRequest* req = (WaitForTexturesRequest*)messageData.get();
|
|
|
|
uint64_t* reqTextureIds = (uint64_t*)(req + 1);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < textureIds.Length(); ++i) {
|
|
|
|
reqTextureIds[i] = textureIds[i];
|
|
|
|
}
|
|
|
|
|
2018-08-01 17:44:33 +00:00
|
|
|
req->pid = base::GetCurrentProcId();
|
Bug 1265824 - Wait on texture handles with IPC r=jld,mattwoodrow
There's a lot going on here, but it all fits under the idea of
being able to communicate about texture locking statuses
without spinning on IsReadLocked. This is a bit of a trade -
we could just always allocate/grab a texture from the pool,
which would put a smaller cap on the amount of time we can
possibly spend when a texture is locked. However, this eats
up more CPU and memory than waiting on the textures to unlock,
and could take longer, especially if there were a large number
of textures which we just need to wait for for a short amount
of time. In any case, we very rarely hit the case where we
actually need to wait on the sync IPC to the compositor - most
of the time the textures are already unlocked.
There is also an async IPC call in here, which we make before
flushing async paints. This just causes the compositor to
check whether the GPU is done with its textures or not and
unlock them if it is. This helps us avoid the case where we
take a long time painting asynchronously, turn IPC back on at
the end of that, and then have to wait for the compositor
to to get into TiledLayerBufferComposite::UseTiles before
getting a response. Specifically this eliminates several talos
regressions which use ASAP mode.
Lastly, there seem to be no other cases of static Monitors
being used. This seems like it falls under similar use cases
as StaticMutexes, so I added it in. I can move it into its own
file if we think it might be generally useful in the future.
MozReview-Commit-ID: IYQLwUqMxg2
--HG--
extra : rebase_source : 4f05832f51dae6db98773dcad03cb008a80eca6c
2018-05-05 22:46:26 +00:00
|
|
|
bool dataWasSet = smsg.SetData(req, messageSize);
|
|
|
|
|
|
|
|
if (!dataWasSet) {
|
|
|
|
LOG_ERROR("Data was too large: %zu\n", messageSize);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MachReceiveMessage msg;
|
|
|
|
bool success =
|
|
|
|
ipc::SharedMemoryBasic::SendMachMessage(aProcessId, smsg, &msg);
|
|
|
|
if (!success) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (msg.GetDataLength() != sizeof(WaitForTexturesReply)) {
|
|
|
|
LOG_ERROR("Improperly formatted reply\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
WaitForTexturesReply* msg_data =
|
|
|
|
reinterpret_cast<WaitForTexturesReply*>(msg.GetData());
|
|
|
|
if (!msg_data->success) {
|
|
|
|
LOG_ERROR("Failed waiting for textures to unlock.\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextureSync::CleanupForPid(base::ProcessId aProcessId) {
|
|
|
|
{
|
|
|
|
StaticMonitorAutoLock lock(gTextureLockMonitor);
|
|
|
|
std::unordered_set<uint64_t>* lockedTextureIds =
|
|
|
|
GetLockedTextureIdsForProcess(aProcessId);
|
|
|
|
lockedTextureIds->clear();
|
|
|
|
}
|
|
|
|
gTextureLockMonitor.NotifyAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace layers
|
|
|
|
|
2018-11-28 09:16:55 +00:00
|
|
|
} // namespace mozilla
|