Files
palemoon27/gfx/layers/ImageDataSerializer.cpp
T
roytam1 6a4edbe796 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1221716 - Part 1: Make the simpler parts of BytecodeEmitter::emitTree() use the `ok` boolean consistently. r=Waldo. (8b2eae4dcf)
- Bug 1221716 - Part 2: Factor out all remaining complex cases from the switch statement in emitTree(). r=Waldo. (805c9a96da)
- Bug 1221737 - Drop some BytecodeEmitter checks for cases that the Parser rules out. r=jonco. (9726a6527b)
- Bug 1224460 - Use pwd -W to fill _topsrcdir in configure. r=gps (cc7bf71652)
- Bug 1221737 followup - Bump XDR_BYTECODE_VERSION_SUBTRAHEND to fix build errors on a CLOSED TREE. r=bustage (d2d2f41a14)
- Bug 1170913, full-update target in tools/update-packaging/ always runs automation-partial-patch, r=glandium DONTBUILD (12e5e212d8)
- Bug 1137756 - Use absolute paths in complete-patch.patch. r=gps (62fc37688b)
- Bug 1173998 - use localized package for previous mar; r=nthomas (fb6c95955c)
- Bug 1173459 - Stop generating partial MAR files and publishing complete MARs to balrog as a part of nightly automation. r=mshal (4c427b9f7f)
- Bug 1164580 - Preprocess ua-update.json via slashslash filter. r=fabrice (d934f84f15)
- Bug 1200021 - Part 2: more diagnostics. r=bas (e1cfecbbd4)
- Bug 1200021 - crash in mozilla::layers::ContentClientDoubleBuffered::FinalizeFrame(nsIntRegion const&): Diagnostics to get more data. r=bas (d782b24501)
- Bug 1222569 - fix initialization order in DataTextureSourceD3D9; r=Bas (028939600b)
- Bug 1209801 - Part 1: Add TextureFlags parameter to TextureClientPool. r=mattwoodrow (c5b73613f9)
- Bug 1209801 - Part 2: Do not allow big image textures to be used with TiledLayerBuffers. r=mattwoodrow (cb553ccdea)
- Bug 1211615: Upload the full texture on the first upload for component alpha textures. r=nical (3bd6688679)
- minor (928a95b259)
- Bug 1222569 - remove unused variable in TextureD3D9.cpp; r=Bas (ac5a86be1c)
- Bug 1223928 - Make the horizontal scrollbar on the root scrollable shift correctly with the dynamic toolbar. r=botond (6c6c0b8c24)
- Bug 1216349: Upload the old valid region as well if our texture host changed. r=nical (7d4d041bd2)
- Bug 1236227, don't OOM in TextDecoder, r=baku (9bef90eada)
- Bug 1218594 - r=smaug (de39570c72)
- remove include (62e582fe3d)
- Bug 1226176 - Compute retained sizes in dominator trees and expose them to JavaScript; r=bz,sfink (92bb08a674)
2023-01-27 10:51:45 +08:00

