Back out a5a5d2c176f7 (bug 882865) because of Android test failures on a CLOSED TREE
[gecko.git] / gfx / layers / YCbCrImageDataSerializer.cpp
blob31ef7a59ab0ec0041af7bba4d6bf050cedcc858d
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/. */
6 #include "mozilla/layers/YCbCrImageDataSerializer.h"
8 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
10 using namespace mozilla::ipc;
12 namespace mozilla {
13 namespace layers {
15 // The Data is layed out as follows:
17 // +-----------------+ -++ --+ --+ <-- Beginning of the buffer
18 // | YCbCrBufferInfo | | | |
19 // +-----------------+ --+ | |
20 // | data | | | YCbCrBufferInfo->[mY/mCb/mCr]Offset
21 // +-----------------+ ------+ |
22 // | data | |
23 // +-----------------+ ----------+
24 // | data |
25 // +-----------------+
27 // There can be padding between the blocks above to keep word alignment.
29 // Structure written at the beginning og the data blob containing the image
30 // (as shown in the figure above). It contains the necessary informations to
31 // read the image in the blob.
32 struct YCbCrBufferInfo
34 uint32_t mYOffset;
35 uint32_t mCbOffset;
36 uint32_t mCrOffset;
37 uint32_t mYWidth;
38 uint32_t mYHeight;
39 uint32_t mCbCrWidth;
40 uint32_t mCbCrHeight;
43 static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData)
45 return reinterpret_cast<YCbCrBufferInfo*>(aData);
48 bool YCbCrImageDataDeserializerBase::IsValid()
50 if (mData == nullptr) {
51 return false;
53 return true;
56 uint8_t* YCbCrImageDataDeserializerBase::GetYData()
58 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
59 return reinterpret_cast<uint8_t*>(info) + info->mYOffset;
62 uint8_t* YCbCrImageDataDeserializerBase::GetCbData()
64 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
65 return reinterpret_cast<uint8_t*>(info) + info->mCbOffset;
68 uint8_t* YCbCrImageDataDeserializerBase::GetCrData()
70 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
71 return reinterpret_cast<uint8_t*>(info) + info->mCrOffset;
74 uint8_t* YCbCrImageDataDeserializerBase::GetData()
76 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
77 return (reinterpret_cast<uint8_t*>(info)) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
80 uint32_t YCbCrImageDataDeserializerBase::GetYStride()
82 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
83 return info->mYWidth;
86 uint32_t YCbCrImageDataDeserializerBase::GetCbCrStride()
88 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
89 return info->mCbCrWidth;
92 gfxIntSize YCbCrImageDataDeserializerBase::GetYSize()
94 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
95 return gfxIntSize(info->mYWidth, info->mYHeight);
98 gfxIntSize YCbCrImageDataDeserializerBase::GetCbCrSize()
100 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
101 return gfxIntSize(info->mCbCrWidth, info->mCbCrHeight);
104 // Offset in bytes
105 static size_t ComputeOffset(uint32_t aHeight, uint32_t aStride)
107 return MOZ_ALIGN_WORD(aHeight * aStride);
110 // Minimum required shmem size in bytes
111 size_t
112 YCbCrImageDataSerializer::ComputeMinBufferSize(const gfx::IntSize& aYSize,
113 const gfx::IntSize& aCbCrSize)
115 uint32_t yStride = aYSize.width;
116 uint32_t CbCrStride = aCbCrSize.width;
118 return ComputeOffset(aYSize.height, yStride)
119 + 2 * ComputeOffset(aCbCrSize.height, CbCrStride)
120 + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
123 size_t
124 YCbCrImageDataSerializer::ComputeMinBufferSize(const gfxIntSize& aYSize,
125 const gfxIntSize& aCbCrSize)
127 return ComputeMinBufferSize(gfx::IntSize(aYSize.width, aYSize.height),
128 gfx::IntSize(aCbCrSize.width, aCbCrSize.height));
130 // Offset in bytes
131 static size_t ComputeOffset(uint32_t aSize)
133 return MOZ_ALIGN_WORD(aSize);
136 // Minimum required shmem size in bytes
137 size_t
138 YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize)
140 return ComputeOffset(aSize) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
143 void
144 YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize& aYSize,
145 const gfx::IntSize& aCbCrSize)
147 YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
148 info->mYOffset = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
149 info->mCbOffset = info->mYOffset
150 + MOZ_ALIGN_WORD(aYSize.width * aYSize.height);
151 info->mCrOffset = info->mCbOffset
152 + MOZ_ALIGN_WORD(aCbCrSize.width * aCbCrSize.height);
154 info->mYWidth = aYSize.width;
155 info->mYHeight = aYSize.height;
156 info->mCbCrWidth = aCbCrSize.width;
157 info->mCbCrHeight = aCbCrSize.height;
160 void
161 YCbCrImageDataSerializer::InitializeBufferInfo(const gfxIntSize& aYSize,
162 const gfxIntSize& aCbCrSize)
164 InitializeBufferInfo(gfx::IntSize(aYSize.width, aYSize.height),
165 gfx::IntSize(aCbCrSize.width, aCbCrSize.height));
168 static void CopyLineWithSkip(const uint8_t* src, uint8_t* dst, uint32_t len, uint32_t skip) {
169 for (uint32_t i = 0; i < len; ++i) {
170 *dst = *src;
171 src += 1 + skip;
172 ++dst;
176 bool
177 YCbCrImageDataSerializer::CopyData(const uint8_t* aYData,
178 const uint8_t* aCbData, const uint8_t* aCrData,
179 gfxIntSize aYSize, uint32_t aYStride,
180 gfxIntSize aCbCrSize, uint32_t aCbCrStride,
181 uint32_t aYSkip, uint32_t aCbCrSkip)
183 if (!IsValid() || GetYSize() != aYSize || GetCbCrSize() != aCbCrSize) {
184 return false;
186 for (int i = 0; i < aYSize.height; ++i) {
187 if (aYSkip == 0) {
188 // fast path
189 memcpy(GetYData() + i * GetYStride(),
190 aYData + i * aYStride,
191 aYSize.width);
192 } else {
193 // slower path
194 CopyLineWithSkip(aYData + i * aYStride,
195 GetYData() + i * GetYStride(),
196 aYSize.width, aYSkip);
199 for (int i = 0; i < aCbCrSize.height; ++i) {
200 if (aCbCrSkip == 0) {
201 // fast path
202 memcpy(GetCbData() + i * GetCbCrStride(),
203 aCbData + i * aCbCrStride,
204 aCbCrSize.width);
205 memcpy(GetCrData() + i * GetCbCrStride(),
206 aCrData + i * aCbCrStride,
207 aCbCrSize.width);
208 } else {
209 // slower path
210 CopyLineWithSkip(aCbData + i * aCbCrStride,
211 GetCbData() + i * GetCbCrStride(),
212 aCbCrSize.width, aCbCrSkip);
213 CopyLineWithSkip(aCrData + i * aCbCrStride,
214 GetCrData() + i * GetCbCrStride(),
215 aCbCrSize.width, aCbCrSkip);
218 return true;
222 } // namespace
223 } // namespace