gfx/layers/ipc/SharedPlanarYCbCrImage.cpp

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:32c5e7628151
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 "SharedPlanarYCbCrImage.h"
7 #include <stddef.h> // for size_t
8 #include <stdio.h> // for printf
9 #include "gfx2DGlue.h" // for Moz2D transition helpers
10 #include "ISurfaceAllocator.h" // for ISurfaceAllocator, etc
11 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
12 #include "mozilla/gfx/Types.h" // for SurfaceFormat::SurfaceFormat::YUV
13 #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
14 #include "mozilla/layers/ImageClient.h" // for ImageClient
15 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
16 #include "mozilla/layers/TextureClient.h" // for BufferTextureClient, etc
17 #include "mozilla/layers/YCbCrImageDataSerializer.h"
18 #include "mozilla/layers/ImageBridgeChild.h" // for ImageBridgeChild
19 #include "mozilla/mozalloc.h" // for operator delete
20 #include "nsISupportsImpl.h" // for Image::AddRef
21 #include "mozilla/ipc/Shmem.h"
22
23 namespace mozilla {
24 namespace layers {
25
26 using namespace mozilla::ipc;
27
28 SharedPlanarYCbCrImage::SharedPlanarYCbCrImage(ImageClient* aCompositable)
29 : PlanarYCbCrImage(nullptr)
30 , mCompositable(aCompositable)
31 {
32 mTextureClient = aCompositable->CreateBufferTextureClient(gfx::SurfaceFormat::YUV);
33 MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
34 }
35
36 SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
37 MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
38
39 if (mCompositable->GetAsyncID() != 0 &&
40 !InImageBridgeChildThread()) {
41 ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient.forget().drop());
42 ImageBridgeChild::DispatchReleaseImageClient(mCompositable.forget().drop());
43 }
44 }
45
46 size_t
47 SharedPlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
48 {
49 // NB: Explicitly skipping mTextureClient, the memory is already reported
50 // at time of allocation in GfxMemoryImageReporter.
51 // Not owned:
52 // - mCompositable
53 size_t size = PlanarYCbCrImage::SizeOfExcludingThis(aMallocSizeOf);
54 return size;
55 }
56
57 TextureClient*
58 SharedPlanarYCbCrImage::GetTextureClient(CompositableClient* aClient)
59 {
60 return mTextureClient.get();
61 }
62
63 uint8_t*
64 SharedPlanarYCbCrImage::GetBuffer()
65 {
66 return mTextureClient->GetBuffer();
67 }
68
69 TemporaryRef<gfx::SourceSurface>
70 SharedPlanarYCbCrImage::GetAsSourceSurface()
71 {
72 if (!mTextureClient->IsAllocated()) {
73 NS_WARNING("Can't get as surface");
74 return nullptr;
75 }
76 return PlanarYCbCrImage::GetAsSourceSurface();
77 }
78
79 void
80 SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
81 {
82 // If mShmem has not been allocated (through Allocate(aData)), allocate it.
83 // This code path is slower than the one used when Allocate has been called
84 // since it will trigger a full copy.
85 if (!mTextureClient->IsAllocated()) {
86 Data data = aData;
87 if (!Allocate(data)) {
88 NS_WARNING("SharedPlanarYCbCrImage::SetData failed to allocate");
89 return;
90 }
91 }
92
93 MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
94 if (!mTextureClient->Lock(OPEN_WRITE_ONLY)) {
95 MOZ_ASSERT(false, "Failed to lock the texture.");
96 return;
97 }
98 TextureClientAutoUnlock unlock(mTextureClient);
99 if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
100 MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
101 return;
102 }
103 // do not set mBuffer like in PlanarYCbCrImage because the later
104 // will try to manage this memory without knowing it belongs to a
105 // shmem.
106 mBufferSize = YCbCrImageDataSerializer::ComputeMinBufferSize(mData.mYSize,
107 mData.mCbCrSize);
108 mSize = mData.mPicSize;
109
110 YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
111 mData.mYChannel = serializer.GetYData();
112 mData.mCbChannel = serializer.GetCbData();
113 mData.mCrChannel = serializer.GetCrData();
114 mTextureClient->MarkImmutable();
115 }
116
117 // needs to be overriden because the parent class sets mBuffer which we
118 // do not want to happen.
119 uint8_t*
120 SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
121 {
122 NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(), "This image already has allocated data");
123 size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aSize);
124
125 // get new buffer _without_ setting mBuffer.
126 if (!mTextureClient->Allocate(size)) {
127 return nullptr;
128 }
129
130 // update buffer size
131 mBufferSize = size;
132
133 YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
134 return serializer.GetData();
135 }
136
137 void
138 SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
139 {
140 mData = aData;
141 mSize = aData.mPicSize;
142 /* SetDataNoCopy is used to update YUV plane offsets without (re)allocating
143 * memory previously allocated with AllocateAndGetNewBuffer().
144 * serializer.GetData() returns the address of the memory previously allocated
145 * with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr
146 * channels to compute 0-based offsets to pass to InitializeBufferInfo.
147 */
148 YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
149 uint8_t *base = serializer.GetData();
150 uint32_t yOffset = aData.mYChannel - base;
151 uint32_t cbOffset = aData.mCbChannel - base;
152 uint32_t crOffset = aData.mCrChannel - base;
153 serializer.InitializeBufferInfo(yOffset,
154 cbOffset,
155 crOffset,
156 aData.mYStride,
157 aData.mCbCrStride,
158 aData.mYSize,
159 aData.mCbCrSize,
160 aData.mStereoMode);
161 }
162
163 uint8_t*
164 SharedPlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
165 {
166 NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
167 "This image already has allocated data");
168 if (!mTextureClient->Allocate(aSize)) {
169 return nullptr;
170 }
171 return mTextureClient->GetBuffer();
172 }
173
174 bool
175 SharedPlanarYCbCrImage::IsValid() {
176 return mTextureClient->IsAllocated();
177 }
178
179 bool
180 SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
181 {
182 NS_ABORT_IF_FALSE(!mTextureClient->IsAllocated(),
183 "This image already has allocated data");
184
185 size_t size = YCbCrImageDataSerializer::ComputeMinBufferSize(aData.mYSize,
186 aData.mCbCrSize);
187
188 if (AllocateBuffer(static_cast<uint32_t>(size)) == nullptr) {
189 return false;
190 }
191
192 YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
193 serializer.InitializeBufferInfo(aData.mYSize,
194 aData.mCbCrSize,
195 aData.mStereoMode);
196 MOZ_ASSERT(serializer.IsValid());
197
198 aData.mYChannel = serializer.GetYData();
199 aData.mCbChannel = serializer.GetCbData();
200 aData.mCrChannel = serializer.GetCrData();
201
202 // copy some of aData's values in mData (most of them)
203 mData.mYChannel = aData.mYChannel;
204 mData.mCbChannel = aData.mCbChannel;
205 mData.mCrChannel = aData.mCrChannel;
206 mData.mYSize = aData.mYSize;
207 mData.mCbCrSize = aData.mCbCrSize;
208 mData.mPicX = aData.mPicX;
209 mData.mPicY = aData.mPicY;
210 mData.mPicSize = aData.mPicSize;
211 mData.mStereoMode = aData.mStereoMode;
212 // those members are not always equal to aData's, due to potentially different
213 // packing.
214 mData.mYSkip = 0;
215 mData.mCbSkip = 0;
216 mData.mCrSkip = 0;
217 mData.mYStride = mData.mYSize.width;
218 mData.mCbCrStride = mData.mCbCrSize.width;
219
220 return true;
221 }
222
223 } // namespace
224 } // namespace

mercurial