178 lines
5.1 KiB
C++

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ImageDataSerializer.h"
#include "gfx2DGlue.h" // for SurfaceFormatToImageFormat
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/gfx/2D.h" // for DataSourceSurface, Factory
#include "mozilla/gfx/Logging.h" // for gfxDebug
#include "mozilla/gfx/Tools.h" // for GetAlignedStride, etc
#include "mozilla/mozalloc.h" // for operator delete, etc
namespace mozilla {
namespace layers {
using namespace gfx;
// The Data is layed out as follows:
//
// +-------------------+ -++ --+ <-- ImageDataSerializerBase::mData pointer
// | SurfaceBufferInfo | | |
// +-------------------+ --+ | offset
// | ... | |
// +-------------------+ ------+
// | |
// | data |
// | |
// +-------------------+
// Structure written at the beginning of the data blob containing the image
// (as shown in the figure above). It contains the necessary informations to
// read the image in the blob.
namespace {
struct SurfaceBufferInfo
{
int32_t width;
int32_t height;
SurfaceFormat format;
static int32_t GetOffset()
{
return GetAlignedStride<16>(sizeof(SurfaceBufferInfo));
}
};
} // namespace
static SurfaceBufferInfo*
GetBufferInfo(uint8_t* aData, size_t aDataSize)
{
return aDataSize >= sizeof(SurfaceBufferInfo)
? reinterpret_cast<SurfaceBufferInfo*>(aData)
: nullptr;
}
void
ImageDataSerializer::InitializeBufferInfo(IntSize aSize,
SurfaceFormat aFormat)
{
SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
MOZ_ASSERT(info); // OK to assert here, this method is client-side-only
info->width = aSize.width;
info->height = aSize.height;
info->format = aFormat;
Validate();
}
static inline int32_t
ComputeStride(SurfaceFormat aFormat, int32_t aWidth)
{
CheckedInt<int32_t> size = BytesPerPixel(aFormat);
size *= aWidth;
if (!size.isValid() || size.value() <= 0) {
gfxDebug() << "ComputeStride overflow " << aWidth;
return 0;
}
return GetAlignedStride<4>(size.value());
}
uint32_t
ImageDataSerializerBase::ComputeMinBufferSize(IntSize aSize,
SurfaceFormat aFormat)
{
MOZ_ASSERT(aSize.height >= 0 && aSize.width >= 0);
// This takes care of checking whether there could be overflow
// with enough margin for the metadata.
if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
return 0;
}
int32_t bufsize = GetAlignedStride<16>(ComputeStride(aFormat, aSize.width)
* aSize.height)
+ SurfaceBufferInfo::GetOffset();
if (bufsize < 0) {
// This should not be possible thanks to Factory::AllowedSurfaceSize
return 0;
}
return bufsize;
}
void
ImageDataSerializerBase::Validate()
{
mIsValid = false;
if (!mData) {
return;
}
SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
if (!info) {
return;
}
size_t requiredSize =
ComputeMinBufferSize(IntSize(info->width, info->height), info->format);
mIsValid = !!requiredSize && requiredSize <= mDataSize;
}
uint8_t*
ImageDataSerializerBase::GetData()
{
MOZ_ASSERT(IsValid());
return mData + SurfaceBufferInfo::GetOffset();
}
uint32_t
ImageDataSerializerBase::GetStride() const
{
MOZ_ASSERT(IsValid());
SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
return ComputeStride(GetFormat(), info->width);
}
IntSize
ImageDataSerializerBase::GetSize() const
{
MOZ_ASSERT(IsValid());
SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
return IntSize(info->width, info->height);
}
SurfaceFormat
ImageDataSerializerBase::GetFormat() const
{
MOZ_ASSERT(IsValid());
return GetBufferInfo(mData, mDataSize)->format;
}
already_AddRefed<DrawTarget>
ImageDataSerializerBase::GetAsDrawTarget(gfx::BackendType aBackend)
{
MOZ_ASSERT(IsValid());
RefPtr<DrawTarget> dt = gfx::Factory::CreateDrawTargetForData(aBackend,
GetData(), GetSize(),
GetStride(), GetFormat());
if (!dt) {
gfxCriticalNote << "Failed GetAsDrawTarget " << IsValid() << ", " << hexa(size_t(mData)) << " + " << SurfaceBufferInfo::GetOffset() << ", " << GetSize() << ", " << GetStride() << ", " << (int)GetFormat();
}
return dt.forget();
}
already_AddRefed<gfx::DataSourceSurface>
ImageDataSerializerBase::GetAsSurface()
{
MOZ_ASSERT(IsValid());
return Factory::CreateWrappingDataSourceSurface(GetData(),
GetStride(),
GetSize(),
GetFormat());
}
} // namespace layers
} // namespace mozilla