RefCountedShmem.cpp (2343B)
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 "RefCountedShmem.h" 8 9 #include "mozilla/Atomics.h" 10 #include "mozilla/ipc/ProtocolUtils.h" 11 #include "mozilla/layers/WebRenderMessages.h" 12 13 #define SHM_REFCOUNT_HEADER_SIZE 16 14 15 namespace mozilla { 16 namespace layers { 17 18 uint8_t* RefCountedShm::GetBytes(const RefCountedShmem& aShm) { 19 uint8_t* data = aShm.buffer().get<uint8_t>(); 20 if (!data) { 21 return nullptr; 22 } 23 return data + SHM_REFCOUNT_HEADER_SIZE; 24 } 25 26 size_t RefCountedShm::GetSize(const RefCountedShmem& aShm) { 27 if (!IsValid(aShm)) { 28 return 0; 29 } 30 size_t totalSize = aShm.buffer().Size<uint8_t>(); 31 if (totalSize < SHM_REFCOUNT_HEADER_SIZE) { 32 return 0; 33 } 34 35 return totalSize - SHM_REFCOUNT_HEADER_SIZE; 36 } 37 38 bool RefCountedShm::IsValid(const RefCountedShmem& aShm) { 39 return aShm.buffer().IsWritable() && 40 aShm.buffer().Size<uint8_t>() > SHM_REFCOUNT_HEADER_SIZE; 41 } 42 43 int32_t RefCountedShm::GetReferenceCount(const RefCountedShmem& aShm) { 44 if (!IsValid(aShm)) { 45 return 0; 46 } 47 48 return *aShm.buffer().get<Atomic<int32_t>>(); 49 } 50 51 int32_t RefCountedShm::AddRef(const RefCountedShmem& aShm) { 52 if (!IsValid(aShm)) { 53 return 0; 54 } 55 56 auto* counter = aShm.buffer().get<Atomic<int32_t>>(); 57 if (counter) { 58 return (*counter)++; 59 } 60 return 0; 61 } 62 63 int32_t RefCountedShm::Release(const RefCountedShmem& aShm) { 64 if (!IsValid(aShm)) { 65 return 0; 66 } 67 68 auto* counter = aShm.buffer().get<Atomic<int32_t>>(); 69 if (counter) { 70 return --(*counter); 71 } 72 73 return 0; 74 } 75 76 bool RefCountedShm::Alloc(mozilla::ipc::IProtocol* aAllocator, size_t aSize, 77 RefCountedShmem& aShm) { 78 MOZ_ASSERT(!IsValid(aShm)); 79 auto size = aSize + SHM_REFCOUNT_HEADER_SIZE; 80 if (!aAllocator->AllocUnsafeShmem(size, &aShm.buffer())) { 81 return false; 82 } 83 return true; 84 } 85 86 void RefCountedShm::Dealloc(mozilla::ipc::IProtocol* aAllocator, 87 RefCountedShmem& aShm) { 88 aAllocator->DeallocShmem(aShm.buffer()); 89 aShm.buffer() = ipc::Shmem(); 90 } 91 92 } // namespace layers 93 } // namespace mozilla