1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/layers/TextureSourceProvider.h" 8 #include "mozilla/layers/TextureHost.h" 9 #include "mozilla/layers/PTextureParent.h" 10 #ifdef XP_DARWIN 11 # include "mozilla/layers/TextureSync.h" 12 #endif 13 14 namespace mozilla { 15 namespace layers { 16 ~TextureSourceProvider()17TextureSourceProvider::~TextureSourceProvider() { ReadUnlockTextures(); } 18 ReadUnlockTextures()19void TextureSourceProvider::ReadUnlockTextures() { 20 #ifdef XP_DARWIN 21 nsClassHashtable<nsUint32HashKey, nsTArray<uint64_t>> 22 texturesIdsToUnlockByPid; 23 for (auto& texture : mUnlockAfterComposition) { 24 auto bufferTexture = texture->AsBufferTextureHost(); 25 if (bufferTexture && bufferTexture->IsDirectMap()) { 26 texture->ReadUnlock(); 27 auto actor = texture->GetIPDLActor(); 28 if (actor) { 29 base::ProcessId pid = actor->OtherPid(); 30 nsTArray<uint64_t>* textureIds = 31 texturesIdsToUnlockByPid.LookupOrAdd(pid); 32 textureIds->AppendElement(TextureHost::GetTextureSerial(actor)); 33 } 34 } else { 35 texture->ReadUnlock(); 36 } 37 } 38 for (auto it = texturesIdsToUnlockByPid.ConstIter(); !it.Done(); it.Next()) { 39 TextureSync::SetTexturesUnlocked(it.Key(), *it.UserData()); 40 } 41 #else 42 for (auto& texture : mUnlockAfterComposition) { 43 texture->ReadUnlock(); 44 } 45 #endif 46 mUnlockAfterComposition.Clear(); 47 } 48 UnlockAfterComposition(TextureHost * aTexture)49void TextureSourceProvider::UnlockAfterComposition(TextureHost* aTexture) { 50 mUnlockAfterComposition.AppendElement(aTexture); 51 } 52 NotifyNotUsedAfterComposition(TextureHost * aTextureHost)53bool TextureSourceProvider::NotifyNotUsedAfterComposition( 54 TextureHost* aTextureHost) { 55 mNotifyNotUsedAfterComposition.AppendElement(aTextureHost); 56 57 // If Compositor holds many TextureHosts without compositing, 58 // the TextureHosts should be flushed to reduce memory consumption. 59 const int thresholdCount = 5; 60 const double thresholdSec = 2.0f; 61 if (mNotifyNotUsedAfterComposition.Length() > thresholdCount) { 62 TimeStamp lastCompositionEndTime = GetLastCompositionEndTime(); 63 TimeDuration duration = lastCompositionEndTime 64 ? TimeStamp::Now() - lastCompositionEndTime 65 : TimeDuration(); 66 // Check if we could flush 67 if (duration.ToSeconds() > thresholdSec) { 68 FlushPendingNotifyNotUsed(); 69 } 70 } 71 return true; 72 } 73 FlushPendingNotifyNotUsed()74void TextureSourceProvider::FlushPendingNotifyNotUsed() { 75 for (auto& textureHost : mNotifyNotUsedAfterComposition) { 76 textureHost->CallNotifyNotUsed(); 77 } 78 mNotifyNotUsedAfterComposition.Clear(); 79 } 80 Destroy()81void TextureSourceProvider::Destroy() { 82 ReadUnlockTextures(); 83 FlushPendingNotifyNotUsed(); 84 } 85 86 } // namespace layers 87 } // namespace mozilla 88