Backed out 2 changesets (bug 1639563) for gfx related bustages CLOSED TREE

DONTBUILD
Backed out changeset b2c8de065886 (bug 1639563)
Backed out changeset 43abf0a9602a (bug 1639563)
This commit is contained in:
Bogdan Tara 2020-05-22 06:55:28 +03:00
Родитель 2bf24e6359
Коммит 107fbafd77
9 изменённых файлов: 132 добавлений и 309 удалений

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

@ -230,15 +230,12 @@ bool ShmSegmentsReader::Read(const layers::OffsetRange& aRange,
size_t initialLength = aInto.Length();
size_t srcCursor = aRange.start();
size_t remainingBytesToCopy = aRange.length();
int remainingBytesToCopy = aRange.length();
while (remainingBytesToCopy > 0) {
const size_t shm_idx = srcCursor / mChunkSize;
const size_t ptrOffset = srcCursor % mChunkSize;
if (ptrOffset >= mChunkSize) {
break;
}
const size_t copyRange =
std::min(remainingBytesToCopy, mChunkSize - ptrOffset);
std::min<int>(remainingBytesToCopy, mChunkSize - ptrOffset);
uint8_t* srcPtr =
RefCountedShm::GetBytes(mSmallAllocs[shm_idx]) + ptrOffset;
@ -251,53 +248,6 @@ bool ShmSegmentsReader::Read(const layers::OffsetRange& aRange,
return aInto.Length() - initialLength == aRange.length();
}
Maybe<Range<uint8_t>> ShmSegmentsReader::GetReadPointerLarge(
const layers::OffsetRange& aRange) {
// source = zero is for small allocs.
MOZ_RELEASE_ASSERT(aRange.source() != 0);
if (aRange.source() > mLargeAllocs.Length()) {
return Nothing();
}
size_t id = aRange.source() - 1;
const ipc::Shmem& shm = mLargeAllocs[id];
if (shm.Size<uint8_t>() < aRange.length()) {
return Nothing();
}
uint8_t* srcPtr = shm.get<uint8_t>();
return Some(Range<uint8_t>(srcPtr, aRange.length()));
}
Maybe<Range<uint8_t>> ShmSegmentsReader::GetReadPointer(
const layers::OffsetRange& aRange) {
if (aRange.length() == 0) {
return Some(Range<uint8_t>());
}
if (aRange.source() != 0) {
return GetReadPointerLarge(aRange);
}
if (mChunkSize == 0 ||
aRange.start() + aRange.length() > mChunkSize * mSmallAllocs.Length()) {
return Nothing();
}
size_t srcCursor = aRange.start();
size_t remainingBytesToCopy = aRange.length();
const size_t shm_idx = srcCursor / mChunkSize;
const size_t ptrOffset = srcCursor % mChunkSize;
// Return nothing if we can't return a pointer to the full range
if (ptrOffset >= mChunkSize ||
mChunkSize - ptrOffset < remainingBytesToCopy) {
return Nothing();
}
const size_t copyRange =
std::min(remainingBytesToCopy, mChunkSize - ptrOffset);
uint8_t* srcPtr = RefCountedShm::GetBytes(mSmallAllocs[shm_idx]) + ptrOffset;
return Some(Range<uint8_t>(srcPtr, copyRange));
}
IpcResourceUpdateQueue::IpcResourceUpdateQueue(
layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize)
: mWriter(aAllocator, aChunkSize) {}

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

@ -71,34 +71,9 @@ class ShmSegmentsReader {
bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
// Get a read pointer, if possible, directly into the shm. If the range has
// been broken up into multiple chunks that can't be represented by a single
// range, nothing will be returned to indicate failure.
Maybe<Range<uint8_t>> GetReadPointer(const layers::OffsetRange& aRange);
// Get a read pointer, if possible, directly into the shm. Otherwise, copy
// it into the Vec and return a pointer to that contiguous memory instead.
// If all fails, return nothing.
Maybe<Range<uint8_t>> GetReadPointerOrCopy(const layers::OffsetRange& aRange,
wr::Vec<uint8_t>& aInto) {
if (Maybe<Range<uint8_t>> ptr = GetReadPointer(aRange)) {
return ptr;
} else {
size_t initialLength = aInto.Length();
if (Read(aRange, aInto)) {
return Some(Range<uint8_t>(aInto.Data() + initialLength,
aInto.Length() - initialLength));
} else {
return Nothing();
}
}
}
protected:
bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
Maybe<Range<uint8_t>> GetReadPointerLarge(const layers::OffsetRange& aRange);
const nsTArray<layers::RefCountedShmem>& mSmallAllocs;
const nsTArray<mozilla::ipc::Shmem>& mLargeAllocs;
size_t mChunkSize;
@ -112,8 +87,9 @@ class IpcResourceUpdateQueue {
// we use here. The RefCountedShmem type used to allocate the chunks keeps a
// 16 bytes header in the buffer which we account for here as well. So we pick
// 64k - 2 * 4k - 16 = 57328 bytes as the default alloc size.
explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator,
size_t aChunkSize = 57328);
explicit IpcResourceUpdateQueue(
layers::WebRenderBridgeChild* aAllocator,
size_t aChunkSize = 57328);
IpcResourceUpdateQueue(IpcResourceUpdateQueue&& aOther) noexcept;
IpcResourceUpdateQueue& operator=(IpcResourceUpdateQueue&& aOther) noexcept;

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

@ -8,7 +8,7 @@
#include "CompositableHost.h"
#include "gfxEnv.h"
#include "gfxOTSUtils.h"
#include "gfxEnv.h"
#include "GeckoProfiler.h"
#include "GLContext.h"
#include "GLContextProvider.h"
@ -430,48 +430,6 @@ void WebRenderBridgeParent::Destroy() {
ClearResources();
}
struct WROTSAlloc {
wr::Vec<uint8_t> mVec;
void* Grow(void* aPtr, size_t aLength) {
if (aLength > mVec.Length()) {
mVec.Reserve(aLength - mVec.Length());
}
return mVec.inner.data;
}
wr::Vec<uint8_t> ShrinkToFit(void* aPtr, size_t aLength) {
wr::Vec<uint8_t> result(std::move(mVec));
result.inner.length = aLength;
return result;
}
void Free(void* aPtr) {}
};
static bool ReadRawFont(const OpAddRawFont& aOp, wr::ShmSegmentsReader& aReader,
wr::TransactionBuilder& aUpdates) {
wr::Vec<uint8_t> sourceBytes;
Maybe<Range<uint8_t>> ptr =
aReader.GetReadPointerOrCopy(aOp.bytes(), sourceBytes);
if (ptr.isNothing()) {
return false;
}
Range<uint8_t>& source = ptr.ref();
// Attempt to sanitize the font before passing it along for updating
size_t lengthHint = gfxOTSContext::GuessSanitizedFontSize(
source.begin().get(), source.length());
if (!lengthHint) {
return false;
}
gfxOTSExpandingMemoryStream<WROTSAlloc> output(lengthHint);
gfxOTSContext otsContext;
if (!otsContext.Process(&output, source.begin().get(), source.length())) {
return false;
}
wr::Vec<uint8_t> bytes = output.forget();
aUpdates.AddRawFont(aOp.key(), bytes, aOp.fontIndex());
return true;
}
bool WebRenderBridgeParent::UpdateResources(
const nsTArray<OpUpdateResource>& aResourceUpdates,
const nsTArray<RefCountedShmem>& aSmallShmems,
@ -571,9 +529,12 @@ bool WebRenderBridgeParent::UpdateResources(
break;
}
case OpUpdateResource::TOpAddRawFont: {
if (!ReadRawFont(cmd.get_OpAddRawFont(), reader, aUpdates)) {
const auto& op = cmd.get_OpAddRawFont();
wr::Vec<uint8_t> bytes;
if (!reader.Read(op.bytes(), bytes)) {
return false;
}
aUpdates.AddRawFont(op.key(), bytes, op.fontIndex());
break;
}
case OpUpdateResource::TOpAddFontDescriptor: {

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

@ -1,157 +0,0 @@
/* -*- 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/. */
#ifndef GFX_OTS_UTILS_H
#define GFX_OTS_UTILS_H
#include "gfxFontUtils.h"
#include "opentype-sanitiser.h"
struct gfxOTSMozAlloc {
void* Grow(void* aPtr, size_t aLength) { return moz_xrealloc(aPtr, aLength); }
void* ShrinkToFit(void* aPtr, size_t aLength) {
return moz_xrealloc(aPtr, aLength);
}
void Free(void* aPtr) { free(aPtr); }
};
// Based on ots::ExpandingMemoryStream from ots-memory-stream.h,
// adapted to use Mozilla allocators and to allow the final
// memory buffer to be adopted by the client.
template <typename AllocT = gfxOTSMozAlloc>
class gfxOTSExpandingMemoryStream : public ots::OTSStream {
public:
// limit output/expansion to 256MB by default
enum { DEFAULT_LIMIT = 256 * 1024 * 1024 };
explicit gfxOTSExpandingMemoryStream(size_t initial,
size_t limit = DEFAULT_LIMIT)
: mLength(initial), mLimit(limit), mOff(0) {
mPtr = mAlloc.Grow(nullptr, mLength);
}
~gfxOTSExpandingMemoryStream() { mAlloc.Free(mPtr); }
// Return the buffer, resized to fit its contents (as it may have been
// over-allocated during growth), and give up ownership of it so the
// caller becomes responsible to call free() when finished with it.
auto forget() {
auto p = mAlloc.ShrinkToFit(mPtr, mOff);
mPtr = nullptr;
return p;
}
bool WriteRaw(const void* data, size_t length) override {
if ((mOff + length > mLength) ||
(mLength > std::numeric_limits<size_t>::max() - mOff)) {
if (mLength == mLimit) {
return false;
}
size_t newLength = (mLength + 1) * 2;
if (newLength < mLength) {
return false;
}
if (newLength > mLimit) {
newLength = mLimit;
}
mPtr = mAlloc.Grow(mPtr, newLength);
mLength = newLength;
return WriteRaw(data, length);
}
std::memcpy(static_cast<char*>(mPtr) + mOff, data, length);
mOff += length;
return true;
}
bool Seek(off_t position) override {
if (position < 0) {
return false;
}
if (static_cast<size_t>(position) > mLength) {
return false;
}
mOff = position;
return true;
}
off_t Tell() const override { return mOff; }
private:
AllocT mAlloc;
void* mPtr;
size_t mLength;
const size_t mLimit;
off_t mOff;
};
class MOZ_STACK_CLASS gfxOTSContext : public ots::OTSContext {
public:
gfxOTSContext() {
using namespace mozilla;
// Whether to apply OTS validation to OpenType Layout tables
mCheckOTLTables = StaticPrefs::gfx_downloadable_fonts_otl_validation();
// Whether to preserve Variation tables in downloaded fonts
mCheckVariationTables =
StaticPrefs::gfx_downloadable_fonts_validate_variation_tables();
// Whether to preserve color bitmap glyphs
mKeepColorBitmaps =
StaticPrefs::gfx_downloadable_fonts_keep_color_bitmaps();
}
virtual ots::TableAction GetTableAction(uint32_t aTag) override {
// Preserve Graphite, color glyph and SVG tables,
// and possibly OTL and Variation tables (depending on prefs)
if ((!mCheckOTLTables && (aTag == TRUETYPE_TAG('G', 'D', 'E', 'F') ||
aTag == TRUETYPE_TAG('G', 'P', 'O', 'S') ||
aTag == TRUETYPE_TAG('G', 'S', 'U', 'B'))) ||
(!mCheckVariationTables &&
(aTag == TRUETYPE_TAG('a', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('c', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('f', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('g', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('H', 'V', 'A', 'R') ||
aTag == TRUETYPE_TAG('M', 'V', 'A', 'R') ||
aTag == TRUETYPE_TAG('S', 'T', 'A', 'T') ||
aTag == TRUETYPE_TAG('V', 'V', 'A', 'R'))) ||
aTag == TRUETYPE_TAG('S', 'V', 'G', ' ') ||
aTag == TRUETYPE_TAG('C', 'O', 'L', 'R') ||
aTag == TRUETYPE_TAG('C', 'P', 'A', 'L') ||
(mKeepColorBitmaps && (aTag == TRUETYPE_TAG('C', 'B', 'D', 'T') ||
aTag == TRUETYPE_TAG('C', 'B', 'L', 'C'))) ||
false) {
return ots::TABLE_ACTION_PASSTHRU;
}
return ots::TABLE_ACTION_DEFAULT;
}
static size_t GuessSanitizedFontSize(size_t aLength,
gfxUserFontType aFontType) {
switch (aFontType) {
case GFX_USERFONT_UNKNOWN:
return 0;
case GFX_USERFONT_WOFF:
return aLength * 2;
case GFX_USERFONT_WOFF2:
return aLength * 3;
default:
return aLength;
}
}
static size_t GuessSanitizedFontSize(const uint8_t* aData, size_t aLength) {
gfxUserFontType fontType =
gfxFontUtils::DetermineFontDataType(aData, aLength);
return GuessSanitizedFontSize(aLength, fontType);
}
private:
bool mCheckOTLTables;
bool mCheckVariationTables;
bool mKeepColorBitmaps;
};
#endif /* GFX_OTS_UTILS_H */

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

@ -17,7 +17,9 @@
#include "gfxPlatformFontList.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/PostTraversalTask.h"
#include "gfxOTSUtils.h"
#include "opentype-sanitiser.h"
#include "ots-memory-stream.h"
using namespace mozilla;
@ -33,6 +35,69 @@ mozilla::LogModule* gfxUserFontSet::GetUserFontsLog() {
static uint64_t sFontSetGeneration = 0;
// Based on ots::ExpandingMemoryStream from ots-memory-stream.h,
// adapted to use Mozilla allocators and to allow the final
// memory buffer to be adopted by the client.
class ExpandingMemoryStream : public ots::OTSStream {
public:
ExpandingMemoryStream(size_t initial, size_t limit)
: mLength(initial), mLimit(limit), mOff(0) {
mPtr = moz_xmalloc(mLength);
}
~ExpandingMemoryStream() { free(mPtr); }
// Return the buffer, resized to fit its contents (as it may have been
// over-allocated during growth), and give up ownership of it so the
// caller becomes responsible to call free() when finished with it.
void* forget() {
void* p = moz_xrealloc(mPtr, mOff);
mPtr = nullptr;
return p;
}
bool WriteRaw(const void* data, size_t length) override {
if ((mOff + length > mLength) ||
(mLength > std::numeric_limits<size_t>::max() - mOff)) {
if (mLength == mLimit) {
return false;
}
size_t newLength = (mLength + 1) * 2;
if (newLength < mLength) {
return false;
}
if (newLength > mLimit) {
newLength = mLimit;
}
mPtr = moz_xrealloc(mPtr, newLength);
mLength = newLength;
return WriteRaw(data, length);
}
std::memcpy(static_cast<char*>(mPtr) + mOff, data, length);
mOff += length;
return true;
}
bool Seek(off_t position) override {
if (position < 0) {
return false;
}
if (static_cast<size_t>(position) > mLength) {
return false;
}
mOff = position;
return true;
}
off_t Tell() const override { return mOff; }
private:
void* mPtr;
size_t mLength;
const size_t mLimit;
off_t mOff;
};
gfxUserFontEntry::gfxUserFontEntry(
gfxUserFontSet* aFontSet, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
WeightRange aWeight, StretchRange aStretch, SlantStyleRange aStyle,
@ -115,12 +180,49 @@ gfxFont* gfxUserFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle) {
return nullptr;
}
class MOZ_STACK_CLASS gfxOTSMessageContext : public gfxOTSContext {
class MOZ_STACK_CLASS gfxOTSContext : public ots::OTSContext {
public:
virtual ~gfxOTSMessageContext() {
gfxOTSContext() {
// Whether to apply OTS validation to OpenType Layout tables
mCheckOTLTables = StaticPrefs::gfx_downloadable_fonts_otl_validation();
// Whether to preserve Variation tables in downloaded fonts
mCheckVariationTables =
StaticPrefs::gfx_downloadable_fonts_validate_variation_tables();
// Whether to preserve color bitmap glyphs
mKeepColorBitmaps =
StaticPrefs::gfx_downloadable_fonts_keep_color_bitmaps();
}
virtual ~gfxOTSContext() {
MOZ_ASSERT(mMessages.IsEmpty(), "should have called TakeMessages");
}
virtual ots::TableAction GetTableAction(uint32_t aTag) override {
// Preserve Graphite, color glyph and SVG tables,
// and possibly OTL and Variation tables (depending on prefs)
if ((!mCheckOTLTables && (aTag == TRUETYPE_TAG('G', 'D', 'E', 'F') ||
aTag == TRUETYPE_TAG('G', 'P', 'O', 'S') ||
aTag == TRUETYPE_TAG('G', 'S', 'U', 'B'))) ||
(!mCheckVariationTables &&
(aTag == TRUETYPE_TAG('a', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('c', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('f', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('g', 'v', 'a', 'r') ||
aTag == TRUETYPE_TAG('H', 'V', 'A', 'R') ||
aTag == TRUETYPE_TAG('M', 'V', 'A', 'R') ||
aTag == TRUETYPE_TAG('S', 'T', 'A', 'T') ||
aTag == TRUETYPE_TAG('V', 'V', 'A', 'R'))) ||
aTag == TRUETYPE_TAG('S', 'V', 'G', ' ') ||
aTag == TRUETYPE_TAG('C', 'O', 'L', 'R') ||
aTag == TRUETYPE_TAG('C', 'P', 'A', 'L') ||
(mKeepColorBitmaps && (aTag == TRUETYPE_TAG('C', 'B', 'D', 'T') ||
aTag == TRUETYPE_TAG('C', 'B', 'L', 'C'))) ||
false) {
return ots::TABLE_ACTION_PASSTHRU;
}
return ots::TABLE_ACTION_DEFAULT;
}
virtual void Message(int level, const char* format,
...) MSGFUNC_FMT_ATTR override {
va_list va;
@ -157,6 +259,9 @@ class MOZ_STACK_CLASS gfxOTSMessageContext : public gfxOTSContext {
private:
nsTHashtable<nsCStringHashKey> mWarningsIssued;
nsTArray<gfxUserFontEntry::OTSMessage> mMessages;
bool mCheckOTLTables;
bool mCheckVariationTables;
bool mKeepColorBitmaps;
};
// Call the OTS library to sanitize an sfnt before attempting to use it.
@ -167,15 +272,22 @@ const uint8_t* gfxUserFontEntry::SanitizeOpenTypeData(
aFontType = gfxFontUtils::DetermineFontDataType(aData, aLength);
Telemetry::Accumulate(Telemetry::WEBFONT_FONTTYPE, uint32_t(aFontType));
size_t lengthHint = gfxOTSContext::GuessSanitizedFontSize(aLength, aFontType);
if (!lengthHint) {
if (aFontType == GFX_USERFONT_UNKNOWN) {
aSaneLength = 0;
return nullptr;
}
gfxOTSExpandingMemoryStream output(lengthHint);
uint32_t lengthHint = aLength;
if (aFontType == GFX_USERFONT_WOFF) {
lengthHint *= 2;
} else if (aFontType == GFX_USERFONT_WOFF2) {
lengthHint *= 3;
}
gfxOTSMessageContext otsContext;
// limit output/expansion to 256MB
ExpandingMemoryStream output(lengthHint, 1024 * 1024 * 256);
gfxOTSContext otsContext;
if (!otsContext.Process(&output, aData, aLength, aMessages)) {
// Failed to decode/sanitize the font, so discard it.
aSaneLength = 0;

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

@ -181,11 +181,11 @@ class gfxUserFontFamily : public gfxFontFamily {
};
class gfxUserFontEntry;
class gfxOTSMessageContext;
class gfxOTSContext;
class gfxUserFontSet {
friend class gfxUserFontEntry;
friend class gfxOTSMessageContext;
friend class gfxOTSContext;
public:
typedef mozilla::FontStretch FontStretch;
@ -531,7 +531,7 @@ class gfxUserFontEntry : public gfxFontEntry {
friend class gfxUserFontSet;
friend class nsUserFontSet;
friend class nsFontFaceLoader;
friend class gfxOTSMessageContext;
friend class gfxOTSContext;
public:
enum UserFontLoadState {

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

@ -44,7 +44,6 @@ EXPORTS += [
'gfxLineSegment.h',
'gfxMathTable.h',
'gfxMatrix.h',
'gfxOTSUtils.h',
'gfxPattern.h',
'gfxPlatform.h',
'gfxPlatformFontList.h',

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

@ -652,18 +652,12 @@ struct Vec<uint8_t> final {
inner.length = 0;
}
uint8_t* Data() { return inner.data; }
size_t Length() { return inner.length; }
Range<uint8_t> GetRange() { return Range<uint8_t>(Data(), Length()); }
void PushBytes(Range<uint8_t> aBytes) {
wr_vec_u8_push_bytes(&inner, RangeToByteSlice(aBytes));
}
void Reserve(size_t aLength) { wr_vec_u8_reserve(&inner, aLength); }
~Vec() {
if (inner.data) {
wr_vec_u8_free(inner);

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

@ -269,18 +269,11 @@ impl WrVecU8 {
w
}
fn reserve(&mut self, len: usize) {
let mut vec = self.flush_into_vec();
vec.reserve(len);
*self = Self::from_vec(vec);
}
fn push_bytes(&mut self, bytes: &[u8]) {
let mut vec = self.flush_into_vec();
vec.extend_from_slice(bytes);
*self = Self::from_vec(vec);
}
}
#[no_mangle]
@ -288,11 +281,6 @@ pub extern "C" fn wr_vec_u8_push_bytes(v: &mut WrVecU8, bytes: ByteSlice) {
v.push_bytes(bytes.as_slice());
}
#[no_mangle]
pub extern "C" fn wr_vec_u8_reserve(v: &mut WrVecU8, len: usize) {
v.reserve(len);
}
#[no_mangle]
pub extern "C" fn wr_vec_u8_free(v: WrVecU8) {
v.to_vec();