summaryrefslogtreecommitdiffstats
path: root/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'gfx')
-rw-r--r--gfx/2d/FilterNodeSoftware.cpp2
-rw-r--r--gfx/gl/GLTextureImage.cpp3
-rw-r--r--gfx/gl/GLUploadHelpers.cpp31
-rw-r--r--gfx/gl/GLUploadHelpers.h2
-rw-r--r--gfx/gl/GfxTexturesReporter.cpp8
-rw-r--r--gfx/gl/TextureImageEGL.cpp4
-rw-r--r--gfx/ipc/GPUChild.cpp9
-rw-r--r--gfx/ipc/GPUParent.cpp8
-rw-r--r--gfx/layers/ImageContainer.cpp23
-rw-r--r--gfx/layers/composite/TextureHost.cpp65
-rw-r--r--gfx/layers/composite/X11TextureHost.cpp13
-rw-r--r--gfx/layers/d3d11/TextureD3D11.cpp6
-rw-r--r--gfx/layers/opengl/CompositingRenderTargetOGL.cpp2
-rw-r--r--gfx/layers/opengl/CompositingRenderTargetOGL.h2
-rw-r--r--gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp8
-rw-r--r--gfx/layers/opengl/TextureHostOGL.cpp27
-rw-r--r--gfx/skia/skia/include/core/SkTypes.h6
-rw-r--r--gfx/skia/skia/include/private/SkTDArray.h8
-rw-r--r--gfx/skia/skia/src/core/SkMallocPixelRef.cpp13
-rw-r--r--gfx/skia/skia/src/core/SkMath.cpp15
-rw-r--r--gfx/skia/skia/src/core/SkSafeMath.h106
-rw-r--r--gfx/src/DriverCrashGuard.cpp19
-rw-r--r--gfx/src/gfxCrashReporterUtils.cpp4
-rw-r--r--gfx/tests/gtest/TestGfxPrefs.cpp24
-rw-r--r--gfx/tests/gtest/TestLayers.h16
-rw-r--r--gfx/tests/gtest/TestTextures.cpp7
-rw-r--r--gfx/thebes/gfxFT2Utils.cpp30
-rw-r--r--gfx/thebes/gfxFcPlatformFontList.cpp29
-rw-r--r--gfx/thebes/gfxFcPlatformFontList.h4
-rw-r--r--gfx/thebes/gfxPlatform.cpp8
-rw-r--r--gfx/thebes/gfxPlatformGtk.cpp6
-rwxr-xr-xgfx/thebes/gfxWindowsPlatform.cpp8
32 files changed, 352 insertions, 164 deletions
diff --git a/gfx/2d/FilterNodeSoftware.cpp b/gfx/2d/FilterNodeSoftware.cpp
index 3abdb7a02..169694069 100644
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -2796,7 +2796,7 @@ FilterNodeArithmeticCombineSoftware::SetAttribute(uint32_t aIndex,
uint32_t aSize)
{
MOZ_ASSERT(aIndex == ATT_ARITHMETIC_COMBINE_COEFFICIENTS);
- MOZ_ASSERT(aSize == 4);
+ MOZ_RELEASE_ASSERT(aSize == 4);
mK1 = aFloat[0];
mK2 = aFloat[1];
diff --git a/gfx/gl/GLTextureImage.cpp b/gfx/gl/GLTextureImage.cpp
index c91d558af..65678432d 100644
--- a/gfx/gl/GLTextureImage.cpp
+++ b/gfx/gl/GLTextureImage.cpp
@@ -149,6 +149,9 @@ BasicTextureImage::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion
&uploadSize,
needInit,
aFrom);
+ if (mTextureFormat == SurfaceFormat::UNKNOWN) {
+ return false;
+ }
if (uploadSize > 0) {
UpdateUploadSize(uploadSize);
diff --git a/gfx/gl/GLUploadHelpers.cpp b/gfx/gl/GLUploadHelpers.cpp
index 75165eedf..ca1c890a4 100644
--- a/gfx/gl/GLUploadHelpers.cpp
+++ b/gfx/gl/GLUploadHelpers.cpp
@@ -27,6 +27,23 @@ DataOffset(const IntPoint& aPoint, int32_t aStride, SurfaceFormat aFormat)
return data;
}
+static bool
+CheckUploadBounds(const IntSize& aDst, const IntSize& aSrc, const IntPoint& aOffset)
+{
+ if (aOffset.x < 0 || aOffset.y < 0 ||
+ aOffset.x >= aSrc.width ||
+ aOffset.y >= aSrc.height) {
+ MOZ_ASSERT_UNREACHABLE("Offset outside source bounds");
+ return false;
+ }
+ if (aDst.width > (aSrc.width - aOffset.x) ||
+ aDst.height > (aSrc.height - aOffset.y)) {
+ MOZ_ASSERT_UNREACHABLE("Source has insufficient data");
+ return false;
+ }
+ return true;
+}
+
static GLint GetAddressAlignment(ptrdiff_t aAddress)
{
if (!(aAddress & 0x7)) {
@@ -375,6 +392,7 @@ TexImage2DHelper(GLContext* gl,
SurfaceFormat
UploadImageDataToTexture(GLContext* gl,
unsigned char* aData,
+ const gfx::IntSize& aDataSize,
int32_t aStride,
SurfaceFormat aFormat,
const nsIntRegion& aDstRegion,
@@ -498,6 +516,10 @@ UploadImageDataToTexture(GLContext* gl,
// Upload each rect in the region to the texture
for (auto iter = aDstRegion.RectIter(); !iter.Done(); iter.Next()) {
const IntRect& rect = iter.Get();
+ if (!CheckUploadBounds(rect.Size(), aDataSize, rect.TopLeft())) {
+ return SurfaceFormat::UNKNOWN;
+ }
+
const unsigned char* rectData =
aData + DataOffset(rect.TopLeft(), aStride, aFormat);
@@ -534,10 +556,17 @@ UploadSurfaceToTexture(GLContext* gl,
int32_t stride = aSurface->Stride();
SurfaceFormat format = aSurface->GetFormat();
+ gfx::IntSize size = aSurface->GetSize();
+ if (!CheckUploadBounds(aSize, size, aSrcPoint)) {
+ return SurfaceFormat::UNKNOWN;
+ }
+
unsigned char* data = aSurface->GetData() +
DataOffset(aSrcPoint, stride, format);
+ size.width -= aSrcPoint.x;
+ size.height -= aSrcPoint.y;
- return UploadImageDataToTexture(gl, data, stride, format,
+ return UploadImageDataToTexture(gl, data, size, stride, format,
aDstRegion, aTexture, aSize,
aOutUploadSize, aNeedInit,
aTextureUnit, aTextureTarget);
diff --git a/gfx/gl/GLUploadHelpers.h b/gfx/gl/GLUploadHelpers.h
index 866d44adb..f732d2b38 100644
--- a/gfx/gl/GLUploadHelpers.h
+++ b/gfx/gl/GLUploadHelpers.h
@@ -28,6 +28,7 @@ class GLContext;
* \param gl The GL Context to use.
* \param aData Start of image data of surface to upload.
* Corresponds to the first pixel of the texture.
+ * \param aDataSize The image data's size.
* \param aStride The image data's stride.
* \param aFormat The image data's format.
* \param aDstRegion Region of the texture to upload.
@@ -46,6 +47,7 @@ class GLContext;
gfx::SurfaceFormat
UploadImageDataToTexture(GLContext* gl,
unsigned char* aData,
+ const gfx::IntSize& aDataSize,
int32_t aStride,
gfx::SurfaceFormat aFormat,
const nsIntRegion& aDstRegion,
diff --git a/gfx/gl/GfxTexturesReporter.cpp b/gfx/gl/GfxTexturesReporter.cpp
index 8007fe6b1..d2ca70d27 100644
--- a/gfx/gl/GfxTexturesReporter.cpp
+++ b/gfx/gl/GfxTexturesReporter.cpp
@@ -9,10 +9,6 @@
#include "GfxTexturesReporter.h"
#include "gfxPrefs.h"
-#ifdef MOZ_CRASHREPORTER
-#include "nsExceptionHandler.h"
-#endif
-
using namespace mozilla;
using namespace mozilla::gl;
@@ -75,8 +71,4 @@ GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount)
}
}
}
-
-#ifdef MOZ_CRASHREPORTER
- CrashReporter::AnnotateTexturesSize(sAmount);
-#endif
}
diff --git a/gfx/gl/TextureImageEGL.cpp b/gfx/gl/TextureImageEGL.cpp
index 87a547c26..3bb2987d1 100644
--- a/gfx/gl/TextureImageEGL.cpp
+++ b/gfx/gl/TextureImageEGL.cpp
@@ -119,6 +119,10 @@ TextureImageEGL::DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion&
&uploadSize,
needInit,
aFrom);
+ if (mTextureFormat == SurfaceFormat::UNKNOWN) {
+ return false;
+ }
+
if (uploadSize > 0) {
UpdateUploadSize(uploadSize);
}
diff --git a/gfx/ipc/GPUChild.cpp b/gfx/ipc/GPUChild.cpp
index 72328ac0b..3c2797683 100644
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -121,9 +121,6 @@ GPUChild::RecvGraphicsError(const nsCString& aError)
bool
GPUChild::RecvInitCrashReporter(Shmem&& aShmem)
{
-#ifdef MOZ_CRASHREPORTER
- mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_GPU, aShmem);
-#endif
return true;
}
@@ -163,12 +160,6 @@ void
GPUChild::ActorDestroy(ActorDestroyReason aWhy)
{
if (aWhy == AbnormalShutdown) {
-#ifdef MOZ_CRASHREPORTER
- if (mCrashReporter) {
- mCrashReporter->GenerateCrashReport(OtherPid());
- mCrashReporter = nullptr;
- }
-#endif
Telemetry::Accumulate(Telemetry::SUBPROCESS_ABNORMAL_ABORT,
nsDependentCString(XRE_ChildProcessTypeToString(GeckoProcessType_GPU), 1));
}
diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp
index d63e17e2f..896c7b36b 100644
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -82,11 +82,6 @@ GPUParent::Init(base::ProcessId aParentPid,
nsDebugImpl::SetMultiprocessMode("GPU");
-#ifdef MOZ_CRASHREPORTER
- // Init crash reporter support.
- CrashReporterClient::InitSingleton(this);
-#endif
-
// Ensure gfxPrefs are initialized.
gfxPrefs::GetSingleton();
gfxConfig::Init();
@@ -380,9 +375,6 @@ GPUParent::ActorDestroy(ActorDestroyReason aWhy)
gfxVars::Shutdown();
gfxConfig::Shutdown();
gfxPrefs::DestroySingleton();
-#ifdef MOZ_CRASHREPORTER
- CrashReporterClient::DestroySingleton();
-#endif
XRE_ShutdownChildProcess();
}
diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp
index 8072e0401..5e4019e86 100644
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -438,12 +438,15 @@ static void
CopyPlane(uint8_t *aDst, const uint8_t *aSrc,
const gfx::IntSize &aSize, int32_t aStride, int32_t aSkip)
{
+ int32_t height = aSize.height;
+ int32_t width = aSize.width;
+
+ MOZ_RELEASE_ASSERT(width <= aStride);
+
if (!aSkip) {
// Fast path: planar input.
- memcpy(aDst, aSrc, aSize.height * aStride);
+ memcpy(aDst, aSrc, height * aStride);
} else {
- int32_t height = aSize.height;
- int32_t width = aSize.width;
for (int y = 0; y < height; ++y) {
const uint8_t *src = aSrc;
uint8_t *dst = aDst;
@@ -461,13 +464,11 @@ CopyPlane(uint8_t *aDst, const uint8_t *aSrc,
bool
RecyclingPlanarYCbCrImage::CopyData(const Data& aData)
{
- mData = aData;
-
// update buffer size
// Use uint32_t throughout to match AllocateBuffer's param and mBufferSize
const auto checkedSize =
- CheckedInt<uint32_t>(mData.mCbCrStride) * mData.mCbCrSize.height * 2 +
- CheckedInt<uint32_t>(mData.mYStride) * mData.mYSize.height;
+ CheckedInt<uint32_t>(aData.mCbCrStride) * aData.mCbCrSize.height * 2 +
+ CheckedInt<uint32_t>(aData.mYStride) * aData.mYSize.height;
if (!checkedSize.isValid())
return false;
@@ -482,16 +483,18 @@ RecyclingPlanarYCbCrImage::CopyData(const Data& aData)
// update buffer size
mBufferSize = size;
+ mData = aData;
mData.mYChannel = mBuffer.get();
mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
+ mData.mYSkip = mData.mCbSkip = mData.mCrSkip = 0;
CopyPlane(mData.mYChannel, aData.mYChannel,
- mData.mYSize, mData.mYStride, mData.mYSkip);
+ aData.mYSize, aData.mYStride, aData.mYSkip);
CopyPlane(mData.mCbChannel, aData.mCbChannel,
- mData.mCbCrSize, mData.mCbCrStride, mData.mCbSkip);
+ aData.mCbCrSize, aData.mCbCrStride, aData.mCbSkip);
CopyPlane(mData.mCrChannel, aData.mCrChannel,
- mData.mCbCrSize, mData.mCbCrStride, mData.mCrSkip);
+ aData.mCbCrSize, aData.mCbCrStride, aData.mCrSkip);
mSize = aData.mPicSize;
mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp
index 8c5b8c7b7..c93037384 100644
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -100,15 +100,9 @@ TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
TextureFlags aFlags,
uint64_t aSerial)
{
- if (aSharedData.type() == SurfaceDescriptor::TSurfaceDescriptorBuffer &&
- aSharedData.get_SurfaceDescriptorBuffer().data().type() == MemoryOrShmem::Tuintptr_t &&
- !aAllocator->IsSameProcess())
- {
- NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
- return nullptr;
- }
TextureParent* actor = new TextureParent(aAllocator, aSerial);
if (!actor->Init(aSharedData, aLayersBackend, aFlags)) {
+ actor->ActorDestroy(ipc::IProtocol::ActorDestroyReason::FailedConstructor);
delete actor;
return nullptr;
}
@@ -210,6 +204,11 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
#ifdef MOZ_X11
case SurfaceDescriptor::TSurfaceDescriptorX11: {
+ if (!aDeallocator->IsSameProcess()) {
+ NS_ERROR("A client process is trying to peek at our address space using a X11Texture!");
+ return nullptr;
+ }
+
const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11();
return MakeAndAddRef<X11TextureHost>(aFlags, desc);
}
@@ -244,13 +243,49 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
const MemoryOrShmem& data = bufferDesc.data();
switch (data.type()) {
case MemoryOrShmem::TShmem: {
- result = new ShmemTextureHost(data.get_Shmem(),
- bufferDesc.desc(),
- aDeallocator,
- aFlags);
+ const ipc::Shmem& shmem = data.get_Shmem();
+ const BufferDescriptor& desc = bufferDesc.desc();
+ if (!shmem.IsReadable()) {
+ // We failed to map the shmem so we can't verify its size. This
+ // should not be a fatal error, so just create the texture with
+ // nothing backing it.
+ result = new ShmemTextureHost(shmem, desc, aDeallocator, aFlags);
+ break;
+ }
+
+ size_t bufSize = shmem.Size<char>();
+ size_t reqSize = SIZE_MAX;
+ switch (desc.type()) {
+ case BufferDescriptor::TYCbCrDescriptor: {
+ const YCbCrDescriptor& ycbcr = desc.get_YCbCrDescriptor();
+ reqSize =
+ ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.cbCrSize());
+ break;
+ }
+ case BufferDescriptor::TRGBDescriptor: {
+ const RGBDescriptor& rgb = desc.get_RGBDescriptor();
+ reqSize = ImageDataSerializer::ComputeRGBBufferSize(rgb.size(), rgb.format());
+ break;
+ }
+ default:
+ gfxCriticalError() << "Bad buffer host descriptor " << (int)desc.type();
+ MOZ_CRASH("GFX: Bad descriptor");
+ }
+
+ if (bufSize < reqSize) {
+ NS_ERROR("A client process gave a shmem too small to fit for its descriptor!");
+ return nullptr;
+ }
+
+ result = new ShmemTextureHost(shmem, desc, aDeallocator, aFlags);
break;
}
case MemoryOrShmem::Tuintptr_t: {
+ if (!aDeallocator->IsSameProcess()) {
+ NS_ERROR("A client process is trying to peek at our address space using a MemoryTexture!");
+ return nullptr;
+ }
+
result = new MemoryTextureHost(reinterpret_cast<uint8_t*>(data.get_uintptr_t()),
bufferDesc.desc(),
aFlags);
@@ -268,6 +303,11 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
}
#ifdef XP_WIN
case SurfaceDescriptor::TSurfaceDescriptorDIB: {
+ if (!aDeallocator->IsSameProcess()) {
+ NS_ERROR("A client process is trying to peek at our address space using a DIBTexture!");
+ return nullptr;
+ }
+
result = new DIBTextureHost(aFlags, aDesc);
break;
}
@@ -848,8 +888,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
mFirstSource = mCompositor->CreateDataTextureSource(mFlags|TextureFlags::RGB_FROM_YCBCR);
mFirstSource->SetOwner(this);
}
- mFirstSource->Update(surf, aRegion);
- return true;
+ return mFirstSource->Update(surf, aRegion);
}
RefPtr<DataTextureSource> srcY;
diff --git a/gfx/layers/composite/X11TextureHost.cpp b/gfx/layers/composite/X11TextureHost.cpp
index 7ca42426d..92b6f8e91 100644
--- a/gfx/layers/composite/X11TextureHost.cpp
+++ b/gfx/layers/composite/X11TextureHost.cpp
@@ -22,10 +22,9 @@ X11TextureHost::X11TextureHost(TextureFlags aFlags,
const SurfaceDescriptorX11& aDescriptor)
: TextureHost(aFlags)
{
- RefPtr<gfxXlibSurface> surface = aDescriptor.OpenForeign();
- mSurface = surface.get();
+ mSurface = aDescriptor.OpenForeign();
- if (!(aFlags & TextureFlags::DEALLOCATE_CLIENT)) {
+ if (mSurface && !(aFlags & TextureFlags::DEALLOCATE_CLIENT)) {
mSurface->TakePixmap();
}
}
@@ -33,7 +32,7 @@ X11TextureHost::X11TextureHost(TextureFlags aFlags,
bool
X11TextureHost::Lock()
{
- if (!mCompositor) {
+ if (!mCompositor || !mSurface) {
return false;
}
@@ -69,6 +68,9 @@ X11TextureHost::SetCompositor(Compositor* aCompositor)
SurfaceFormat
X11TextureHost::GetFormat() const
{
+ if (!mSurface) {
+ return SurfaceFormat::UNKNOWN;
+ }
gfxContentType type = mSurface->GetContentType();
#ifdef GL_PROVIDER_GLX
if (mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL) {
@@ -81,6 +83,9 @@ X11TextureHost::GetFormat() const
IntSize
X11TextureHost::GetSize() const
{
+ if (!mSurface) {
+ return IntSize();
+ }
return mSurface->GetSize();
}
diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp
index 8fbcfd234..954242585 100644
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -632,10 +632,6 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
- case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
- result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aFlags);
- break;
- }
case SurfaceDescriptor::TSurfaceDescriptorD3D10: {
result = new DXGITextureHostD3D11(aFlags,
aDesc.get_SurfaceDescriptorD3D10());
@@ -647,7 +643,7 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
break;
}
default: {
- NS_WARNING("Unsupported SurfaceDescriptor type");
+ MOZ_ASSERT_UNREACHABLE("Unsupported SurfaceDescriptor type");
}
}
return result.forget();
diff --git a/gfx/layers/opengl/CompositingRenderTargetOGL.cpp b/gfx/layers/opengl/CompositingRenderTargetOGL.cpp
index c05b8edfd..a1521c56d 100644
--- a/gfx/layers/opengl/CompositingRenderTargetOGL.cpp
+++ b/gfx/layers/opengl/CompositingRenderTargetOGL.cpp
@@ -60,7 +60,7 @@ CompositingRenderTargetOGL::BindRenderTarget()
msg.AppendPrintf("Framebuffer not complete -- CheckFramebufferStatus returned 0x%x, "
"GLContext=%p, IsOffscreen()=%d, mFBO=%d, aFBOTextureTarget=0x%x, "
"aRect.width=%d, aRect.height=%d",
- result, mGL, mGL->IsOffscreen(), mFBO, mInitParams.mFBOTextureTarget,
+ result, mGL.get(), mGL->IsOffscreen(), mFBO, mInitParams.mFBOTextureTarget,
mInitParams.mSize.width, mInitParams.mSize.height);
NS_WARNING(msg.get());
}
diff --git a/gfx/layers/opengl/CompositingRenderTargetOGL.h b/gfx/layers/opengl/CompositingRenderTargetOGL.h
index 501701d6f..071dc5cac 100644
--- a/gfx/layers/opengl/CompositingRenderTargetOGL.h
+++ b/gfx/layers/opengl/CompositingRenderTargetOGL.h
@@ -184,7 +184,7 @@ private:
* the target is always cleared at the end of a frame.
*/
RefPtr<CompositorOGL> mCompositor;
- GLContext* mGL;
+ RefPtr<GLContext> mGL;
GLuint mTextureHandle;
GLuint mFBO;
};
diff --git a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
index 05f8cf38f..9736618f7 100644
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -28,6 +28,8 @@ MacIOSurfaceTextureHostOGL::~MacIOSurfaceTextureHostOGL()
GLTextureSource*
MacIOSurfaceTextureHostOGL::CreateTextureSourceForPlane(size_t aPlane)
{
+ MOZ_ASSERT(mSurface);
+
GLuint textureHandle;
gl::GLContext* gl = mCompositor->gl();
gl->fGenTextures(1, &textureHandle);
@@ -84,11 +86,17 @@ MacIOSurfaceTextureHostOGL::SetCompositor(Compositor* aCompositor)
gfx::SurfaceFormat
MacIOSurfaceTextureHostOGL::GetFormat() const {
+ if (!mSurface) {
+ return gfx::SurfaceFormat::UNKNOWN;
+ }
return mSurface->GetFormat();
}
gfx::SurfaceFormat
MacIOSurfaceTextureHostOGL::GetReadFormat() const {
+ if (!mSurface) {
+ return gfx::SurfaceFormat::UNKNOWN;
+ }
return mSurface->GetReadFormat();
}
diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp
index 854160bc6..ec6ba9131 100644
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -25,10 +25,6 @@
#include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
#endif
-#ifdef GL_PROVIDER_GLX
-#include "mozilla/layers/X11TextureHost.h"
-#endif
-
using namespace mozilla::gl;
using namespace mozilla::gfx;
@@ -44,12 +40,6 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
{
RefPtr<TextureHost> result;
switch (aDesc.type()) {
- case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
- result = CreateBackendIndependentTextureHost(aDesc,
- aDeallocator, aFlags);
- break;
- }
-
#ifdef MOZ_WIDGET_ANDROID
case SurfaceDescriptor::TSurfaceTextureDescriptor: {
const SurfaceTextureDescriptor& desc = aDesc.get_SurfaceTextureDescriptor();
@@ -79,14 +69,6 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
}
#endif
-#ifdef GL_PROVIDER_GLX
- case SurfaceDescriptor::TSurfaceDescriptorX11: {
- const auto& desc = aDesc.get_SurfaceDescriptorX11();
- result = new X11TextureHost(aFlags, desc);
- break;
- }
-#endif
-
case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
result = new GLTextureHost(aFlags, desc.texture(),
@@ -96,7 +78,10 @@ CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
desc.hasAlpha());
break;
}
- default: return nullptr;
+ default: {
+ MOZ_ASSERT_UNREACHABLE("Unsupported SurfaceDescriptor type");
+ break;
+ }
}
return result.forget();
}
@@ -176,9 +161,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
}
}
- mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
-
- return true;
+ return mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
}
void
diff --git a/gfx/skia/skia/include/core/SkTypes.h b/gfx/skia/skia/include/core/SkTypes.h
index 0cef8a125..f45c3c2b7 100644
--- a/gfx/skia/skia/include/core/SkTypes.h
+++ b/gfx/skia/skia/include/core/SkTypes.h
@@ -109,6 +109,11 @@ SK_API extern void* sk_calloc(size_t size);
*/
SK_API extern void* sk_calloc_throw(size_t size);
+// Performs a safe multiply count * elemSize, checking for overflow
+SK_API extern void* sk_calloc_throw(size_t count, size_t elemSize);
+SK_API extern void* sk_malloc_throw(size_t count, size_t elemSize);
+SK_API extern void* sk_realloc_throw(void* buffer, size_t count, size_t elemSize);
+
// bzero is safer than memset, but we can't rely on it, so... sk_bzero()
static inline void sk_bzero(void* buffer, size_t size) {
// Please c.f. sk_careful_memcpy. It's undefined behavior to call memset(null, 0, 0).
@@ -295,6 +300,7 @@ template <typename D, typename S> D SkTo(S s) {
#define SK_MaxU32 0xFFFFFFFF
#define SK_MinU32 0
#define SK_NaN32 ((int) (1U << 31))
+#define SK_MaxSizeT SIZE_MAX
/** Returns true if the value can be represented with signed 16bits
*/
diff --git a/gfx/skia/skia/include/private/SkTDArray.h b/gfx/skia/skia/include/private/SkTDArray.h
index f71d35700..a46a05e9d 100644
--- a/gfx/skia/skia/include/private/SkTDArray.h
+++ b/gfx/skia/skia/include/private/SkTDArray.h
@@ -21,7 +21,7 @@ public:
fReserve = fCount = 0;
fArray = NULL;
if (count) {
- fArray = (T*)sk_malloc_throw(count * sizeof(T));
+ fArray = (T*)sk_malloc_throw(count, sizeof(T));
memcpy(fArray, src, sizeof(T) * count);
fReserve = fCount = count;
}
@@ -346,7 +346,7 @@ public:
void shrinkToFit() {
fReserve = fCount;
- fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T));
+ fArray = (T*)sk_realloc_throw(fArray, fReserve, sizeof(T));
}
private:
@@ -359,6 +359,7 @@ private:
* This is the same as calling setCount(count() + delta).
*/
void adjustCount(int delta) {
+ SkASSERT_RELEASE(fCount <= std::numeric_limits<int>::max() - delta);
this->setCount(fCount + delta);
}
@@ -372,9 +373,10 @@ private:
*/
void resizeStorageToAtLeast(int count) {
SkASSERT(count > fReserve);
+ SkASSERT_RELEASE(count <= std::numeric_limits<int>::max() - std::numeric_limits<int>::max() / 5 - 4);
fReserve = count + 4;
fReserve += fReserve / 4;
- fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T));
+ fArray = (T*)sk_realloc_throw(fArray, fReserve, sizeof(T));
}
};
diff --git a/gfx/skia/skia/src/core/SkMallocPixelRef.cpp b/gfx/skia/skia/src/core/SkMallocPixelRef.cpp
index fffc04484..8db704fa4 100644
--- a/gfx/skia/skia/src/core/SkMallocPixelRef.cpp
+++ b/gfx/skia/skia/src/core/SkMallocPixelRef.cpp
@@ -8,8 +8,21 @@
#include "SkMallocPixelRef.h"
#include "SkBitmap.h"
#include "SkReadBuffer.h"
+#include "SkSafeMath.h"
#include "SkWriteBuffer.h"
+void* sk_calloc_throw(size_t count, size_t elemSize) {
+ return sk_calloc_throw(SkSafeMath::Mul(count, elemSize));
+}
+
+void* sk_malloc_throw(size_t count, size_t elemSize) {
+ return sk_malloc_throw(SkSafeMath::Mul(count, elemSize));
+}
+
+void* sk_realloc_throw(void* buffer, size_t count, size_t elemSize) {
+ return sk_realloc_throw(buffer, SkSafeMath::Mul(count, elemSize));
+}
+
// assumes ptr was allocated via sk_malloc
static void sk_free_releaseproc(void* ptr, void*) {
sk_free(ptr);
diff --git a/gfx/skia/skia/src/core/SkMath.cpp b/gfx/skia/skia/src/core/SkMath.cpp
index 6eff790c8..84796c522 100644
--- a/gfx/skia/skia/src/core/SkMath.cpp
+++ b/gfx/skia/skia/src/core/SkMath.cpp
@@ -84,3 +84,18 @@ float SkScalarSinCos(float radians, float* cosValue) {
}
return sinValue;
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+size_t SkSafeMath::Add(size_t x, size_t y) {
+ SkSafeMath tmp;
+ size_t sum = tmp.add(x, y);
+ return tmp.ok() ? sum : SK_MaxSizeT;
+}
+
+size_t SkSafeMath::Mul(size_t x, size_t y) {
+ SkSafeMath tmp;
+ size_t prod = tmp.mul(x, y);
+ return tmp.ok() ? prod : SK_MaxSizeT;
+}
+
diff --git a/gfx/skia/skia/src/core/SkSafeMath.h b/gfx/skia/skia/src/core/SkSafeMath.h
new file mode 100644
index 000000000..0bc0fbfac
--- /dev/null
+++ b/gfx/skia/skia/src/core/SkSafeMath.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSafeMath_DEFINED
+#define SkSafeMath_DEFINED
+
+#include "SkTypes.h"
+
+// SkSafeMath always check that a series of operations do not overflow.
+// This must be correct for all platforms, because this is a check for safety at runtime.
+
+class SkSafeMath {
+public:
+ SkSafeMath() = default;
+
+ bool ok() const { return fOK; }
+ explicit operator bool() const { return fOK; }
+
+ size_t mul(size_t x, size_t y) {
+ return sizeof(size_t) == sizeof(uint64_t) ? mul64(x, y) : mul32(x, y);
+ }
+
+ size_t add(size_t x, size_t y) {
+ size_t result = x + y;
+ fOK &= result >= x;
+ return result;
+ }
+
+ /**
+ * Return a + b, unless this result is an overflow/underflow. In those cases, fOK will
+ * be set to false, and it is undefined what this returns.
+ */
+ int addInt(int a, int b) {
+ if (b < 0 && a < std::numeric_limits<int>::min() - b) {
+ fOK = false;
+ return a;
+ } else if (b > 0 && a > std::numeric_limits<int>::max() - b) {
+ fOK = false;
+ return a;
+ }
+ return a + b;
+ }
+
+ size_t alignUp(size_t x, size_t alignment) {
+ SkASSERT(alignment && !(alignment & (alignment - 1)));
+ return add(x, alignment - 1) & ~(alignment - 1);
+ }
+
+ template <typename T> T castTo(size_t value) {
+ if (!SkTFitsIn<T>(value)) {
+ fOK = false;
+ }
+ return static_cast<T>(value);
+ }
+
+ // These saturate to their results
+ static size_t Add(size_t x, size_t y);
+ static size_t Mul(size_t x, size_t y);
+ static size_t Align4(size_t x) {
+ SkSafeMath safe;
+ return safe.alignUp(x, 4);
+ }
+
+private:
+ uint32_t mul32(uint32_t x, uint32_t y) {
+ uint64_t bx = x;
+ uint64_t by = y;
+ uint64_t result = bx * by;
+ fOK &= result >> 32 == 0;
+ return result;
+ }
+
+ uint64_t mul64(uint64_t x, uint64_t y) {
+ if (x <= std::numeric_limits<uint64_t>::max() >> 32
+ && y <= std::numeric_limits<uint64_t>::max() >> 32) {
+ return x * y;
+ } else {
+ auto hi = [](uint64_t x) { return x >> 32; };
+ auto lo = [](uint64_t x) { return x & 0xFFFFFFFF; };
+
+ uint64_t lx_ly = lo(x) * lo(y);
+ uint64_t hx_ly = hi(x) * lo(y);
+ uint64_t lx_hy = lo(x) * hi(y);
+ uint64_t hx_hy = hi(x) * hi(y);
+ uint64_t result = 0;
+ result = this->add(lx_ly, (hx_ly << 32));
+ result = this->add(result, (lx_hy << 32));
+ fOK &= (hx_hy + (hx_ly >> 32) + (lx_hy >> 32)) == 0;
+
+ #if defined(SK_DEBUG) && defined(__clang__) && defined(__x86_64__)
+ auto double_check = (unsigned __int128)x * y;
+ SkASSERT(result == (double_check & 0xFFFFFFFFFFFFFFFF));
+ SkASSERT(!fOK || (double_check >> 64 == 0));
+ #endif
+
+ return result;
+ }
+ }
+ bool fOK = true;
+};
+
+#endif//SkSafeMath_DEFINED
diff --git a/gfx/src/DriverCrashGuard.cpp b/gfx/src/DriverCrashGuard.cpp
index 36d08dcf3..4754c26ad 100644
--- a/gfx/src/DriverCrashGuard.cpp
+++ b/gfx/src/DriverCrashGuard.cpp
@@ -7,9 +7,6 @@
#include "gfxPrefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
-#ifdef MOZ_CRASHREPORTER
-#include "nsExceptionHandler.h"
-#endif
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsXULAppAPI.h"
@@ -164,12 +161,6 @@ DriverCrashGuard::~DriverCrashGuard()
} else {
dom::ContentChild::GetSingleton()->SendEndDriverCrashGuard(uint32_t(mType));
}
-
-#ifdef MOZ_CRASHREPORTER
- // Remove the crash report annotation.
- CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
- NS_LITERAL_CSTRING(""));
-#endif
}
bool
@@ -208,16 +199,6 @@ DriverCrashGuard::ActivateGuard()
{
mGuardActivated = true;
-#ifdef MOZ_CRASHREPORTER
- // Anotate crash reports only if we're a real guard. Otherwise, we could
- // attribute a random parent process crash to a graphics problem in a child
- // process.
- if (mMode != Mode::Proxy) {
- CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
- NS_LITERAL_CSTRING("1"));
- }
-#endif
-
// If we're in the content process, the rest of the guarding is handled
// in the parent.
if (XRE_IsContentProcess()) {
diff --git a/gfx/src/gfxCrashReporterUtils.cpp b/gfx/src/gfxCrashReporterUtils.cpp
index 42647ccc6..757c15527 100644
--- a/gfx/src/gfxCrashReporterUtils.cpp
+++ b/gfx/src/gfxCrashReporterUtils.cpp
@@ -5,10 +5,6 @@
#include "gfxCrashReporterUtils.h"
-#if defined(MOZ_CRASHREPORTER)
-#define MOZ_GFXFEATUREREPORTER 1
-#endif
-
#ifdef MOZ_GFXFEATUREREPORTER
#include "gfxCrashReporterUtils.h"
#include <string.h> // for strcmp
diff --git a/gfx/tests/gtest/TestGfxPrefs.cpp b/gfx/tests/gtest/TestGfxPrefs.cpp
index 72b698ed6..4e3b6037e 100644
--- a/gfx/tests/gtest/TestGfxPrefs.cpp
+++ b/gfx/tests/gtest/TestGfxPrefs.cpp
@@ -80,27 +80,3 @@ TEST(GfxPrefs, Set) {
ASSERT_TRUE(gfxPrefs::APZMaxVelocity() == -1.0f);
}
-#ifdef MOZ_CRASHREPORTER
-// Randomly test the function we use in nsExceptionHandler.cpp here:
-extern bool SimpleNoCLibDtoA(double aValue, char* aBuffer, int aBufferLength);
-TEST(GfxPrefs, StringUtility)
-{
- char testBuffer[64];
- double testVal[] = {13.4,
- 3324243.42,
- 0.332424342,
- 864.0,
- 86400 * 100000000.0 * 10000000000.0 * 10000000000.0 * 100.0,
- 86400.0 * 366.0 * 100.0 + 14243.44332};
- for (size_t i=0; i<mozilla::ArrayLength(testVal); i++) {
- ASSERT_TRUE(SimpleNoCLibDtoA(testVal[i], testBuffer, sizeof(testBuffer)));
- ASSERT_TRUE(fabs(1.0 - atof(testBuffer)/testVal[i]) < 0.0001);
- }
-
- // We do not like negative numbers (random limitation)
- ASSERT_FALSE(SimpleNoCLibDtoA(-864.0, testBuffer, sizeof(testBuffer)));
-
- // It won't fit into 32:
- ASSERT_FALSE(SimpleNoCLibDtoA(testVal[4], testBuffer, sizeof(testBuffer)/2));
-}
-#endif
diff --git a/gfx/tests/gtest/TestLayers.h b/gfx/tests/gtest/TestLayers.h
index 18e351f77..fc6b750f1 100644
--- a/gfx/tests/gtest/TestLayers.h
+++ b/gfx/tests/gtest/TestLayers.h
@@ -8,6 +8,22 @@
#include "Layers.h"
#include "nsTArray.h"
+#include "mozilla/layers/ISurfaceAllocator.h"
+
+namespace mozilla {
+namespace layers {
+
+class TestSurfaceAllocator final : public ISurfaceAllocator
+{
+public:
+ TestSurfaceAllocator() {}
+ ~TestSurfaceAllocator() override {}
+
+ bool IsSameProcess() const override { return true; }
+};
+
+} // layers
+} // mozilla
/* Create layer tree from a simple layer tree description syntax.
* Each index is either the first letter of the layer type or
diff --git a/gfx/tests/gtest/TestTextures.cpp b/gfx/tests/gtest/TestTextures.cpp
index b4856ae6b..8f413cb3b 100644
--- a/gfx/tests/gtest/TestTextures.cpp
+++ b/gfx/tests/gtest/TestTextures.cpp
@@ -5,6 +5,7 @@
#include "gtest/gtest.h"
#include "gmock/gmock.h"
+#include "TestLayers.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Tools.h"
@@ -147,7 +148,8 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface)
ASSERT_NE(descriptor.type(), SurfaceDescriptor::Tnull_t);
// host deserialization
- RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, nullptr,
+ RefPtr<TestSurfaceAllocator> deallocator = new TestSurfaceAllocator();
+ RefPtr<TextureHost> host = CreateBackendIndependentTextureHost(descriptor, deallocator,
texture->GetFlags());
ASSERT_TRUE(host.get() != nullptr);
@@ -191,7 +193,8 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
ASSERT_EQ(ycbcrDesc.stereoMode(), ycbcrData.mStereoMode);
// host deserialization
- RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, nullptr,
+ RefPtr<TestSurfaceAllocator> deallocator = new TestSurfaceAllocator();
+ RefPtr<TextureHost> textureHost = CreateBackendIndependentTextureHost(descriptor, deallocator,
client->GetFlags());
RefPtr<BufferTextureHost> host = static_cast<BufferTextureHost*>(textureHost.get());
diff --git a/gfx/thebes/gfxFT2Utils.cpp b/gfx/thebes/gfxFT2Utils.cpp
index a544a8cb4..77e1c9632 100644
--- a/gfx/thebes/gfxFT2Utils.cpp
+++ b/gfx/thebes/gfxFT2Utils.cpp
@@ -10,6 +10,10 @@
#include FT_TRUETYPE_TABLES_H
#include <algorithm>
+#ifndef FT_FACE_FLAG_COLOR
+#define FT_FACE_FLAG_COLOR ( 1L << 14 )
+#endif
+
#ifdef HAVE_FONTCONFIG_FCFREETYPE_H
#include <fontconfig/fcfreetype.h>
#endif
@@ -53,7 +57,7 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
if (MOZ_UNLIKELY(!mFace)) {
// No face. This unfortunate situation might happen if the font
// file is (re)moved at the wrong time.
- const gfxFloat emHeight = mGfxFont->GetStyle()->size;
+ const gfxFloat emHeight = mGfxFont->GetAdjustedSize();
aMetrics->emHeight = emHeight;
aMetrics->maxAscent = aMetrics->emAscent = 0.8 * emHeight;
aMetrics->maxDescent = aMetrics->emDescent = 0.2 * emHeight;
@@ -80,6 +84,11 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
const FT_Size_Metrics& ftMetrics = mFace->size->metrics;
+ aMetrics->maxAscent = FLOAT_FROM_26_6(ftMetrics.ascender);
+ aMetrics->maxDescent = -FLOAT_FROM_26_6(ftMetrics.descender);
+ aMetrics->maxAdvance = FLOAT_FROM_26_6(ftMetrics.max_advance);
+ gfxFloat lineHeight = FLOAT_FROM_26_6(ftMetrics.height);
+
gfxFloat emHeight;
// Scale for vertical design metric conversion: pixels per design unit.
// If this remains at 0.0, we can't use metrics from OS/2 etc.
@@ -103,6 +112,19 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
const TT_Header* head =
static_cast<TT_Header*>(FT_Get_Sfnt_Table(mFace, ft_sfnt_head));
if (head) {
+ // Even if the font is not explicitly scalable, if the face has
+ // color bitmaps, it should be treated as scalable and scaled to
+ // the desired size. Metrics based on y_ppem need to be rescaled
+ // for the adjusted size. This makes metrics agree with the
+ // scales we pass to Cairo for Fontconfig fonts.
+ if (mFace->face_flags & FT_FACE_FLAG_COLOR) {
+ emHeight = mGfxFont->GetAdjustedSize();
+ gfxFloat adjustScale = emHeight / ftMetrics.y_ppem;
+ aMetrics->maxAscent *= adjustScale;
+ aMetrics->maxDescent *= adjustScale;
+ aMetrics->maxAdvance *= adjustScale;
+ lineHeight *= adjustScale;
+ }
gfxFloat emUnit = head->Units_Per_EM;
yScale = emHeight / emUnit;
}
@@ -111,11 +133,6 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
TT_OS2 *os2 =
static_cast<TT_OS2*>(FT_Get_Sfnt_Table(mFace, ft_sfnt_os2));
- aMetrics->maxAscent = FLOAT_FROM_26_6(ftMetrics.ascender);
- aMetrics->maxDescent = -FLOAT_FROM_26_6(ftMetrics.descender);
- aMetrics->maxAdvance = FLOAT_FROM_26_6(ftMetrics.max_advance);
-
- gfxFloat lineHeight;
if (os2 && os2->sTypoAscender && yScale > 0.0) {
aMetrics->emAscent = os2->sTypoAscender * yScale;
aMetrics->emDescent = -os2->sTypoDescender * yScale;
@@ -142,7 +159,6 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Metrics* aMetrics,
} else {
aMetrics->emAscent = aMetrics->maxAscent;
aMetrics->emDescent = aMetrics->maxDescent;
- lineHeight = FLOAT_FROM_26_6(ftMetrics.height);
}
cairo_text_extents_t extents;
diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp
index 601e7a90c..75e8fb76a 100644
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -811,6 +811,15 @@ ChooseFontSize(gfxFontconfigFontEntry* aEntry,
bestSize = size;
}
}
+ // If the font has bitmaps but wants to be scaled, then let it scale.
+ if (bestSize >= 0.0) {
+ FcBool scalable;
+ if (FcPatternGetBool(aEntry->GetPattern(),
+ FC_SCALABLE, 0, &scalable) == FcResultMatch &&
+ scalable) {
+ return requestedSize;
+ }
+ }
return bestSize;
}
@@ -946,10 +955,16 @@ gfxFontconfigFontFamily::AddFontPattern(FcPattern* aFontPattern)
NS_ASSERTION(!mHasStyles,
"font patterns must not be added to already enumerated families");
- FcBool scalable;
- if (FcPatternGetBool(aFontPattern, FC_SCALABLE, 0, &scalable) != FcResultMatch ||
- !scalable) {
+ FcBool outline;
+ if (FcPatternGetBool(aFontPattern, FC_OUTLINE, 0, &outline) != FcResultMatch ||
+ !outline) {
mHasNonScalableFaces = true;
+
+ FcBool scalable;
+ if (FcPatternGetBool(aFontPattern, FC_SCALABLE, 0, &scalable) == FcResultMatch &&
+ scalable) {
+ mForceScalable = true;
+ }
}
nsCountedRef<FcPattern> pattern(aFontPattern);
@@ -961,7 +976,9 @@ static const double kRejectDistance = 10000.0;
// Calculate a distance score representing the size disparity between the
// requested style's size and the font entry's size.
static double
-SizeDistance(gfxFontconfigFontEntry* aEntry, const gfxFontStyle& aStyle)
+SizeDistance(gfxFontconfigFontEntry* aEntry,
+ const gfxFontStyle& aStyle,
+ bool aForceScalable)
{
double requestedSize = SizeForStyle(aEntry, aStyle);
double bestDist = -1.0;
@@ -978,7 +995,7 @@ SizeDistance(gfxFontconfigFontEntry* aEntry, const gfxFontStyle& aStyle)
if (bestDist < 0.0) {
// No size means scalable
return -1.0;
- } else if (5.0 * bestDist < requestedSize) {
+ } else if (aForceScalable || 5.0 * bestDist < requestedSize) {
// fontconfig prefers a matching family or lang to pixelsize of bitmap
// fonts. CSS suggests a tolerance of 20% on pixelsize.
return bestDist;
@@ -1012,7 +1029,7 @@ gfxFontconfigFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle,
for (size_t i = 0; i < aFontEntryList.Length(); i++) {
gfxFontconfigFontEntry* entry =
static_cast<gfxFontconfigFontEntry*>(aFontEntryList[i]);
- double dist = SizeDistance(entry, aFontStyle);
+ double dist = SizeDistance(entry, aFontStyle, mForceScalable);
// If the entry is scalable or has a style that does not match
// the group of unscalable fonts, then start a new group.
if (dist < 0.0 ||
diff --git a/gfx/thebes/gfxFcPlatformFontList.h b/gfx/thebes/gfxFcPlatformFontList.h
index 1bc35021e..aa8f614a9 100644
--- a/gfx/thebes/gfxFcPlatformFontList.h
+++ b/gfx/thebes/gfxFcPlatformFontList.h
@@ -175,7 +175,8 @@ public:
explicit gfxFontconfigFontFamily(const nsAString& aName) :
gfxFontFamily(aName),
mContainsAppFonts(false),
- mHasNonScalableFaces(false)
+ mHasNonScalableFaces(false),
+ mForceScalable(false)
{ }
void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) override;
@@ -201,6 +202,7 @@ protected:
bool mContainsAppFonts;
bool mHasNonScalableFaces;
+ bool mForceScalable;
};
class gfxFontconfigFont : public gfxFontconfigFontBase {
diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp
index 2e4ec990f..a468592fe 100644
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -71,9 +71,6 @@
#include "nsIScreenManager.h"
#include "FrameMetrics.h"
#include "MainThreadUtils.h"
-#ifdef MOZ_CRASHREPORTER
-#include "nsExceptionHandler.h"
-#endif
#include "nsWeakReference.h"
@@ -293,12 +290,7 @@ void CrashStatsLogForwarder::UpdateCrashReport()
message << logAnnotation << Get<0>(*it) << "]" << Get<1>(*it) << " (t=" << Get<2>(*it) << ") ";
}
-#ifdef MOZ_CRASHREPORTER
- nsCString reportString(message.str().c_str());
- nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString);
-#else
nsresult annotated = NS_ERROR_NOT_IMPLEMENTED;
-#endif
if (annotated != NS_OK) {
printf("Crash Annotation %s: %s",
mCrashCriticalKey.get(), message.str().c_str());
diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp
index 9d7f512f2..1fb3bc4fd 100644
--- a/gfx/thebes/gfxPlatformGtk.cpp
+++ b/gfx/thebes/gfxPlatformGtk.cpp
@@ -227,10 +227,10 @@ gfxPlatformGtk::UpdateFontList()
// out a more general list
static const char kFontDejaVuSans[] = "DejaVu Sans";
static const char kFontDejaVuSerif[] = "DejaVu Serif";
-static const char kFontEmojiOneMozilla[] = "EmojiOne Mozilla";
static const char kFontFreeSans[] = "FreeSans";
static const char kFontFreeSerif[] = "FreeSerif";
static const char kFontTakaoPGothic[] = "TakaoPGothic";
+static const char kFontTwemojiMozilla[] = "Twemoji Mozilla";
static const char kFontDroidSansFallback[] = "Droid Sans Fallback";
static const char kFontWenQuanYiMicroHei[] = "WenQuanYi Micro Hei";
static const char kFontNanumGothic[] = "NanumGothic";
@@ -242,7 +242,7 @@ gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
{
if (aNextCh == 0xfe0fu) {
// if char is followed by VS16, try for a color emoji glyph
- aFontList.AppendElement(kFontEmojiOneMozilla);
+ aFontList.AppendElement(kFontTwemojiMozilla);
}
aFontList.AppendElement(kFontDejaVuSerif);
@@ -254,7 +254,7 @@ gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
uint32_t p = aCh >> 16;
if (p == 1) { // try color emoji font, unless VS15 (text style) present
if (aNextCh != 0xfe0fu && aNextCh != 0xfe0eu) {
- aFontList.AppendElement(kFontEmojiOneMozilla);
+ aFontList.AppendElement(kFontTwemojiMozilla);
}
}
}
diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp
index 84199170b..af4d932a9 100755
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -634,7 +634,6 @@ static const char kFontCambriaMath[] = "Cambria Math";
static const char kFontEbrima[] = "Ebrima";
static const char kFontEstrangeloEdessa[] = "Estrangelo Edessa";
static const char kFontEuphemia[] = "Euphemia";
-static const char kFontEmojiOneMozilla[] = "EmojiOne Mozilla";
static const char kFontGabriola[] = "Gabriola";
static const char kFontJavaneseText[] = "Javanese Text";
static const char kFontKhmerUI[] = "Khmer UI";
@@ -661,6 +660,7 @@ static const char kFontSegoeUIEmoji[] = "Segoe UI Emoji";
static const char kFontSegoeUISymbol[] = "Segoe UI Symbol";
static const char kFontSylfaen[] = "Sylfaen";
static const char kFontTraditionalArabic[] = "Traditional Arabic";
+static const char kFontTwemojiMozilla[] = "Twemoji Mozilla";
static const char kFontUtsaah[] = "Utsaah";
static const char kFontYuGothic[] = "Yu Gothic";
@@ -671,7 +671,7 @@ gfxWindowsPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
{
if (aNextCh == 0xfe0fu) {
aFontList.AppendElement(kFontSegoeUIEmoji);
- aFontList.AppendElement(kFontEmojiOneMozilla);
+ aFontList.AppendElement(kFontTwemojiMozilla);
}
// Arial is used as the default fallback for system fallback
@@ -683,11 +683,11 @@ gfxWindowsPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
if (aNextCh == 0xfe0eu) {
aFontList.AppendElement(kFontSegoeUISymbol);
aFontList.AppendElement(kFontSegoeUIEmoji);
- aFontList.AppendElement(kFontEmojiOneMozilla);
+ aFontList.AppendElement(kFontTwemojiMozilla);
} else {
if (aNextCh != 0xfe0fu) {
aFontList.AppendElement(kFontSegoeUIEmoji);
- aFontList.AppendElement(kFontEmojiOneMozilla);
+ aFontList.AppendElement(kFontTwemojiMozilla);
}
aFontList.AppendElement(kFontSegoeUISymbol);
}