diff options
author | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-07-06 15:53:52 +0200 |
---|---|---|
committer | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-07-06 15:53:52 +0200 |
commit | 941e54654eabed0a3568f7fefe424a45aa02eddb (patch) | |
tree | 49aa02b174c428962d99142d8061267bfcd79e69 /gfx | |
parent | ad9ee72dcd7981bc47b3844a224d69fadfdfd8ef (diff) | |
parent | 0daa12376295d5d796256a116eb2a348a3a9273f (diff) | |
download | UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.gz UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.lz UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.xz UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.zip |
Merge branch 'master' of https://github.com/MoonchildProductions/UXP into _testBranch_test_1
Diffstat (limited to 'gfx')
69 files changed, 511 insertions, 559 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/2d/ssse3-scaler.c b/gfx/2d/ssse3-scaler.c index 345844b84..745f58f6f 100644 --- a/gfx/2d/ssse3-scaler.c +++ b/gfx/2d/ssse3-scaler.c @@ -37,6 +37,7 @@ #include <tmmintrin.h> #include <stdint.h> #include <assert.h> +#include "ssse3-scaler.h" typedef int32_t pixman_fixed_16_16_t; typedef pixman_fixed_16_16_t pixman_fixed_t; @@ -44,6 +45,8 @@ typedef pixman_fixed_16_16_t pixman_fixed_t; #define pixman_fixed_to_int(f) ((int) ((f) >> 16)) #define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16)) #define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0)) +#define PIXMAN_FIXED_INT_MAX 32767 +#define PIXMAN_FIXED_INT_MIN -32768 typedef struct pixman_vector pixman_vector_t; typedef int pixman_bool_t; @@ -463,6 +466,12 @@ ssse3_bilinear_cover_iter_init (pixman_iter_t *iter) bilinear_info_t *info; pixman_vector_t v; + if (iter->x > PIXMAN_FIXED_INT_MAX || + iter->x < PIXMAN_FIXED_INT_MIN || + iter->y > PIXMAN_FIXED_INT_MAX || + iter->y < PIXMAN_FIXED_INT_MIN) + goto fail; + /* Reference point is the center of the pixel */ v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2; v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2; @@ -505,7 +514,7 @@ fail: /* scale the src from src_width/height to dest_width/height drawn * into the rectangle x,y width,height * src_stride and dst_stride are 4 byte units */ -void ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride, +bool ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride, uint32_t *dest, int dest_width, int dest_height, int dest_stride, int x, int y, @@ -551,6 +560,10 @@ void ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stri iter.data = NULL; ssse3_bilinear_cover_iter_init(&iter); + + if (!iter.fini) + return false; + if (iter.data) { for (int iy = 0; iy < height; iy++) { ssse3_fetch_bilinear_cover(&iter, NULL); @@ -558,4 +571,5 @@ void ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stri } ssse3_bilinear_cover_iter_fini(&iter); } + return true; } diff --git a/gfx/2d/ssse3-scaler.h b/gfx/2d/ssse3-scaler.h index b3b53ed64..ea8d8a066 100644 --- a/gfx/2d/ssse3-scaler.h +++ b/gfx/2d/ssse3-scaler.h @@ -6,10 +6,12 @@ #ifndef MOZILLA_GFX_2D_SSSE3_SCALER_H_ #define MOZILLA_GFX_2D_SSSE3_SCALER_H_ +#include <stdbool.h> + #ifdef __cplusplus extern "C" { #endif -void ssse3_scale_data(uint32_t *src, int src_width, int src_height, +bool ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride, uint32_t *dest, int dest_width, int dest_height, int dest_rowstride, diff --git a/gfx/cairo/cairo/src/cairo-mutex-impl-private.h b/gfx/cairo/cairo/src/cairo-mutex-impl-private.h index 25223f3ea..6c67f6ebb 100644 --- a/gfx/cairo/cairo/src/cairo-mutex-impl-private.h +++ b/gfx/cairo/cairo/src/cairo-mutex-impl-private.h @@ -36,6 +36,7 @@ * Carl D. Worth <cworth@cworth.org> * Mathias Hasselmann <mathias.hasselmann@gmx.de> * Behdad Esfahbod <behdad@behdad.org> + * Mark Straver <moonchild@palemoon.org> */ #ifndef CAIRO_MUTEX_IMPL_PRIVATE_H @@ -178,24 +179,24 @@ #elif defined(_WIN32) /******************************************************/ #define WIN32_LEAN_AND_MEAN -/* We require Windows 2000 features such as ETO_PDY */ -#if !defined(WINVER) || (WINVER < 0x0500) -# define WINVER 0x0500 +/* We require Windows 7 features */ +#if !defined(WINVER) || (WINVER < 0x0601) +# define WINVER 0x0601 #endif -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) -# define _WIN32_WINNT 0x0500 +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0601) +# define _WIN32_WINNT 0x0601 #endif # include <windows.h> - typedef CRITICAL_SECTION cairo_mutex_impl_t; + typedef SRWLOCK cairo_mutex_impl_t; # define CAIRO_MUTEX_IMPL_WIN32 1 -# define CAIRO_MUTEX_IMPL_LOCK(mutex) EnterCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) LeaveCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_INIT(mutex) InitializeCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_FINI(mutex) DeleteCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 } +# define CAIRO_MUTEX_IMPL_LOCK(mutex) AcquireSRWLockExclusive (&(mutex)) +# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) ReleaseSRWLockExclusive (&(mutex)) +# define CAIRO_MUTEX_IMPL_INIT(mutex) InitializeSRWLock (&(mutex)) +# define CAIRO_MUTEX_IMPL_FINI(mutex) CAIRO_MUTEX_IMPL_NOOP +# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER SRWLOCK_INIT #elif defined __OS2__ /******************************************************/ diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 23090ef98..33315413f 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -19,7 +19,6 @@ #include "GLReadTexImageHelper.h" #include "GLScreenBuffer.h" -#include "gfxCrashReporterUtils.h" #include "gfxEnv.h" #include "gfxUtils.h" #include "GLContextProvider.h" @@ -523,8 +522,6 @@ GLContext::InitWithPrefix(const char* prefix, bool trygl) MOZ_RELEASE_ASSERT(!mSymbols.fBindFramebuffer, "GFX: InitWithPrefix should only be called once."); - ScopedGfxFeatureReporter reporter("GL Context"); - if (!InitWithPrefixImpl(prefix, trygl)) { // If initialization fails, zero the symbols to avoid hard-to-understand bugs. mSymbols.Zero(); @@ -532,7 +529,6 @@ GLContext::InitWithPrefix(const char* prefix, bool trygl) return false; } - reporter.SetSuccessful(); return true; } diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index ca972e0f3..098662200 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -23,7 +23,7 @@ #ifdef ANDROID #include <android/log.h> - #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args) + #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Android" , ## args) #endif #define GLES2_LIB "libGLESv2.so" @@ -79,7 +79,6 @@ #endif #include "gfxASurface.h" -#include "gfxCrashReporterUtils.h" #include "gfxFailure.h" #include "gfxPlatform.h" #include "gfxUtils.h" diff --git a/gfx/gl/GLContextProviderGLX.cpp b/gfx/gl/GLContextProviderGLX.cpp index 9a1157f33..d804f95af 100644 --- a/gfx/gl/GLContextProviderGLX.cpp +++ b/gfx/gl/GLContextProviderGLX.cpp @@ -35,8 +35,6 @@ #include "GLScreenBuffer.h" #include "gfxPrefs.h" -#include "gfxCrashReporterUtils.h" - #ifdef MOZ_WIDGET_GTK #include "gfxPlatformGtk.h" #endif @@ -93,13 +91,11 @@ GLXLibrary::EnsureInitialized() libGLfilename = "libGL.so.1"; #endif - ScopedGfxFeatureReporter reporter(libGLfilename, forceFeatureReport); mOGLLibrary = PR_LoadLibrary(libGLfilename); if (!mOGLLibrary) { NS_WARNING("Couldn't load OpenGL shared library."); return false; } - reporter.SetSuccessful(); } if (gfxEnv::GlxDebug()) { diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp index a1373f78f..c9c3f0a54 100644 --- a/gfx/gl/GLContextProviderWGL.cpp +++ b/gfx/gl/GLContextProviderWGL.cpp @@ -11,8 +11,6 @@ #include "gfxPlatform.h" #include "gfxWindowsSurface.h" -#include "gfxCrashReporterUtils.h" - #include "prenv.h" #include "mozilla/Preferences.h" @@ -99,8 +97,6 @@ WGLLibrary::EnsureInitialized() if (mInitialized) return true; - mozilla::ScopedGfxFeatureReporter reporter("WGL"); - std::string libGLFilename = "Opengl32.dll"; // SU_SPIES_DIRECTORY is for AMD CodeXL/gDEBugger if (PR_GetEnv("SU_SPIES_DIRECTORY")) { @@ -268,7 +264,6 @@ WGLLibrary::EnsureInitialized() mInitialized = true; - reporter.SetSuccessful(); return true; } diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp index 130bce119..3d8da3085 100644 --- a/gfx/gl/GLLibraryEGL.cpp +++ b/gfx/gl/GLLibraryEGL.cpp @@ -6,7 +6,6 @@ #include "angle/Platform.h" #include "gfxConfig.h" -#include "gfxCrashReporterUtils.h" #include "gfxUtils.h" #include "mozilla/Preferences.h" #include "mozilla/Assertions.h" @@ -33,9 +32,6 @@ namespace gl { StaticMutex GLLibraryEGL::sMutex; GLLibraryEGL sEGLLibrary; -#ifdef MOZ_B2G -MOZ_THREAD_LOCAL(EGLContext) GLLibraryEGL::sCurrentContext; -#endif // should match the order of EGLExtensions, and be null-terminated. static const char* sEGLExtensionNames[] = { @@ -303,13 +299,6 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId return true; } - mozilla::ScopedGfxFeatureReporter reporter("EGL"); - -#ifdef MOZ_B2G - if (!sCurrentContext.init()) - MOZ_CRASH("GFX: Tls init failed"); -#endif - #ifdef XP_WIN if (!mEGLLibrary) { // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and @@ -632,7 +621,6 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId } mInitialized = true; - reporter.SetSuccessful(); return true; } diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h index fa6ea748b..88fce067e 100644 --- a/gfx/gl/GLLibraryEGL.h +++ b/gfx/gl/GLLibraryEGL.h @@ -656,32 +656,12 @@ public: static void AfterGLCall(const char* glFunction); #endif -#ifdef MOZ_B2G - EGLContext CachedCurrentContext() { - return sCurrentContext.get(); - } - void UnsetCachedCurrentContext() { - sCurrentContext.set(nullptr); - } - void SetCachedCurrentContext(EGLContext aCtx) { - sCurrentContext.set(aCtx); - } - bool CachedCurrentContextMatches() { - return sCurrentContext.get() == fGetCurrentContext(); - } - -private: - static MOZ_THREAD_LOCAL(EGLContext) sCurrentContext; -public: - -#else EGLContext CachedCurrentContext() { return nullptr; } void UnsetCachedCurrentContext() {} void SetCachedCurrentContext(EGLContext aCtx) { } bool CachedCurrentContextMatches() { return true; } -#endif private: bool mInitialized; 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/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 3c2797683..a075716e3 100644 --- a/gfx/ipc/GPUChild.cpp +++ b/gfx/ipc/GPUChild.cpp @@ -14,7 +14,6 @@ #if defined(XP_WIN) # include "mozilla/gfx/DeviceManagerDx.h" #endif -#include "mozilla/ipc/CrashReporterHost.h" namespace mozilla { namespace gfx { @@ -119,12 +118,6 @@ GPUChild::RecvGraphicsError(const nsCString& aError) } bool -GPUChild::RecvInitCrashReporter(Shmem&& aShmem) -{ - return true; -} - -bool GPUChild::RecvNotifyUiObservers(const nsCString& aTopic) { nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService(); diff --git a/gfx/ipc/GPUChild.h b/gfx/ipc/GPUChild.h index c0f7d076f..888884ddf 100644 --- a/gfx/ipc/GPUChild.h +++ b/gfx/ipc/GPUChild.h @@ -12,9 +12,6 @@ #include "mozilla/gfx/gfxVarReceiver.h" namespace mozilla { -namespace ipc { -class CrashReporterHost; -} // namespace namespace gfx { class GPUProcessHost; @@ -37,7 +34,6 @@ public: // PGPUChild overrides. bool RecvInitComplete(const GPUDeviceData& aData) override; bool RecvReportCheckerboard(const uint32_t& aSeverity, const nsCString& aLog) override; - bool RecvInitCrashReporter(Shmem&& shmem) override; bool RecvAccumulateChildHistogram(InfallibleTArray<Accumulation>&& aAccumulations) override; bool RecvAccumulateChildKeyedHistogram(InfallibleTArray<KeyedAccumulation>&& aAccumulations) override; void ActorDestroy(ActorDestroyReason aWhy) override; @@ -49,7 +45,6 @@ public: private: GPUProcessHost* mHost; - UniquePtr<ipc::CrashReporterHost> mCrashReporter; bool mGPUReady; }; diff --git a/gfx/ipc/GPUParent.cpp b/gfx/ipc/GPUParent.cpp index 896c7b36b..b693f4728 100644 --- a/gfx/ipc/GPUParent.cpp +++ b/gfx/ipc/GPUParent.cpp @@ -14,7 +14,6 @@ #include "mozilla/Assertions.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/gfxVars.h" -#include "mozilla/ipc/CrashReporterClient.h" #include "mozilla/ipc/ProcessChild.h" #include "mozilla/layers/APZThreadUtils.h" #include "mozilla/layers/APZCTreeManager.h" diff --git a/gfx/ipc/PGPU.ipdl b/gfx/ipc/PGPU.ipdl index c442335c9..d36c51394 100644 --- a/gfx/ipc/PGPU.ipdl +++ b/gfx/ipc/PGPU.ipdl @@ -89,8 +89,6 @@ child: // Graphics errors, analogous to PContent::GraphicsError async GraphicsError(nsCString aError); - async InitCrashReporter(Shmem shmem); - // Have a message be broadcasted to the UI process by the UI process // observer service. async NotifyUiObservers(nsCString aTopic); diff --git a/gfx/layers/Compositor.cpp b/gfx/layers/Compositor.cpp index ce7eb9008..b623b8de9 100644 --- a/gfx/layers/Compositor.cpp +++ b/gfx/layers/Compositor.cpp @@ -173,9 +173,7 @@ Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags, const gfx::Matrix4x4& aTransform, uint32_t aFlashCounter) { -#ifdef MOZ_B2G - int lWidth = 4; -#elif defined(ANDROID) +#if defined(ANDROID) int lWidth = 10; #else int lWidth = 2; diff --git a/gfx/layers/ImageDataSerializer.cpp b/gfx/layers/ImageDataSerializer.cpp index 08ed83bd9..db11e903c 100644 --- a/gfx/layers/ImageDataSerializer.cpp +++ b/gfx/layers/ImageDataSerializer.cpp @@ -84,6 +84,41 @@ ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize } uint32_t +ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize, + uint32_t aYOffset, uint32_t aCbOffset, uint32_t aCrOffset) +{ + MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0); + + int32_t yStride = aYSize.width; + int32_t cbCrStride = aCbCrSize.width; + if (aYSize.height < 0 || aYSize.width < 0 || aCbCrSize.height < 0 || aCbCrSize.width < 0 || + !gfx::Factory::AllowedSurfaceSize(IntSize(yStride, aYSize.height)) || + !gfx::Factory::AllowedSurfaceSize(IntSize(cbCrStride, aCbCrSize.height))) { + return 0; + } + + uint32_t yLength = GetAlignedStride<4>(yStride, aYSize.height); + uint32_t cbCrLength = GetAlignedStride<4>(cbCrStride, aCbCrSize.height); + if (yLength == 0 || cbCrLength == 0) { + return 0; + } + + CheckedInt<uint32_t> yEnd = aYOffset; + yEnd += yLength; + CheckedInt<uint32_t> cbEnd = aCbOffset; + cbEnd += cbCrLength; + CheckedInt<uint32_t> crEnd = aCrOffset; + crEnd += cbCrLength; + + if (!yEnd.isValid() || !cbEnd.isValid() || !crEnd.isValid() || + yEnd.value() > aCbOffset || cbEnd.value() > aCrOffset) { + return 0; + } + + return crEnd.value(); +} + +uint32_t ComputeYCbCrBufferSize(uint32_t aBufferSize) { return GetAlignedStride<4>(aBufferSize, 1); diff --git a/gfx/layers/ImageDataSerializer.h b/gfx/layers/ImageDataSerializer.h index 53a589d21..4b3194b0c 100644 --- a/gfx/layers/ImageDataSerializer.h +++ b/gfx/layers/ImageDataSerializer.h @@ -47,7 +47,11 @@ uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, int32_t aCbCrStride); uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize); - +uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, + const gfx::IntSize& aCbCrSize, + uint32_t aYOffset, + uint32_t aCbOffset, + uint32_t aCrOffset); uint32_t ComputeYCbCrBufferSize(uint32_t aBufferSize); void ComputeYCbCrOffsets(int32_t yStride, int32_t yHeight, diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 857ae5958..f54326360 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1145,6 +1145,7 @@ APZCTreeManager::UpdateWheelTransaction(LayoutDeviceIntPoint aRefPoint, case eMouseUp: case eMouseDown: case eMouseDoubleClick: + case eMouseAuxClick: case eMouseClick: case eContextMenu: case eDrop: diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index 1ff27f795..634d9e340 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -470,15 +470,15 @@ AttemptVideoScale(TextureSourceBasic* aSource, const SourceSurface* aSourceMask, RefPtr<DataSourceSurface> srcSource = aSource->GetSurface(aDest)->GetDataSurface(); DataSourceSurface::ScopedMap mapSrc(srcSource, DataSourceSurface::READ); - ssse3_scale_data((uint32_t*)mapSrc.GetData(), srcSource->GetSize().width, srcSource->GetSize().height, - mapSrc.GetStride()/4, - ((uint32_t*)dstData) + fillRect.x + (dstStride / 4) * fillRect.y, dstRect.width, dstRect.height, - dstStride / 4, - offset.x, offset.y, - fillRect.width, fillRect.height); + bool success = ssse3_scale_data((uint32_t*)mapSrc.GetData(), srcSource->GetSize().width, srcSource->GetSize().height, + mapSrc.GetStride()/4, + ((uint32_t*)dstData) + fillRect.x + (dstStride / 4) * fillRect.y, dstRect.width, dstRect.height, + dstStride / 4, + offset.x, offset.y, + fillRect.width, fillRect.height); aDest->ReleaseBits(dstData); - return true; + return success; } else #endif // MOZILLA_SSE_HAVE_CPUID_DETECTION return false; diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 35070cad6..f25503532 100755 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -35,9 +35,6 @@ #include "TextRenderer.h" // for TextRenderer #include <vector> #include "GeckoProfiler.h" // for GeckoProfiler -#ifdef MOZ_ENABLE_PROFILER_SPS -#include "ProfilerMarkers.h" // for ProfilerMarkers -#endif #define CULLING_LOG(...) // #define CULLING_LOG(...) printf_stderr("CULLING: " __VA_ARGS__) @@ -86,26 +83,7 @@ static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer) static void PrintUniformityInfo(Layer* aLayer) { -#ifdef MOZ_ENABLE_PROFILER_SPS - if (!profiler_is_active()) { - return; - } - - // Don't want to print a log for smaller layers - if (aLayer->GetLocalVisibleRegion().GetBounds().width < 300 || - aLayer->GetLocalVisibleRegion().GetBounds().height < 300) { - return; - } - - Matrix4x4 transform = aLayer->AsLayerComposite()->GetShadowBaseTransform(); - if (!transform.Is2D()) { - return; - } - - Point translation = transform.As2D().GetTranslation(); - LayerTranslationPayload* payload = new LayerTranslationPayload(aLayer, translation); - PROFILER_MARKER_PAYLOAD("LayerTranslation", payload); -#endif + /*** STUB ***/ } /* all of the per-layer prepared data we need to maintain */ diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index e7d87e238..e4a2ffd86 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -259,7 +259,9 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc, case BufferDescriptor::TYCbCrDescriptor: { const YCbCrDescriptor& ycbcr = desc.get_YCbCrDescriptor(); reqSize = - ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.cbCrSize()); + ImageDataSerializer::ComputeYCbCrBufferSize(ycbcr.ySize(), ycbcr.cbCrSize(), + ycbcr.yOffset(), ycbcr.cbOffset(), + ycbcr.crOffset()); break; } case BufferDescriptor::TRGBDescriptor: { @@ -272,7 +274,7 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc, MOZ_CRASH("GFX: Bad descriptor"); } - if (bufSize < reqSize) { + if (reqSize == 0 || bufSize < reqSize) { NS_ERROR("A client process gave a shmem too small to fit for its descriptor!"); return nullptr; } @@ -888,8 +890,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/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 540d39b33..2197f5444 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -19,7 +19,6 @@ #include "nsWindowsHelpers.h" #include "gfxPrefs.h" #include "gfxConfig.h" -#include "gfxCrashReporterUtils.h" #include "gfxUtils.h" #include "mozilla/gfx/StackArray.h" #include "mozilla/Services.h" @@ -181,8 +180,6 @@ CompositorD3D11::~CompositorD3D11() bool CompositorD3D11::Initialize(nsCString* const out_failureReason) { - ScopedGfxFeatureReporter reporter("D3D11 Layers"); - MOZ_ASSERT(gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)); HRESULT hr; @@ -415,7 +412,6 @@ CompositorD3D11::Initialize(nsCString* const out_failureReason) mAllowPartialPresents = CanUsePartialPresents(mDevice); - reporter.SetSuccessful(); return true; } diff --git a/gfx/layers/d3d9/CompositorD3D9.cpp b/gfx/layers/d3d9/CompositorD3D9.cpp index 0f7e942c1..85c19139f 100644 --- a/gfx/layers/d3d9/CompositorD3D9.cpp +++ b/gfx/layers/d3d9/CompositorD3D9.cpp @@ -15,7 +15,6 @@ #include "gfxFailure.h" #include "mozilla/layers/LayerManagerComposite.h" #include "gfxPrefs.h" -#include "gfxCrashReporterUtils.h" #include "gfxUtils.h" #include "mozilla/gfx/DeviceManagerDx.h" #include "mozilla/layers/CompositorBridgeParent.h" @@ -43,8 +42,6 @@ CompositorD3D9::~CompositorD3D9() bool CompositorD3D9::Initialize(nsCString* const out_failureReason) { - ScopedGfxFeatureReporter reporter("D3D9 Layers"); - mDeviceManager = DeviceManagerD3D9::Get(); if (!mDeviceManager) { *out_failureReason = "FEATURE_FAILURE_D3D9_DEVICE_MANAGER"; @@ -62,8 +59,6 @@ CompositorD3D9::Initialize(nsCString* const out_failureReason) return false; } - reporter.SetSuccessful(); - return true; } diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 6728e8841..bf510cd46 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -74,9 +74,6 @@ #include "mozilla/HalTypes.h" #include "mozilla/StaticPtr.h" #include "mozilla/Telemetry.h" -#ifdef MOZ_ENABLE_PROFILER_SPS -#include "ProfilerMarkers.h" -#endif #include "mozilla/VsyncDispatcher.h" #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) #include "VsyncSource.h" @@ -1923,11 +1920,7 @@ CompositorBridgeParent::GetAPZCTreeManager(uint64_t aLayersId) static void InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp) { -#ifdef MOZ_ENABLE_PROFILER_SPS - MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); - VsyncPayload* payload = new VsyncPayload(aVsyncTimestamp); - PROFILER_MARKER_PAYLOAD("VsyncTimestamp", payload); -#endif + /*** STUB ***/ } /*static */ void diff --git a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp index 1bb6d046b..c3ea33149 100644 --- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp @@ -73,9 +73,6 @@ #include "mozilla/HalTypes.h" #include "mozilla/StaticPtr.h" #include "mozilla/Telemetry.h" -#ifdef MOZ_ENABLE_PROFILER_SPS -#include "ProfilerMarkers.h" -#endif #include "mozilla/VsyncDispatcher.h" #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) #include "VsyncSource.h" diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 0466a1031..efd7a0162 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -73,24 +73,10 @@ protected: MOZ_IS_CLASS_INIT void Init() { -#ifdef MOZ_ENABLE_PROFILER_SPS - mPseudoStackHack = mozilla_get_pseudo_stack(); -#endif } void CleanUp() { -#ifdef MOZ_ENABLE_PROFILER_SPS - mPseudoStackHack = nullptr; -#endif } - -private: - -#ifdef MOZ_ENABLE_PROFILER_SPS - // This is needed to avoid a spurious leak report. There's no other - // use for it. See bug 1239504 and bug 1215265. - MOZ_INIT_OUTSIDE_CTOR PseudoStack* mPseudoStackHack; -#endif }; } diff --git a/gfx/layers/ipc/LayerTransactionChild.cpp b/gfx/layers/ipc/LayerTransactionChild.cpp index 8b60d3b51..f07e2c27f 100644 --- a/gfx/layers/ipc/LayerTransactionChild.cpp +++ b/gfx/layers/ipc/LayerTransactionChild.cpp @@ -72,15 +72,6 @@ void LayerTransactionChild::ActorDestroy(ActorDestroyReason why) { mDestroyed = true; -#ifdef MOZ_B2G - // Due to poor lifetime management of gralloc (and possibly shmems) we will - // crash at some point in the future when we get destroyed due to abnormal - // shutdown. Its better just to crash here. On desktop though, we have a chance - // of recovering. - if (why == AbnormalShutdown) { - NS_RUNTIMEABORT("ActorDestroy by IPC channel failure at LayerTransactionChild"); - } -#endif } } // namespace layers 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/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index bbe1b4657..93656d72a 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -12,7 +12,6 @@ #include "GLUploadHelpers.h" #include "Layers.h" // for WriteSnapshotToDumpFile #include "LayerScope.h" // for LayerScope -#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter #include "gfxEnv.h" // for gfxEnv #include "gfxPlatform.h" // for gfxPlatform #include "gfxPrefs.h" // for gfxPrefs @@ -225,8 +224,6 @@ CompositorOGL::CleanupResources() bool CompositorOGL::Initialize(nsCString* const out_failureReason) { - ScopedGfxFeatureReporter reporter("GL Layers"); - // Do not allow double initialization MOZ_ASSERT(mGLContext == nullptr, "Don't reinitialize CompositorOGL"); @@ -424,8 +421,6 @@ CompositorOGL::Initialize(nsCString* const out_failureReason) console->LogStringMessage(msg.get()); } - reporter.SetSuccessful(); - return true; } diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index 02c398b51..ec6ba9131 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -161,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/qcms/chain.c b/gfx/qcms/chain.c index e382fbe00..dbae18378 100644 --- a/gfx/qcms/chain.c +++ b/gfx/qcms/chain.c @@ -972,6 +972,12 @@ static float* qcms_modular_transform_data(struct qcms_modular_transform *transfo assert(0 && "Unsupported transform module"); return NULL; } + if (transform->grid_size <= 0 && + (transform_fn == qcms_transform_module_clut || + transform_fn == qcms_transform_module_clut_only)) { + assert(0 && "Invalid transform"); + return NULL; + } transform->transform_module_fn(transform,src,dest,len); dest = src; src = new_src; 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/SkMask.cpp b/gfx/skia/skia/src/core/SkMask.cpp index 111508074..b40b94974 100644 --- a/gfx/skia/skia/src/core/SkMask.cpp +++ b/gfx/skia/skia/src/core/SkMask.cpp @@ -43,7 +43,12 @@ uint8_t* SkMask::AllocImage(size_t size) { #ifdef TRACK_SKMASK_LIFETIME SkDebugf("SkMask::AllocImage %d\n", gCounter++); #endif - return (uint8_t*)sk_malloc_throw(SkAlign4(size)); + size_t aligned_size = std::numeric_limits<size_t>::max(); + size_t adjustment = 3; + if (size + adjustment > size) { + aligned_size = (size + adjustment) & ~adjustment; + } + return static_cast<uint8_t*>(sk_malloc_throw(aligned_size)); } /** We explicitly use this allocator for SkBimap pixels, so that we can diff --git a/gfx/skia/skia/src/core/SkMath.cpp b/gfx/skia/skia/src/core/SkMath.cpp index 6eff790c8..bf9a73da8 100644 --- a/gfx/skia/skia/src/core/SkMath.cpp +++ b/gfx/skia/skia/src/core/SkMath.cpp @@ -6,6 +6,7 @@ */ #include "SkMathPriv.h" +#include "SkSafeMath.h" #include "SkFixed.h" #include "SkFloatBits.h" #include "SkFloatingPoint.h" @@ -84,3 +85,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..9948fd722 --- /dev/null +++ b/gfx/skia/skia/src/core/SkSafeMath.h @@ -0,0 +1,108 @@ +/* + * 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" +#include "SkTFitsIn.h" +#include <limits> + +// 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/skia/skia/src/core/SkScan_Path.cpp b/gfx/skia/skia/src/core/SkScan_Path.cpp index 5b80492cf..d15d2d54b 100644 --- a/gfx/skia/skia/src/core/SkScan_Path.cpp +++ b/gfx/skia/skia/src/core/SkScan_Path.cpp @@ -591,16 +591,10 @@ static bool clip_to_limit(const SkRegion& orig, SkRegion* reduced) { return true; } -/** - * Variants of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction - * is 0.5. When SK_RASTERIZE_EVEN_ROUNDING is enabled, we must bias the result before rounding to - * account for potential FDot6 rounding edge-cases. - */ -#ifdef SK_RASTERIZE_EVEN_ROUNDING -static const double kRoundBias = 0.5 / SK_FDot6One; -#else -static const double kRoundBias = 0.0; -#endif +// Bias used for conservative rounding of float rects to int rects, to nudge the irects a little +// larger, so we don't "think" a path's bounds are inside a clip, when (due to numeric drift in +// the scan-converter) we might walk beyond the predicted limits. +static const double kConservativeRoundBias = 0.5 + 1.5 / SK_FDot6One; /** * Round the value down. This is used to round the top and left of a rectangle, @@ -608,8 +602,8 @@ static const double kRoundBias = 0.0; */ static inline int round_down_to_int(SkScalar x) { double xx = x; - xx -= 0.5 + kRoundBias; - return (int)ceil(xx); + xx -= kConservativeRoundBias; + return pin_double_to_int(ceil(xx)); } /** @@ -618,8 +612,8 @@ static inline int round_down_to_int(SkScalar x) { */ static inline int round_up_to_int(SkScalar x) { double xx = x; - xx += 0.5 + kRoundBias; - return (int)floor(xx); + xx += kConservativeRoundBias; + return pin_double_to_int(floor(xx)); } /** diff --git a/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp b/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp index e3f30b0c1..993e1c59d 100644 --- a/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp +++ b/gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp @@ -14,6 +14,7 @@ #include "GrResourceProvider.h" #include "GrTypes.h" +#include "SkSafeMath.h" #include "SkTraceEvent.h" #ifdef SK_DEBUG @@ -335,7 +336,7 @@ void* GrVertexBufferAllocPool::makeSpace(size_t vertexSize, SkASSERT(startVertex); size_t offset = 0; // assign to suppress warning - void* ptr = INHERITED::makeSpace(vertexSize * vertexCount, + void* ptr = INHERITED::makeSpace(SkSafeMath::Mul(vertexSize, vertexCount), vertexSize, buffer, &offset); @@ -360,7 +361,7 @@ void* GrIndexBufferAllocPool::makeSpace(int indexCount, SkASSERT(startIndex); size_t offset = 0; // assign to suppress warning - void* ptr = INHERITED::makeSpace(indexCount * sizeof(uint16_t), + void* ptr = INHERITED::makeSpace(SkSafeMath::Mul(indexCount, sizeof(uint16_t)), sizeof(uint16_t), buffer, &offset); diff --git a/gfx/skia/skia/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/gfx/skia/skia/src/gpu/batches/GrAAHairLinePathRenderer.cpp index 9d73cf4f1..ec6c99c6e 100644 --- a/gfx/skia/skia/src/gpu/batches/GrAAHairLinePathRenderer.cpp +++ b/gfx/skia/skia/src/gpu/batches/GrAAHairLinePathRenderer.cpp @@ -828,6 +828,13 @@ void AAHairlineBatch::onPrepareDraws(Target* target) const { int lineCount = lines.count() / 2; int conicCount = conics.count() / 3; + int quadAndConicCount = conicCount + quadCount; + + static constexpr int kMaxLines = SK_MaxS32 / kLineSegNumVertices; + static constexpr int kMaxQuadsAndConics = SK_MaxS32 / kQuadNumVertices; + if (lineCount > kMaxLines || quadAndConicCount > kMaxQuadsAndConics) { + return; + } // do lines first if (lineCount) { @@ -899,7 +906,7 @@ void AAHairlineBatch::onPrepareDraws(Target* target) const { ref_quads_index_buffer(target->resourceProvider())); size_t vertexStride = sizeof(BezierVertex); - int vertexCount = kQuadNumVertices * quadCount + kQuadNumVertices * conicCount; + int vertexCount = kQuadNumVertices * quadAndConicCount; void *vertices = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); diff --git a/gfx/src/gfxCrashReporterUtils.cpp b/gfx/src/gfxCrashReporterUtils.cpp deleted file mode 100644 index 757c15527..000000000 --- a/gfx/src/gfxCrashReporterUtils.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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 "gfxCrashReporterUtils.h" - -#ifdef MOZ_GFXFEATUREREPORTER -#include "gfxCrashReporterUtils.h" -#include <string.h> // for strcmp -#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 -#include "mozilla/Services.h" // for GetObserverService -#include "mozilla/StaticMutex.h" -#include "mozilla/mozalloc.h" // for operator new, etc -#include "mozilla/RefPtr.h" // for RefPtr -#include "nsCOMPtr.h" // for nsCOMPtr -#include "nsError.h" // for NS_OK, NS_FAILED, nsresult -#include "nsExceptionHandler.h" // for AppendAppNotesToCrashReport -#include "nsID.h" -#include "nsIEventTarget.h" // for NS_DISPATCH_NORMAL -#include "nsIObserver.h" // for nsIObserver, etc -#include "nsIObserverService.h" // for nsIObserverService -#include "nsIRunnable.h" // for nsIRunnable -#include "nsISupports.h" -#include "nsTArray.h" // for nsTArray -#include "nsThreadUtils.h" // for NS_DispatchToMainThread, etc -#include "nscore.h" // for NS_IMETHOD, NS_IMETHODIMP, etc - -namespace mozilla { - -static nsTArray<nsCString> *gFeaturesAlreadyReported = nullptr; -static StaticMutex gFeaturesAlreadyReportedMutex; - -class ObserverToDestroyFeaturesAlreadyReported final : public nsIObserver -{ - -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - ObserverToDestroyFeaturesAlreadyReported() {} -private: - virtual ~ObserverToDestroyFeaturesAlreadyReported() {} -}; - -NS_IMPL_ISUPPORTS(ObserverToDestroyFeaturesAlreadyReported, - nsIObserver) - -NS_IMETHODIMP -ObserverToDestroyFeaturesAlreadyReported::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - if (!strcmp(aTopic, "xpcom-shutdown")) { - StaticMutexAutoLock al(gFeaturesAlreadyReportedMutex); - if (gFeaturesAlreadyReported) { - delete gFeaturesAlreadyReported; - gFeaturesAlreadyReported = nullptr; - } - } - return NS_OK; -} - -class RegisterObserverRunnable : public Runnable { -public: - NS_IMETHOD Run() override { - // LeakLog made me do this. Basically, I just wanted gFeaturesAlreadyReported to be a static nsTArray<nsCString>, - // and LeakLog was complaining about leaks like this: - // leaked 1 instance of nsTArray_base with size 8 bytes - // leaked 7 instances of nsStringBuffer with size 8 bytes each (56 bytes total) - // So this is a work-around using a pointer, and using a nsIObserver to deallocate on xpcom shutdown. - // Yay for fighting bloat. - nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); - if (!observerService) - return NS_OK; - RefPtr<ObserverToDestroyFeaturesAlreadyReported> observer = new ObserverToDestroyFeaturesAlreadyReported; - observerService->AddObserver(observer, "xpcom-shutdown", false); - return NS_OK; - } -}; - -class AppendAppNotesRunnable : public CancelableRunnable { -public: - explicit AppendAppNotesRunnable(const nsACString& aFeatureStr) - : mFeatureString(aFeatureStr) - { - } - - NS_IMETHOD Run() override { - CrashReporter::AppendAppNotesToCrashReport(mFeatureString); - return NS_OK; - } - -private: - nsAutoCString mFeatureString; -}; - -void -ScopedGfxFeatureReporter::WriteAppNote(char statusChar) -{ - StaticMutexAutoLock al(gFeaturesAlreadyReportedMutex); - - if (!gFeaturesAlreadyReported) { - gFeaturesAlreadyReported = new nsTArray<nsCString>; - nsCOMPtr<nsIRunnable> r = new RegisterObserverRunnable(); - NS_DispatchToMainThread(r); - } - - nsAutoCString featureString; - featureString.AppendPrintf("%s%c ", - mFeature, - statusChar); - - if (!gFeaturesAlreadyReported->Contains(featureString)) { - gFeaturesAlreadyReported->AppendElement(featureString); - AppNote(featureString); - } -} - -void -ScopedGfxFeatureReporter::AppNote(const nsACString& aMessage) -{ - if (NS_IsMainThread()) { - CrashReporter::AppendAppNotesToCrashReport(aMessage); - } else { - nsCOMPtr<nsIRunnable> r = new AppendAppNotesRunnable(aMessage); - NS_DispatchToMainThread(r); - } -} - -} // end namespace mozilla - -#else - -namespace mozilla { -void ScopedGfxFeatureReporter::WriteAppNote(char) {} -void ScopedGfxFeatureReporter::AppNote(const nsACString&) {} - -} // namespace mozilla - -#endif diff --git a/gfx/src/gfxCrashReporterUtils.h b/gfx/src/gfxCrashReporterUtils.h deleted file mode 100644 index efc5ab1ab..000000000 --- a/gfx/src/gfxCrashReporterUtils.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; 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 gfxCrashReporterUtils_h__ -#define gfxCrashReporterUtils_h__ - -#include "nsString.h" - -namespace mozilla { - -/** \class ScopedGfxFeatureReporter - * - * On creation, adds "FeatureName?" to AppNotes - * On destruction, adds "FeatureName-", or "FeatureName+" if you called SetSuccessful(). - * - * Any such string is added at most once to AppNotes, and is subsequently skipped. - * - * This ScopedGfxFeatureReporter class is designed to be fool-proof to use in functions that - * have many exit points. We don't want to encourage having function with many exit points. - * It just happens that our graphics features initialization functions are like that. - */ -class ScopedGfxFeatureReporter -{ -public: - explicit ScopedGfxFeatureReporter(const char *aFeature, bool aForce = false) - : mFeature(aFeature), mStatusChar('-') - { - WriteAppNote(aForce ? '!' : '?'); - } - ~ScopedGfxFeatureReporter() { - WriteAppNote(mStatusChar); - } - void SetSuccessful() { mStatusChar = '+'; } - - static void AppNote(const nsACString& aMessage); - - class AppNoteWritingRunnable; - -protected: - const char *mFeature; - char mStatusChar; - -private: - void WriteAppNote(char statusChar); -}; - -} // end namespace mozilla - -#endif // gfxCrashReporterUtils_h__ diff --git a/gfx/src/moz.build b/gfx/src/moz.build index 3678eee7a..ea707a340 100644 --- a/gfx/src/moz.build +++ b/gfx/src/moz.build @@ -16,7 +16,6 @@ DEFINES['MOZ_APP_VERSION'] = '"%s"' % CONFIG['MOZ_APP_VERSION'] EXPORTS += [ 'DriverCrashGuard.h', 'FilterSupport.h', - 'gfxCrashReporterUtils.h', 'gfxTelemetry.h', 'nsBoundingMetrics.h', 'nsColor.h', @@ -60,7 +59,6 @@ if CONFIG['MOZ_X11']: UNIFIED_SOURCES += [ 'DriverCrashGuard.cpp', 'FilterSupport.cpp', - 'gfxCrashReporterUtils.cpp', 'gfxTelemetry.cpp', 'nsColor.cpp', 'nsFont.cpp', diff --git a/gfx/tests/mochitest/test_acceleration.html b/gfx/tests/mochitest/test_acceleration.html index 0475a9590..cb1fcd39b 100644 --- a/gfx/tests/mochitest/test_acceleration.html +++ b/gfx/tests/mochitest/test_acceleration.html @@ -98,7 +98,7 @@ switch(osName) break; default: - if (xr.OS == "Android" && xr.widgetToolkit != "gonk") { + if (xr.OS == "Android") { isnot(acceleratedWindows, 0, "Acceleration enabled on Android"); } else { is(acceleratedWindows, 0, "Acceleration not supported on '" + osName + "'"); diff --git a/gfx/thebes/ContextStateTracker.cpp b/gfx/thebes/ContextStateTracker.cpp index e3659e5fc..a179abad9 100644 --- a/gfx/thebes/ContextStateTracker.cpp +++ b/gfx/thebes/ContextStateTracker.cpp @@ -5,9 +5,6 @@ #include "ContextStateTracker.h" #include "GLContext.h" -#ifdef MOZ_ENABLE_PROFILER_SPS -#include "ProfilerMarkers.h" -#endif namespace mozilla { @@ -110,15 +107,6 @@ ContextStateTrackerOGL::Flush(GLContext* aGL) aGL->fDeleteQueries(1, &handle); -#ifdef MOZ_ENABLE_PROFILER_SPS - PROFILER_MARKER_PAYLOAD("gpu_timer_query", new GPUMarkerPayload( - mCompletedSections[0].mCpuTimeStart, - mCompletedSections[0].mCpuTimeEnd, - 0, - gpuTime - )); -#endif - mCompletedSections.RemoveElementAt(0); } } diff --git a/gfx/thebes/DeviceManagerDx.cpp b/gfx/thebes/DeviceManagerDx.cpp index c194f40f2..2f2693c76 100644 --- a/gfx/thebes/DeviceManagerDx.cpp +++ b/gfx/thebes/DeviceManagerDx.cpp @@ -389,7 +389,6 @@ DeviceManagerDx::CreateDevice(IDXGIAdapter* aAdapter, void DeviceManagerDx::CreateWARPCompositorDevice() { - ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP()); FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING); HRESULT hr; @@ -434,7 +433,6 @@ DeviceManagerDx::CreateWARPCompositorDevice() } mCompositorDevice->SetExceptionMode(0); - reporterWARP.SetSuccessful(); } FeatureStatus diff --git a/gfx/thebes/DeviceManagerDx.h b/gfx/thebes/DeviceManagerDx.h index ea6dd4846..e29ab0731 100644 --- a/gfx/thebes/DeviceManagerDx.h +++ b/gfx/thebes/DeviceManagerDx.h @@ -34,8 +34,6 @@ struct ID3D11Device; struct IDirectDraw7; namespace mozilla { -class ScopedGfxFeatureReporter; - namespace gfx { class FeatureState; diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index f587737b5..76427d88c 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -21,6 +21,7 @@ #include "nsIScreenManager.h" #include "nsILocaleService.h" #include "nsServiceManagerUtils.h" +#include "nsUnicodeProperties.h" #include "gfxPrefs.h" #include "cairo.h" #include "VsyncSource.h" @@ -32,6 +33,7 @@ using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::gfx; +using namespace mozilla::unicode; static FT_Library gPlatformFTLibrary = nullptr; @@ -168,19 +170,17 @@ gfxAndroidPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, static const char kNotoSansCJKJP[] = "Noto Sans CJK JP"; static const char kNotoColorEmoji[] = "Noto Color Emoji"; - if (aNextCh == 0xfe0fu) { - // if char is followed by VS16, try for a color emoji glyph - aFontList.AppendElement(kNotoColorEmoji); + EmojiPresentation emoji = GetEmojiPresentation(aCh); + if (emoji != EmojiPresentation::TextOnly) { + if (aNextCh == kVariationSelector16 || + (aNextCh != kVariationSelector15 && + emoji == EmojiPresentation::EmojiDefault)) { + // if char is followed by VS16, try for a color emoji glyph + aFontList.AppendElement(kNotoColorEmoji); + } } - if (!IS_IN_BMP(aCh)) { - uint32_t p = aCh >> 16; - if (p == 1) { // try color emoji font, unless VS15 (text style) present - if (aNextCh != 0xfe0fu && aNextCh != 0xfe0eu) { - aFontList.AppendElement(kNotoColorEmoji); - } - } - } else { + if (IS_IN_BMP(aCh)) { // try language-specific "Droid Sans *" and "Noto Sans *" fonts for // certain blocks, as most devices probably have these uint8_t block = (aCh >> 8) & 0xff; diff --git a/gfx/thebes/gfxFontConstants.h b/gfx/thebes/gfxFontConstants.h index 5aa1eb0c7..3eae49ee1 100644 --- a/gfx/thebes/gfxFontConstants.h +++ b/gfx/thebes/gfxFontConstants.h @@ -222,13 +222,14 @@ enum { #define NS_FONT_SUB_SUPER_SMALL_SIZE (20.0) #define NS_FONT_SUB_SUPER_LARGE_SIZE (45.0) -// pref lang id's for font prefs +// pref lang ids for font prefs enum eFontPrefLang { #define FONT_PREF_LANG(enum_id_, str_, atom_id_) eFontPrefLang_ ## enum_id_ #include "gfxFontPrefLangList.h" #undef FONT_PREF_LANG , eFontPrefLang_CJKSet // special code for CJK set + , eFontPrefLang_Emoji // special code for emoji presentation , eFontPrefLang_First = eFontPrefLang_Western , eFontPrefLang_Last = eFontPrefLang_Others , eFontPrefLang_Count = (eFontPrefLang_Last - eFontPrefLang_First + 1) diff --git a/gfx/thebes/gfxFontFamilyList.h b/gfx/thebes/gfxFontFamilyList.h index e240102e0..9d1a3cf49 100644 --- a/gfx/thebes/gfxFontFamilyList.h +++ b/gfx/thebes/gfxFontFamilyList.h @@ -38,6 +38,7 @@ enum FontFamilyType : uint32_t { // special eFamily_moz_variable, eFamily_moz_fixed, + eFamily_moz_emoji, eFamily_generic_first = eFamily_serif, eFamily_generic_last = eFamily_fantasy, diff --git a/gfx/thebes/gfxFontUtils.cpp b/gfx/thebes/gfxFontUtils.cpp index cb505e87b..54ca03ff6 100644 --- a/gfx/thebes/gfxFontUtils.cpp +++ b/gfx/thebes/gfxFontUtils.cpp @@ -575,55 +575,64 @@ typedef struct { #pragma pack() uint32_t -gfxFontUtils::MapCharToGlyphFormat4(const uint8_t *aBuf, char16_t aCh) +gfxFontUtils::MapCharToGlyphFormat4(const uint8_t* aBuf, uint32_t aLength, + char16_t aCh) { const Format4Cmap *cmap4 = reinterpret_cast<const Format4Cmap*>(aBuf); - uint16_t segCount; - const AutoSwap_PRUint16 *endCodes; - const AutoSwap_PRUint16 *startCodes; - const AutoSwap_PRUint16 *idDelta; - const AutoSwap_PRUint16 *idRangeOffset; - uint16_t probe; - uint16_t rangeShiftOver2; - uint16_t index; - - segCount = (uint16_t)(cmap4->segCountX2) / 2; - - endCodes = &cmap4->arrays[0]; - startCodes = &cmap4->arrays[segCount + 1]; // +1 for reserved word between arrays - idDelta = &startCodes[segCount]; - idRangeOffset = &idDelta[segCount]; - - probe = 1 << (uint16_t)(cmap4->entrySelector); - rangeShiftOver2 = (uint16_t)(cmap4->rangeShift) / 2; - - if ((uint16_t)(startCodes[rangeShiftOver2]) <= aCh) { - index = rangeShiftOver2; - } else { - index = 0; - } - - while (probe > 1) { - probe >>= 1; - if ((uint16_t)(startCodes[index + probe]) <= aCh) { - index += probe; + + uint16_t segCount = (uint16_t)(cmap4->segCountX2) / 2; + + const AutoSwap_PRUint16* endCodes = &cmap4->arrays[0]; + const AutoSwap_PRUint16* startCodes = &cmap4->arrays[segCount + 1]; + const AutoSwap_PRUint16* idDelta = &startCodes[segCount]; + const AutoSwap_PRUint16* idRangeOffset = &idDelta[segCount]; + + // Sanity-check that the fixed-size arrays don't exceed the buffer. + const uint8_t* const limit = aBuf + aLength; + if ((const uint8_t*)(&idRangeOffset[segCount]) > limit) { + return 0; // broken font, just bail out safely + } + + // For most efficient binary search, we want to work on a range of segment + // indexes that is a power of 2 so that we can always halve it by shifting. + // So we find the largest power of 2 that is <= segCount. + // We will offset this range by segOffset so as to reach the end + // of the table, provided that doesn't put us beyond the target + // value from the outset. + uint32_t powerOf2 = mozilla::FindHighestBit(segCount); + uint32_t segOffset = segCount - powerOf2; + uint32_t idx = 0; + + if (uint16_t(startCodes[segOffset]) <= aCh) { + idx = segOffset; + } + + // Repeatedly halve the size of the range until we find the target group + while (powerOf2 > 1) { + powerOf2 >>= 1; + if (uint16_t(startCodes[idx + powerOf2]) <= aCh) { + idx += powerOf2; } } - if (aCh >= (uint16_t)(startCodes[index]) && aCh <= (uint16_t)(endCodes[index])) { + if (aCh >= uint16_t(startCodes[idx]) && aCh <= uint16_t(endCodes[idx])) { uint16_t result; - if ((uint16_t)(idRangeOffset[index]) == 0) { + if (uint16_t(idRangeOffset[idx]) == 0) { result = aCh; } else { - uint16_t offset = aCh - (uint16_t)(startCodes[index]); - const AutoSwap_PRUint16 *glyphIndexTable = - (const AutoSwap_PRUint16*)((const char*)&idRangeOffset[index] + - (uint16_t)(idRangeOffset[index])); + uint16_t offset = aCh - uint16_t(startCodes[idx]); + const AutoSwap_PRUint16* glyphIndexTable = + (const AutoSwap_PRUint16*)((const char*)&idRangeOffset[idx] + + uint16_t(idRangeOffset[idx])); + if ((const uint8_t*)(glyphIndexTable + offset + 1) > limit) { + return 0; // broken font, just bail out safely + } result = glyphIndexTable[offset]; } - // note that this is unsigned 16-bit arithmetic, and may wrap around - result += (uint16_t)(idDelta[index]); + // Note that this is unsigned 16-bit arithmetic, and may wrap around + // (which is required behavior per spec) + result += uint16_t(idDelta[idx]); return result; } @@ -761,7 +770,8 @@ gfxFontUtils::MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength, switch (format) { case 4: gid = aUnicode < UNICODE_BMP_LIMIT ? - MapCharToGlyphFormat4(aCmapBuf + offset, char16_t(aUnicode)) : 0; + MapCharToGlyphFormat4(aCmapBuf + offset, aBufLength - offset, + char16_t(aUnicode)) : 0; break; case 10: gid = MapCharToGlyphFormat10(aCmapBuf + offset, aUnicode); @@ -785,6 +795,7 @@ gfxFontUtils::MapCharToGlyph(const uint8_t *aCmapBuf, uint32_t aBufLength, case 4: if (aUnicode < UNICODE_BMP_LIMIT) { varGID = MapCharToGlyphFormat4(aCmapBuf + offset, + aBufLength - offset, char16_t(aUnicode)); } break; diff --git a/gfx/thebes/gfxFontUtils.h b/gfx/thebes/gfxFontUtils.h index dd6a76558..1e87e5436 100644 --- a/gfx/thebes/gfxFontUtils.h +++ b/gfx/thebes/gfxFontUtils.h @@ -804,7 +804,7 @@ public: bool& aUnicodeFont, bool& aSymbolFont); static uint32_t - MapCharToGlyphFormat4(const uint8_t *aBuf, char16_t aCh); + MapCharToGlyphFormat4(const uint8_t *aBuf, uint32_t aLength, char16_t aCh); static uint32_t MapCharToGlyphFormat10(const uint8_t *aBuf, uint32_t aCh); diff --git a/gfx/thebes/gfxHarfBuzzShaper.cpp b/gfx/thebes/gfxHarfBuzzShaper.cpp index 1f472f88d..f2264bc1f 100644 --- a/gfx/thebes/gfxHarfBuzzShaper.cpp +++ b/gfx/thebes/gfxHarfBuzzShaper.cpp @@ -12,20 +12,14 @@ #include "mozilla/Sprintf.h" #include "nsUnicodeProperties.h" #include "nsUnicodeScriptCodes.h" -#include "nsUnicodeNormalizer.h" #include "harfbuzz/hb.h" #include "harfbuzz/hb-ot.h" -#if ENABLE_INTL_API // ICU is available: we'll use it for Unicode composition - // and decomposition in preference to nsUnicodeNormalizer. #include "unicode/unorm.h" #include "unicode/utext.h" -#define MOZ_HB_SHAPER_USE_ICU_NORMALIZATION 1 + static const UNormalizer2 * sNormalizer = nullptr; -#else -#undef MOZ_HB_SHAPER_USE_ICU_NORMALIZATION -#endif #include <algorithm> @@ -117,13 +111,15 @@ gfxHarfBuzzShaper::GetNominalGlyph(hb_codepoint_t unicode) const NS_ASSERTION(mCmapTable && (mCmapFormat > 0) && (mSubtableOffset > 0), "cmap data not correctly set up, expect disaster"); + uint32_t length; const uint8_t* data = - (const uint8_t*)hb_blob_get_data(mCmapTable, nullptr); + (const uint8_t*)hb_blob_get_data(mCmapTable, &length); switch (mCmapFormat) { case 4: gid = unicode < UNICODE_BMP_LIMIT ? gfxFontUtils::MapCharToGlyphFormat4(data + mSubtableOffset, + length - mSubtableOffset, unicode) : 0; break; case 10: @@ -163,8 +159,9 @@ gfxHarfBuzzShaper::GetVariationGlyph(hb_codepoint_t unicode, NS_ASSERTION(mCmapTable && (mCmapFormat > 0) && (mSubtableOffset > 0), "cmap data not correctly set up, expect disaster"); + uint32_t length; const uint8_t* data = - (const uint8_t*)hb_blob_get_data(mCmapTable, nullptr); + (const uint8_t*)hb_blob_get_data(mCmapTable, &length); if (mUVSTableOffset) { hb_codepoint_t gid = @@ -182,6 +179,7 @@ gfxHarfBuzzShaper::GetVariationGlyph(hb_codepoint_t unicode, case 4: if (compat < UNICODE_BMP_LIMIT) { return gfxFontUtils::MapCharToGlyphFormat4(data + mSubtableOffset, + length - mSubtableOffset, compat); } break; @@ -1091,8 +1089,6 @@ HBUnicodeCompose(hb_unicode_funcs_t *ufuncs, hb_codepoint_t *ab, void *user_data) { -#if MOZ_HB_SHAPER_USE_ICU_NORMALIZATION - if (sNormalizer) { UChar32 ch = unorm2_composePair(sNormalizer, a, b); if (ch >= 0) { @@ -1101,14 +1097,6 @@ HBUnicodeCompose(hb_unicode_funcs_t *ufuncs, } } -#else // no ICU available, use the old nsUnicodeNormalizer - - if (nsUnicodeNormalizer::Compose(a, b, ab)) { - return true; - } - -#endif - return false; } @@ -1129,8 +1117,6 @@ HBUnicodeDecompose(hb_unicode_funcs_t *ufuncs, } #endif -#if MOZ_HB_SHAPER_USE_ICU_NORMALIZATION - if (!sNormalizer) { return false; } @@ -1162,12 +1148,6 @@ HBUnicodeDecompose(hb_unicode_funcs_t *ufuncs, utext_close(&text); return *b != 0 || *a != ab; - -#else // no ICU available, use the old nsUnicodeNormalizer - - return nsUnicodeNormalizer::DecomposeNonRecursively(ab, a, b); - -#endif } static void @@ -1250,11 +1230,9 @@ gfxHarfBuzzShaper::Initialize() HBUnicodeDecompose, nullptr, nullptr); -#if MOZ_HB_SHAPER_USE_ICU_NORMALIZATION UErrorCode error = U_ZERO_ERROR; sNormalizer = unorm2_getNFCInstance(&error); - NS_ASSERTION(U_SUCCESS(error), "failed to get ICU normalizer"); -#endif + MOZ_ASSERT(U_SUCCESS(error), "failed to get ICU normalizer"); } gfxFontEntry *entry = mFont->GetFontEntry(); diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index a468592fe..171d1bec9 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -18,7 +18,6 @@ #include "mozilla/Logging.h" #include "mozilla/Services.h" -#include "gfxCrashReporterUtils.h" #include "gfxPlatform.h" #include "gfxPrefs.h" #include "gfxEnv.h" @@ -157,6 +156,7 @@ static Mutex* gGfxPlatformPrefsLock = nullptr; static qcms_profile *gCMSOutputProfile = nullptr; static qcms_profile *gCMSsRGBProfile = nullptr; +static bool gCMSRGBTransformFailed = false; static qcms_transform *gCMSRGBTransform = nullptr; static qcms_transform *gCMSInverseRGBTransform = nullptr; static qcms_transform *gCMSRGBATransform = nullptr; @@ -650,7 +650,6 @@ gfxPlatform::Init() gfxPrefs::CanvasAzureAccelerated(), gfxPrefs::DisableGralloc(), gfxPrefs::ForceShmemTiles()); - ScopedGfxFeatureReporter::AppNote(forcedPrefs); } InitMoz2DLogging(); @@ -1858,7 +1857,7 @@ gfxPlatform::GetCMSsRGBProfile() qcms_transform * gfxPlatform::GetCMSRGBTransform() { - if (!gCMSRGBTransform) { + if (!gCMSRGBTransform && !gCMSRGBTransformFailed) { qcms_profile *inProfile, *outProfile; outProfile = GetCMSOutputProfile(); inProfile = GetCMSsRGBProfile(); @@ -1869,6 +1868,9 @@ gfxPlatform::GetCMSRGBTransform() gCMSRGBTransform = qcms_transform_create(inProfile, QCMS_DATA_RGB_8, outProfile, QCMS_DATA_RGB_8, QCMS_INTENT_PERCEPTUAL); + if (!gCMSRGBTransform) { + gCMSRGBTransformFailed = true; + } } return gCMSRGBTransform; @@ -2399,11 +2401,10 @@ gfxPlatform::GetTilesSupportInfo(mozilla::widget::InfoObject& aObj) /*static*/ bool gfxPlatform::AsyncPanZoomEnabled() { -#if !defined(MOZ_B2G) && !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_UIKIT) - // For XUL applications (everything but B2G on mobile and desktop, and - // Firefox on Android) we only want to use APZ when E10S is enabled. If - // we ever get input events off the main thread we can consider relaxing - // this requirement. +#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_UIKIT) + // For XUL applications (everything but Firefox on Android) we only want + // to use APZ when E10S is enabled. If we ever get input events off the + // main thread we can consider relaxing this requirement. if (!BrowserTabsRemoteAutostart()) { return false; } diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 01394db14..e12f4e197 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -869,28 +869,54 @@ gfxPlatformFontList::ResolveGenericFontNames( nsIAtom* langGroup = GetLangGroupForPrefLang(aPrefLang); NS_ASSERTION(langGroup, "null lang group for pref lang"); + gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(genericFamilies, + langGroup, + aGenericFamilies); + +#if 0 // dump out generic mappings + printf("%s ===> ", prefFontName.get()); + for (uint32_t k = 0; k < aGenericFamilies->Length(); k++) { + if (k > 0) printf(", "); + printf("%s", NS_ConvertUTF16toUTF8(aGenericFamilies[k]->Name()).get()); + } + printf("\n"); +#endif +} + +void +gfxPlatformFontList::ResolveEmojiFontNames( + nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies) +{ + // emoji preference has no lang name + AutoTArray<nsString,4> genericFamilies; + + nsAutoCString prefFontListName("font.name-list.emoji"); + gfxFontUtils::AppendPrefsFontList(prefFontListName.get(), genericFamilies); + + gfxPlatformFontList::GetFontFamiliesFromGenericFamilies(genericFamilies, + nullptr, + aGenericFamilies); +} + +void +gfxPlatformFontList::GetFontFamiliesFromGenericFamilies( + nsTArray<nsString>& aGenericNameFamilies, + nsIAtom* aLangGroup, + nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies) +{ // lookup and add platform fonts uniquely - for (const nsString& genericFamily : genericFamilies) { + for (const nsString& genericFamily : aGenericNameFamilies) { gfxFontStyle style; - style.language = langGroup; + style.language = aLangGroup; style.systemFont = false; AutoTArray<gfxFontFamily*,10> families; - FindAndAddFamilies(genericFamily, &families, &style); + FindAndAddFamilies(genericFamily, &families, &style, 1.0); for (gfxFontFamily* f : families) { if (!aGenericFamilies->Contains(f)) { aGenericFamilies->AppendElement(f); } } } - -#if 0 // dump out generic mappings - printf("%s ===> ", prefFontName.get()); - for (uint32_t k = 0; k < aGenericFamilies->Length(); k++) { - if (k > 0) printf(", "); - printf("%s", NS_ConvertUTF16toUTF8(aGenericFamilies[k]->Name()).get()); - } - printf("\n"); -#endif } nsTArray<RefPtr<gfxFontFamily>>* @@ -902,6 +928,17 @@ gfxPlatformFontList::GetPrefFontsLangGroup(mozilla::FontFamilyType aGenericType, aGenericType = eFamily_monospace; } + if (aGenericType == eFamily_moz_emoji) { + // Emoji font has no lang + PrefFontList* prefFonts = mEmojiPrefFont.get(); + if (MOZ_UNLIKELY(!prefFonts)) { + prefFonts = new PrefFontList; + ResolveEmojiFontNames(prefFonts); + mEmojiPrefFont.reset(prefFonts); + } + return prefFonts; + } + PrefFontList* prefFonts = mLangGroupPrefFonts[aPrefLang][aGenericType].get(); if (MOZ_UNLIKELY(!prefFonts)) { @@ -1180,6 +1217,10 @@ gfxPlatformFontList::AppendPrefLang(eFontPrefLang aPrefLangs[], uint32_t& aLen, mozilla::FontFamilyType gfxPlatformFontList::GetDefaultGeneric(eFontPrefLang aLang) { + if (aLang == eFontPrefLang_Emoji) { + return eFamily_moz_emoji; + } + // initialize lang group pref font defaults (i.e. serif/sans-serif) if (MOZ_UNLIKELY(mDefaultGenericsLangGroup.IsEmpty())) { mDefaultGenericsLangGroup.AppendElements(ArrayLength(gPrefLangNames)); diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index c16994d8c..d77c12059 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -380,6 +380,15 @@ protected: eFontPrefLang aPrefLang, nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies); + void + ResolveEmojiFontNames(nsTArray<RefPtr<gfxFontFamily>>* aGenericFamilies); + + void + GetFontFamiliesFromGenericFamilies( + nsTArray<nsString>& aGenericFamilies, + nsIAtom* aLangGroup, + nsTArray<RefPtr<gfxFontFamily>>* aFontFamilies); + virtual nsresult InitFontListForPlatform() = 0; void ApplyWhitelist(); @@ -436,6 +445,8 @@ protected: eFontPrefLang_First, eFontPrefLang_Count> mLangGroupPrefFonts; + mozilla::UniquePtr<PrefFontList> mEmojiPrefFont; + // when system-wide font lookup fails for a character, cache it to skip future searches gfxSparseBitSet mCodepointsWithNoFonts; diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index 1fb3bc4fd..be75332d6 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -240,9 +240,14 @@ gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray<const char*>& aFontList) { - if (aNextCh == 0xfe0fu) { - // if char is followed by VS16, try for a color emoji glyph - aFontList.AppendElement(kFontTwemojiMozilla); + EmojiPresentation emoji = GetEmojiPresentation(aCh); + if (emoji != EmojiPresentation::TextOnly) { + if (aNextCh == kVariationSelector16 || + (aNextCh != kVariationSelector15 && + emoji == EmojiPresentation::EmojiDefault)) { + // if char is followed by VS16, try for a color emoji glyph + aFontList.AppendElement(kFontTwemojiMozilla); + } } aFontList.AppendElement(kFontDejaVuSerif); @@ -250,15 +255,6 @@ gfxPlatformGtk::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, aFontList.AppendElement(kFontDejaVuSans); aFontList.AppendElement(kFontFreeSans); - if (!IS_IN_BMP(aCh)) { - uint32_t p = aCh >> 16; - if (p == 1) { // try color emoji font, unless VS15 (text style) present - if (aNextCh != 0xfe0fu && aNextCh != 0xfe0eu) { - aFontList.AppendElement(kFontTwemojiMozilla); - } - } - } - // add fonts for CJK ranges // xxx - this isn't really correct, should use the same CJK font ordering // as the pref font code diff --git a/gfx/thebes/gfxPlatformMac.cpp b/gfx/thebes/gfxPlatformMac.cpp index 3216f0f07..79684dd19 100644 --- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -18,6 +18,7 @@ #include "nsTArray.h" #include "mozilla/Preferences.h" #include "mozilla/VsyncDispatcher.h" +#include "nsUnicodeProperties.h" #include "qcms.h" #include "gfx2DGlue.h" @@ -29,6 +30,7 @@ using namespace mozilla; using namespace mozilla::gfx; +using namespace mozilla::unicode; // cribbed from CTFontManager.h enum { @@ -195,23 +197,24 @@ gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray<const char*>& aFontList) { - if (aNextCh == 0xfe0f) { - aFontList.AppendElement(kFontAppleColorEmoji); + EmojiPresentation emoji = GetEmojiPresentation(aCh); + if (emoji != EmojiPresentation::TextOnly) { + if (aNextCh == kVariationSelector16 || + (aNextCh != kVariationSelector15 && + emoji == EmojiPresentation::EmojiDefault)) { + // if char is followed by VS16, try for a color emoji glyph + aFontList.AppendElement(kFontAppleColorEmoji); + } } aFontList.AppendElement(kFontLucidaGrande); if (!IS_IN_BMP(aCh)) { uint32_t p = aCh >> 16; - uint32_t b = aCh >> 8; if (p == 1) { - if (b >= 0x1f0 && b < 0x1f7) { - aFontList.AppendElement(kFontAppleColorEmoji); - } else { - aFontList.AppendElement(kFontAppleSymbols); - aFontList.AppendElement(kFontSTIXGeneral); - aFontList.AppendElement(kFontGeneva); - } + aFontList.AppendElement(kFontAppleSymbols); + aFontList.AppendElement(kFontSTIXGeneral); + aFontList.AppendElement(kFontGeneva); } else if (p == 2) { // OSX installations with MS Office may have these fonts aFontList.AppendElement(kFontMingLiUExtB); diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index 6718eed01..1702cab66 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -2813,7 +2813,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh, return nullptr; // 2. search pref fonts - RefPtr<gfxFont> font = WhichPrefFontSupportsChar(aCh); + RefPtr<gfxFont> font = WhichPrefFontSupportsChar(aCh, aNextCh); if (font) { *aMatchType = gfxTextRange::kPrefsFallback; return font.forget(); @@ -3081,15 +3081,25 @@ gfxFontGroup::ContainsUserFont(const gfxUserFontEntry* aUserFont) } already_AddRefed<gfxFont> -gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh) +gfxFontGroup::WhichPrefFontSupportsChar(uint32_t aCh, uint32_t aNextCh) { RefPtr<gfxFont> font; - // get the pref font list if it hasn't been set up already - uint32_t unicodeRange = FindCharUnicodeRange(aCh); + eFontPrefLang charLang; gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList(); - eFontPrefLang charLang = pfl->GetFontPrefLangFor(unicodeRange); + EmojiPresentation emoji = GetEmojiPresentation(aCh); + if ((emoji != EmojiPresentation::TextOnly && + (aNextCh == kVariationSelector16 || + (emoji == EmojiPresentation::EmojiDefault && + aNextCh != kVariationSelector15)))) { + charLang = eFontPrefLang_Emoji; + } else { + // get the pref font list if it hasn't been set up already + uint32_t unicodeRange = FindCharUnicodeRange(aCh); + charLang = pfl->GetFontPrefLangFor(unicodeRange); + } + // if the last pref font was the first family in the pref list, no need to recheck through a list of families if (mLastPrefFont && charLang == mLastPrefLang && mLastPrefFirstFont && mLastPrefFont->HasCharacter(aCh)) { diff --git a/gfx/thebes/gfxTextRun.h b/gfx/thebes/gfxTextRun.h index 0e44456ae..c3673785c 100644 --- a/gfx/thebes/gfxTextRun.h +++ b/gfx/thebes/gfxTextRun.h @@ -917,7 +917,8 @@ public: protected: // search through pref fonts for a character, return nullptr if no matching pref font - already_AddRefed<gfxFont> WhichPrefFontSupportsChar(uint32_t aCh); + already_AddRefed<gfxFont> WhichPrefFontSupportsChar(uint32_t aCh, + uint32_t aNextCh); already_AddRefed<gfxFont> WhichSystemFontSupportsChar(uint32_t aCh, uint32_t aNextCh, diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 313372ebc..401bceaa9 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -1477,7 +1477,7 @@ gfxUtils::ThreadSafeGetFeatureStatus(const nsCOMPtr<nsIGfxInfo>& gfxInfo, status); ErrorResult rv; - runnable->Dispatch(rv); + runnable->Dispatch(dom::workers::Terminating, rv); if (rv.Failed()) { // XXXbz This is totally broken, since we're supposed to just abort // everything up the callstack but the callers basically eat the diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index af4d932a9..a988859eb 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -13,6 +13,7 @@ #include "gfxWindowsSurface.h" #include "nsUnicharUtils.h" +#include "nsUnicodeProperties.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" @@ -32,8 +33,6 @@ #include "nsIGfxInfo.h" -#include "gfxCrashReporterUtils.h" - #include "gfxGDIFontList.h" #include "gfxGDIFont.h" @@ -81,6 +80,7 @@ using namespace mozilla::gfx; using namespace mozilla::layers; using namespace mozilla::widget; using namespace mozilla::image; +using namespace mozilla::unicode; IDWriteRenderingParams* GetDwriteRenderingParams(bool aGDI) { @@ -398,7 +398,6 @@ gfxWindowsPlatform::InitDWriteSupport() return false; } - mozilla::ScopedGfxFeatureReporter reporter("DWrite"); decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); if (!createDWriteFactory) { @@ -420,7 +419,6 @@ gfxWindowsPlatform::InitDWriteSupport() Factory::SetDWriteFactory(mDWriteFactory); SetupClearTypeParams(); - reporter.SetSuccessful(); return true; } @@ -669,9 +667,15 @@ gfxWindowsPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray<const char*>& aFontList) { - if (aNextCh == 0xfe0fu) { - aFontList.AppendElement(kFontSegoeUIEmoji); - aFontList.AppendElement(kFontTwemojiMozilla); + EmojiPresentation emoji = GetEmojiPresentation(aCh); + if (emoji != EmojiPresentation::TextOnly) { + if (aNextCh == kVariationSelector16 || + (aNextCh != kVariationSelector15 && + emoji == EmojiPresentation::EmojiDefault)) { + // if char is followed by VS16, try for a color emoji glyph + // XXX: For Win8+ native, aFontList.AppendElement(kFontSegoeUIEmoji); + aFontList.AppendElement(kFontTwemojiMozilla); + } } // Arial is used as the default fallback for system fallback @@ -680,17 +684,7 @@ gfxWindowsPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, if (!IS_IN_BMP(aCh)) { uint32_t p = aCh >> 16; if (p == 1) { // SMP plane - if (aNextCh == 0xfe0eu) { - aFontList.AppendElement(kFontSegoeUISymbol); - aFontList.AppendElement(kFontSegoeUIEmoji); - aFontList.AppendElement(kFontTwemojiMozilla); - } else { - if (aNextCh != 0xfe0fu) { - aFontList.AppendElement(kFontSegoeUIEmoji); - aFontList.AppendElement(kFontTwemojiMozilla); - } - aFontList.AppendElement(kFontSegoeUISymbol); - } + aFontList.AppendElement(kFontSegoeUISymbol); aFontList.AppendElement(kFontEbrima); aFontList.AppendElement(kFontNirmalaUI); aFontList.AppendElement(kFontCambriaMath); @@ -1571,8 +1565,6 @@ gfxWindowsPlatform::InitializeD2DConfig() void gfxWindowsPlatform::InitializeD2D() { - ScopedGfxFeatureReporter d2d1_1("D2D1.1"); - FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D); DeviceManagerDx* dm = DeviceManagerDx::Get(); @@ -1623,7 +1615,6 @@ gfxWindowsPlatform::InitializeD2D() } MOZ_ASSERT(d2d1.IsEnabled()); - d2d1_1.SetSuccessful(); } bool diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index f77d9a87a..f401038fc 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -13,7 +13,6 @@ */ #include "cairo-win32.h" -#include "gfxCrashReporterUtils.h" #include "gfxFontUtils.h" #include "gfxWindowsSurface.h" #include "gfxFont.h" diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build index 227b2b875..e253d7891 100644 --- a/gfx/thebes/moz.build +++ b/gfx/thebes/moz.build @@ -223,12 +223,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': 'DeviceManagerDx.cpp', ] -# We prefer to use ICU for normalization functions, but currently it is only -# available if we're building with the Intl API enabled: -if CONFIG['ENABLE_INTL_API']: - USE_LIBS += [ - 'icu', - ] +# We use ICU for normalization functions +USE_LIBS += [ + 'icu', +] include('/ipc/chromium/chromium-config.mozbuild') |