Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "SourceSurfaceSharedData.h"
7 :
8 : #include "mozilla/Likely.h"
9 : #include "mozilla/Types.h" // for decltype
10 :
11 : namespace mozilla {
12 : namespace gfx {
13 :
14 : bool
15 0 : SourceSurfaceSharedData::Init(const IntSize &aSize,
16 : int32_t aStride,
17 : SurfaceFormat aFormat)
18 : {
19 0 : mSize = aSize;
20 0 : mStride = aStride;
21 0 : mFormat = aFormat;
22 :
23 0 : size_t len = GetAlignedDataLength();
24 0 : mBuf = new SharedMemoryBasic();
25 0 : if (NS_WARN_IF(!mBuf->Create(len)) ||
26 0 : NS_WARN_IF(!mBuf->Map(len))) {
27 0 : mBuf = nullptr;
28 0 : return false;
29 : }
30 :
31 0 : return true;
32 : }
33 :
34 : void
35 0 : SourceSurfaceSharedData::GuaranteePersistance()
36 : {
37 : // Shared memory is not unmapped until we release SourceSurfaceSharedData.
38 0 : }
39 :
40 : void
41 0 : SourceSurfaceSharedData::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
42 : size_t& aHeapSizeOut,
43 : size_t& aNonHeapSizeOut) const
44 : {
45 0 : if (mBuf) {
46 0 : aNonHeapSizeOut += GetAlignedDataLength();
47 : }
48 0 : }
49 :
50 : uint8_t*
51 0 : SourceSurfaceSharedData::GetDataInternal() const
52 : {
53 0 : mMutex.AssertCurrentThreadOwns();
54 :
55 : // If we have an old buffer lingering, it is because we get reallocated to
56 : // get a new handle to share, but there were still active mappings.
57 0 : if (MOZ_UNLIKELY(mOldBuf)) {
58 0 : MOZ_ASSERT(mMapCount > 0);
59 0 : MOZ_ASSERT(mFinalized);
60 0 : return static_cast<uint8_t*>(mOldBuf->memory());
61 : }
62 0 : return static_cast<uint8_t*>(mBuf->memory());
63 : }
64 :
65 : nsresult
66 0 : SourceSurfaceSharedData::ShareToProcess(base::ProcessId aPid,
67 : SharedMemoryBasic::Handle& aHandle)
68 : {
69 0 : MutexAutoLock lock(mMutex);
70 :
71 0 : if (mClosed) {
72 0 : return NS_ERROR_NOT_AVAILABLE;
73 : }
74 :
75 0 : bool shared = mBuf->ShareToProcess(aPid, &aHandle);
76 0 : if (MOZ_UNLIKELY(!shared)) {
77 0 : return NS_ERROR_FAILURE;
78 : }
79 :
80 0 : return NS_OK;
81 : }
82 :
83 : void
84 0 : SourceSurfaceSharedData::CloseHandleInternal()
85 : {
86 0 : mMutex.AssertCurrentThreadOwns();
87 :
88 0 : if (mClosed) {
89 0 : return;
90 : }
91 :
92 0 : if (mFinalized && mShared) {
93 0 : mBuf->CloseHandle();
94 0 : mClosed = true;
95 : }
96 : }
97 :
98 : bool
99 0 : SourceSurfaceSharedData::ReallocHandle()
100 : {
101 0 : MutexAutoLock lock(mMutex);
102 0 : MOZ_ASSERT(mClosed);
103 0 : MOZ_ASSERT(mFinalized);
104 :
105 0 : size_t len = GetAlignedDataLength();
106 0 : RefPtr<SharedMemoryBasic> buf = new SharedMemoryBasic();
107 0 : if (NS_WARN_IF(!buf->Create(len)) ||
108 0 : NS_WARN_IF(!buf->Map(len))) {
109 0 : return false;
110 : }
111 :
112 0 : size_t copyLen = GetDataLength();
113 0 : memcpy(buf->memory(), mBuf->memory(), copyLen);
114 0 : buf->Protect(static_cast<char*>(buf->memory()), len, RightsRead);
115 :
116 0 : if (mMapCount > 0 && !mOldBuf) {
117 0 : mOldBuf = Move(mBuf);
118 : }
119 0 : mBuf = Move(buf);
120 0 : mClosed = false;
121 0 : mShared = false;
122 0 : return true;
123 : }
124 :
125 : void
126 0 : SourceSurfaceSharedData::Finalize()
127 : {
128 0 : MutexAutoLock lock(mMutex);
129 0 : MOZ_ASSERT(!mClosed);
130 0 : MOZ_ASSERT(!mFinalized);
131 :
132 0 : size_t len = GetAlignedDataLength();
133 0 : mBuf->Protect(static_cast<char*>(mBuf->memory()), len, RightsRead);
134 :
135 0 : mFinalized = true;
136 0 : CloseHandleInternal();
137 0 : }
138 :
139 : } // namespace gfx
140 : } // namespace mozilla
|