Bug 1421187 - P3. Optimize pixels data copy and remove extra loop. r=mattwoodrow

There's no need to perform the format test within the loop, so we can separate the different cases as needed.
Also copy the entire pixel data in one go, by using C types.

The skip value definition doesn't specify if it's in bytes, or in "pixels". We will assume the later. There are currently no decoders returning HDR content with a skip value different than zero anyway.

MozReview-Commit-ID: KTwYuNKJq3R

--HG--
extra : rebase_source : 3f1989c37ebdab6a60605815a961eda7286c423c
This commit is contained in:
Jean-Yves Avenard 2017-11-28 16:29:49 +01:00
Родитель 5166929d97
Коммит 4fd0cbda6e
1 изменённых файлов: 46 добавлений и 16 удалений

Просмотреть файл

@ -1812,6 +1812,30 @@ TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, LayersIPC
return MakeAndAddRef<TextureClient>(aData, aFlags, aAllocator);
}
template<class PixelDataType>
static void
copyData(PixelDataType* aDst,
const MappedYCbCrChannelData& aChannelDst,
PixelDataType* aSrc,
const MappedYCbCrChannelData& aChannelSrc)
{
uint8_t* srcByte = reinterpret_cast<uint8_t*>(aSrc);
const int32_t srcSkip = aChannelSrc.skip + 1;
uint8_t* dstByte = reinterpret_cast<uint8_t*>(aDst);
const int32_t dstSkip = aChannelDst.skip + 1;
for (int32_t i = 0; i < aChannelSrc.size.height; ++i) {
for (int32_t j = 0; j < aChannelSrc.size.width; ++j) {
*aDst = *aSrc;
aSrc += srcSkip;
aDst += dstSkip;
}
srcByte += aChannelSrc.stride;
aSrc = reinterpret_cast<PixelDataType*>(srcByte);
dstByte += aChannelDst.stride;
aDst = reinterpret_cast<PixelDataType*>(dstByte);
}
}
bool
MappedYCbCrChannelData::CopyInto(MappedYCbCrChannelData& aDst)
{
@ -1827,26 +1851,32 @@ MappedYCbCrChannelData::CopyInto(MappedYCbCrChannelData& aDst)
return true;
}
for (int32_t i = 0; i < size.height; ++i) {
if (aDst.skip == 0 && skip == 0) {
// fast-ish path
if (aDst.skip == 0 && skip == 0) {
// fast-ish path
for (int32_t i = 0; i < size.height; ++i) {
memcpy(aDst.data + i * aDst.stride,
data + i * stride,
size.width * bytesPerPixel);
} else {
// slow path
uint8_t* src = data + i * stride;
uint8_t* dst = aDst.data + i * aDst.stride;
for (int32_t j = 0; j < size.width; ++j) {
for (uint32_t k = 0; k < bytesPerPixel; ++k) {
*dst = *src;
src += 1;
dst += 1;
}
src += skip;
dst += aDst.skip;
}
}
return true;
}
MOZ_ASSERT(bytesPerPixel == 1 || bytesPerPixel == 2);
// slow path
if (bytesPerPixel == 1) {
copyData(aDst.data, aDst, data, *this);
} else if (bytesPerPixel == 2) {
if (skip != 0) {
// The skip value definition doesn't specify if it's in bytes, or in
// "pixels". We will assume the later. There are currently no decoders
// returning HDR content with a skip value different than zero anyway.
NS_WARNING("skip value non zero for HDR content, please verify code "
"(see bug 1421187)");
}
copyData(reinterpret_cast<uint16_t*>(aDst.data),
aDst,
reinterpret_cast<uint16_t*>(data),
*this);
}
return true;
}