зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset a137e696f06a (bug 1779935) for causing wpt failures in html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.alpha.worker.html CLOSED TREE
This commit is contained in:
Родитель
bd8c576702
Коммит
21276b3980
|
@ -147,47 +147,51 @@ class GradientCache final
|
|||
lockedInstance->NotifyHandlerEndLocked(lockedInstance);
|
||||
}
|
||||
|
||||
template <typename CreateFunc>
|
||||
static already_AddRefed<GradientStops> LookupOrInsert(
|
||||
const GradientCacheKey& aKey, CreateFunc aCreateFunc) {
|
||||
static GradientCacheData* Lookup(const nsTArray<GradientStop>& aStops,
|
||||
ExtendMode aExtend,
|
||||
BackendType aBackendType) {
|
||||
LockedInstance lockedInstance(sInstanceMutex);
|
||||
if (!EnsureInstanceLocked(lockedInstance)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GradientCacheData* gradientData = lockedInstance->mHashEntries.Get(
|
||||
GradientCacheKey(aStops, aExtend, aBackendType));
|
||||
if (!gradientData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!gradientData->mStops || !gradientData->mStops->IsValid()) {
|
||||
lockedInstance->NotifyExpiredLocked(gradientData, lockedInstance);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
lockedInstance->MarkUsedLocked(gradientData, lockedInstance);
|
||||
return gradientData;
|
||||
}
|
||||
|
||||
static void RegisterEntry(UniquePtr<GradientCacheData> aValue) {
|
||||
uint32_t numberOfEntries;
|
||||
RefPtr<GradientStops> stops;
|
||||
{
|
||||
LockedInstance lockedInstance(sInstanceMutex);
|
||||
if (!EnsureInstanceLocked(lockedInstance)) {
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
GradientCacheData* gradientData = lockedInstance->mHashEntries.Get(aKey);
|
||||
if (gradientData) {
|
||||
if (gradientData->mStops && gradientData->mStops->IsValid()) {
|
||||
lockedInstance->MarkUsedLocked(gradientData, lockedInstance);
|
||||
return do_AddRef(gradientData->mStops);
|
||||
} else {
|
||||
lockedInstance->NotifyExpiredLocked(gradientData, lockedInstance);
|
||||
lockedInstance->NotifyHandlerEndLocked(lockedInstance);
|
||||
}
|
||||
}
|
||||
|
||||
stops = aCreateFunc();
|
||||
if (!stops) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto data = MakeUnique<GradientCacheData>(stops, GradientCacheKey(&aKey));
|
||||
nsresult rv = lockedInstance->AddObjectLocked(data.get(), lockedInstance);
|
||||
nsresult rv =
|
||||
lockedInstance->AddObjectLocked(aValue.get(), lockedInstance);
|
||||
if (NS_FAILED(rv)) {
|
||||
// We are OOM, and we cannot track this object. We don't want to store
|
||||
// entries in the hash table (since the expiration tracker is
|
||||
// responsible for removing the cache entries), so we avoid putting that
|
||||
// entry in the table, which is a good thing considering we are short on
|
||||
// memory anyway, we probably don't want to retain things.
|
||||
return stops.forget();
|
||||
return;
|
||||
}
|
||||
lockedInstance->mHashEntries.InsertOrUpdate(aKey, std::move(data));
|
||||
lockedInstance->mHashEntries.InsertOrUpdate(aValue->mKey,
|
||||
std::move(aValue));
|
||||
numberOfEntries = lockedInstance->mHashEntries.Count();
|
||||
}
|
||||
|
||||
if (numberOfEntries > MAX_ENTRIES) {
|
||||
// We have too many entries force the cache to age a generation.
|
||||
NS_DispatchToMainThread(
|
||||
|
@ -200,8 +204,6 @@ class GradientCache final
|
|||
lockedInstance->NotifyHandlerEndLocked(lockedInstance);
|
||||
}));
|
||||
}
|
||||
|
||||
return stops.forget();
|
||||
}
|
||||
|
||||
GradientCacheMutex& GetMutex() final { return sInstanceMutex; }
|
||||
|
@ -269,12 +271,20 @@ already_AddRefed<GradientStops> gfxGradientCache::GetOrCreateGradientStops(
|
|||
aExtend);
|
||||
}
|
||||
|
||||
return GradientCache::LookupOrInsert(
|
||||
GradientCacheKey(aStops, aExtend, aDT->GetBackendType()),
|
||||
[&]() -> already_AddRefed<GradientStops> {
|
||||
return aDT->CreateGradientStops(aStops.Elements(), aStops.Length(),
|
||||
aExtend);
|
||||
});
|
||||
GradientCacheData* cached =
|
||||
GradientCache::Lookup(aStops, aExtend, aDT->GetBackendType());
|
||||
if (cached) {
|
||||
return do_AddRef(cached->mStops);
|
||||
}
|
||||
|
||||
RefPtr<GradientStops> gs =
|
||||
aDT->CreateGradientStops(aStops.Elements(), aStops.Length(), aExtend);
|
||||
if (!gs) {
|
||||
return nullptr;
|
||||
}
|
||||
GradientCache::RegisterEntry(MakeUnique<GradientCacheData>(
|
||||
gs, GradientCacheKey(aStops, aExtend, aDT->GetBackendType())));
|
||||
return gs.forget();
|
||||
}
|
||||
|
||||
void gfxGradientCache::PurgeAllCaches() { GradientCache::AgeAllGenerations(); }
|
||||
|
|
Загрузка…
Ссылка в новой задаче