diff --git a/accessible/src/jsat/Utils.jsm b/accessible/src/jsat/Utils.jsm index 6a8c1188a2e1..ea61d5dbe01e 100644 --- a/accessible/src/jsat/Utils.jsm +++ b/accessible/src/jsat/Utils.jsm @@ -597,7 +597,7 @@ PivotContext.prototype = { while (parent && (parent = parent.parent)) { ancestry.push(parent); } - } catch (e) { + } catch (x) { // A defunct accessible will raise an exception geting parent. Logger.debug('Failed to get parent:', x); } diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 4769f28adb9d..614d40ba2e93 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -274,7 +274,6 @@ pref("ui.dragThresholdY", 25); pref("layers.offmainthreadcomposition.enabled", true); #ifndef MOZ_WIDGET_GONK pref("dom.ipc.tabs.disabled", true); -pref("layers.acceleration.disabled", true); pref("layers.offmainthreadcomposition.async-animations", false); pref("layers.async-video.enabled", false); #else diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 6cad5063ebb0..683dddb17030 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index a904da8d71e9..fdee8dd1cc45 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + @@ -128,7 +128,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index b0dc35ad1fb9..32a33c74ca26 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 6cad5063ebb0..683dddb17030 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame/config.json b/b2g/config/flame/config.json index dfcda774d678..731890aeb2fe 100644 --- a/b2g/config/flame/config.json +++ b/b2g/config/flame/config.json @@ -1,8 +1,8 @@ { "config_version": 2, "tooltool_manifest": "releng-flame.tt", - "mock_target": "mozilla-centos6-i386", - "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "java-1.6.0-openjdk-devel", "git"], + "mock_target": "mozilla-centos6-x86_64", + "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"], "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]], "build_targets": [], "upload_files": [ @@ -30,7 +30,7 @@ "b2g_manifest": "flame.xml", "b2g_manifest_branch": "master", "b2g_manifest_intree": true, - "additional_source_tarballs": [], + "additional_source_tarballs": ["backup-flame.tar.xz"], "gecko_l10n_root": "https://hg.mozilla.org/l10n-central", "gaia": { "l10n": { diff --git a/b2g/config/flame/releng-flame.tt b/b2g/config/flame/releng-flame.tt index 0d4f101c7a37..82a22df9c752 100644 --- a/b2g/config/flame/releng-flame.tt +++ b/b2g/config/flame/releng-flame.tt @@ -1,2 +1,7 @@ [ +{"size": 169226356, +"digest": "f9456848fd661b8be05d6a30607fad4787bcecfe676b53f9a4074653fdda6a377c961038c866c5d83355e3afd89f1a3bd947a142aeaf7dd7d81b6c376185badd", +"filename": "backup-flame.tar.xz", +"algorithm": "sha512" +} ] diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index cb30e848d837..cfb81cf58f1a 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -18,7 +18,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index e725b098f499..7874a4a4beb4 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "c766bc0d49af19f18788ad8ed0542b82db81f1d8", + "revision": "b43fa272b6a254e7b15a79bb7771133a6d950c49", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 37c2ed9c8bcd..0a85af278a31 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 76eb1e7218e9..a468de5a5e2c 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml index 4f919d763cde..d1733a936e07 100644 --- a/b2g/config/inari/sources.xml +++ b/b2g/config/inari/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml index 7b8c00a8fc69..017894273160 100644 --- a/b2g/config/leo/sources.xml +++ b/b2g/config/leo/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml index 4307d4365309..ac1c359f15b4 100644 --- a/b2g/config/mako/sources.xml +++ b/b2g/config/mako/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/mozconfigs/macosx64_gecko/debug b/b2g/config/mozconfigs/macosx64_gecko/debug index a8feab6a1a41..7b8c32a55122 100644 --- a/b2g/config/mozconfigs/macosx64_gecko/debug +++ b/b2g/config/mozconfigs/macosx64_gecko/debug @@ -1,3 +1,4 @@ +. "$topsrcdir/b2g/config/mozconfigs/common" . $topsrcdir/build/macosx/mozconfig.common ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} diff --git a/b2g/config/mozconfigs/macosx64_gecko/nightly b/b2g/config/mozconfigs/macosx64_gecko/nightly index 2be553c4e03d..f3110e67e274 100644 --- a/b2g/config/mozconfigs/macosx64_gecko/nightly +++ b/b2g/config/mozconfigs/macosx64_gecko/nightly @@ -1,3 +1,4 @@ +. "$topsrcdir/b2g/config/mozconfigs/common" . $topsrcdir/build/macosx/mozconfig.common ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL} diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index d0c0fb3b8eaa..d83501e23d35 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/browser/components/shell/src/nsWindowsShellService.cpp b/browser/components/shell/src/nsWindowsShellService.cpp index 9bf46a7807a4..5218e0a6c853 100644 --- a/browser/components/shell/src/nsWindowsShellService.cpp +++ b/browser/components/shell/src/nsWindowsShellService.cpp @@ -753,17 +753,19 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage) { nsresult rv; - nsRefPtr thebesSurface = + RefPtr surface = aImage->GetFrame(imgIContainer::FRAME_FIRST, imgIContainer::FLAG_SYNC_DECODE); - NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); - nsRefPtr thebesImageSurface = - thebesSurface->GetAsReadableARGB32ImageSurface(); - NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE); + // For either of the following formats we want to set the biBitCount member + // of the BITMAPINFOHEADER struct to 32, below. For that value the bitmap + // format defines that the A8/X8 WORDs in the bitmap byte stream be ignored + // for the BI_RGB value we use for the biCompression member. + MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 || + surface->GetFormat() == SurfaceFormat::B8G8R8X8); - RefPtr dataSurface = - thebesImageSurface->CopyToB8G8R8A8DataSourceSurface(); + RefPtr dataSurface = surface->GetDataSurface(); NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE); int32_t width = dataSurface->GetSize().width; diff --git a/content/base/src/moz.build b/content/base/src/moz.build index 2ee705f58a4e..34d83b34bc61 100644 --- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -229,6 +229,7 @@ LOCAL_INCLUDES += [ '/layout/svg', '/layout/xul', '/netwerk/base/src', + '/xpcom/ds', ] if CONFIG['GNU_CC'] and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index b007624811fd..d480a1d3089f 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -124,6 +124,7 @@ #include "nsILineBreaker.h" #include "nsILoadContext.h" #include "nsILoadGroup.h" +#include "nsIMemoryReporter.h" #include "nsIMIMEService.h" #include "nsINode.h" #include "nsINodeInfo.h" diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index c920855daa7a..6e8e1eee5fad 100755 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -100,9 +100,11 @@ #undef free // apparently defined by some windows header, clashing with a free() // method in SkTypes.h +#ifdef USE_SKIA #include "SkiaGLGlue.h" #include "SurfaceStream.h" #include "SurfaceTypes.h" +#endif using mozilla::gl::GLContext; using mozilla::gl::SkiaGLGlue; @@ -900,6 +902,7 @@ CanvasRenderingContext2D::EnsureTarget() SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue(); +#if USE_SKIA if (glue && glue->GetGrContext() && glue->GetGLContext()) { mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format); if (mTarget) { @@ -909,6 +912,7 @@ CanvasRenderingContext2D::EnsureTarget() printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n"); } } +#endif if (!mTarget) { mTarget = layerManager->CreateDrawTarget(size, format); } @@ -4244,12 +4248,14 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder, CanvasLayer::Data data; if (mStream) { +#ifdef USE_SKIA SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue(); if (glue) { data.mGLContext = glue->GetGLContext(); data.mStream = mStream.get(); } +#endif } else { data.mDrawTarget = mTarget; } @@ -4292,7 +4298,9 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder, if (glue) { canvasLayer->SetPreTransactionCallback( CanvasRenderingContext2DUserData::PreTransactionCallback, userData); +#if USE_SKIA data.mGLContext = glue->GetGLContext(); +#endif data.mStream = mStream.get(); data.mTexID = (uint32_t)((uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE)); } diff --git a/content/html/content/src/HTMLInputElement.cpp b/content/html/content/src/HTMLInputElement.cpp index 8e1ba6c331ab..f640ba522d81 100644 --- a/content/html/content/src/HTMLInputElement.cpp +++ b/content/html/content/src/HTMLInputElement.cpp @@ -4674,24 +4674,15 @@ HTMLInputElement::GetValueAsDate(const nsAString& aValue, return false; } - uint32_t endOfYearOffset = 0; - for (; NS_IsAsciiDigit(aValue[endOfYearOffset]); ++endOfYearOffset); - - // The year must be at least 4 digits long. - if (aValue[endOfYearOffset] != '-' || endOfYearOffset < 4) { + uint32_t endOfYearOffset = aValue.Length() - 6; + + if (aValue[endOfYearOffset] != '-' || + aValue[endOfYearOffset + 3] != '-') { return false; } - // Now, we know where is the next '-' and what should be the size of the - // string. - if (aValue[endOfYearOffset + 3] != '-' || - aValue.Length() != 10 + (endOfYearOffset - 4)) { - return false; - } - - nsresult ec; - *aYear = PromiseFlatString(StringHead(aValue, endOfYearOffset)).ToInteger(&ec); - if (NS_FAILED(ec) || *aYear == 0) { + if (!DigitSubStringToNumber(aValue, 0, endOfYearOffset, aYear) || + *aYear < 1) { return false; } diff --git a/content/media/Latency.h b/content/media/Latency.h index 5b91796e3712..0cee37471f3f 100644 --- a/content/media/Latency.h +++ b/content/media/Latency.h @@ -13,7 +13,7 @@ #include "nsIThread.h" #include "mozilla/Monitor.h" #include "nsISupportsImpl.h" -#include "nsObserverService.h" +#include "nsIObserver.h" class AsyncLatencyLogger; class LogEvent; diff --git a/content/media/MediaTaskQueue.h b/content/media/MediaTaskQueue.h index 08680e1fd48c..3cf860c3c5ae 100644 --- a/content/media/MediaTaskQueue.h +++ b/content/media/MediaTaskQueue.h @@ -23,12 +23,14 @@ class SharedThreadPool; // they're received, and are guaranteed to not be executed concurrently. // They may be executed on different threads, and a memory barrier is used // to make this threadsafe for objects that aren't already threadsafe. -class MediaTaskQueue : public AtomicRefCounted { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaTaskQueue) - MediaTaskQueue(TemporaryRef aPool); +class MediaTaskQueue MOZ_FINAL { ~MediaTaskQueue(); +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTaskQueue) + + MediaTaskQueue(TemporaryRef aPool); + nsresult Dispatch(nsIRunnable* aRunnable); // Removes all pending tasks from the task queue, and blocks until diff --git a/content/media/fmp4/PlatformDecoderModule.h b/content/media/fmp4/PlatformDecoderModule.h index 06e439cf47cc..3438c0d62d75 100644 --- a/content/media/fmp4/PlatformDecoderModule.h +++ b/content/media/fmp4/PlatformDecoderModule.h @@ -143,11 +143,13 @@ public: // MediaTaskQueue passed into the PlatformDecoderModules's Create*Decoder() // function. This may not be necessary for platforms with async APIs // for decoding. -class MediaDataDecoder : public AtomicRefCounted { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaDataDecoder) +class MediaDataDecoder { +protected: virtual ~MediaDataDecoder() {}; +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDecoder) + // Initialize the decoder. The decoder should be ready to decode after // this returns. The decoder should do any initialization here, rather // than in its constructor or PlatformDecoderModule::Create*Decoder(), diff --git a/content/media/fmp4/wmf/MFTDecoder.h b/content/media/fmp4/wmf/MFTDecoder.h index 56c76ed9a86d..0451cbd4355a 100644 --- a/content/media/fmp4/wmf/MFTDecoder.h +++ b/content/media/fmp4/wmf/MFTDecoder.h @@ -14,12 +14,14 @@ namespace mozilla { -class MFTDecoder : public AtomicRefCounted { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(MTFDecoder) - MFTDecoder(); +class MFTDecoder MOZ_FINAL { ~MFTDecoder(); +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MFTDecoder) + + MFTDecoder(); + // Creates the MFT. First thing to do as part of setup. // // Params: diff --git a/content/media/gtest/TestVideoTrackEncoder.cpp b/content/media/gtest/TestVideoTrackEncoder.cpp new file mode 100644 index 000000000000..17d8f87b7498 --- /dev/null +++ b/content/media/gtest/TestVideoTrackEncoder.cpp @@ -0,0 +1,296 @@ +/* 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 "gtest/gtest.h" +#include + +#include "mozilla/ArrayUtils.h" +#include "VP8TrackEncoder.h" +#include "ImageContainer.h" +#include "MediaStreamGraph.h" +#include "WebMWriter.h" // TODO: it's weird to include muxer header to get the class definition of VP8 METADATA + +using ::testing::TestWithParam; +using ::testing::Values; + +using namespace mozilla::layers; +using namespace mozilla; + +// A helper object to generate of different YUV planes. +class YUVBufferGenerator { +public: + YUVBufferGenerator() {} + + void Init(const mozilla::gfx::IntSize &aSize) + { + mImageSize = aSize; + + int yPlaneLen = aSize.width * aSize.height; + int cbcrPlaneLen = (yPlaneLen + 1) / 2; + int frameLen = yPlaneLen + cbcrPlaneLen; + + // Generate source buffer. + mSourceBuffer.SetLength(frameLen); + + // Fill Y plane. + memset(mSourceBuffer.Elements(), 0x10, yPlaneLen); + + // Fill Cb/Cr planes. + memset(mSourceBuffer.Elements() + yPlaneLen, 0x80, cbcrPlaneLen); + } + + mozilla::gfx::IntSize GetSize() const + { + return mImageSize; + } + + void Generate(nsTArray > &aImages) + { + aImages.AppendElement(CreateI420Image()); + aImages.AppendElement(CreateNV12Image()); + aImages.AppendElement(CreateNV21Image()); + } + +private: + Image *CreateI420Image() + { + PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin()); + PlanarYCbCrData data; + + const uint32_t yPlaneSize = mImageSize.width * mImageSize.height; + const uint32_t halfWidth = (mImageSize.width + 1) / 2; + const uint32_t halfHeight = (mImageSize.height + 1) / 2; + const uint32_t uvPlaneSize = halfWidth * halfHeight; + + // Y plane. + uint8_t *y = mSourceBuffer.Elements(); + data.mYChannel = y; + data.mYSize.width = mImageSize.width; + data.mYSize.height = mImageSize.height; + data.mYStride = mImageSize.width; + data.mYSkip = 0; + + // Cr plane. + uint8_t *cr = y + yPlaneSize + uvPlaneSize; + data.mCrChannel = cr; + data.mCrSkip = 0; + + // Cb plane + uint8_t *cb = y + yPlaneSize; + data.mCbChannel = cb; + data.mCbSkip = 0; + + // CrCb plane vectors. + data.mCbCrStride = halfWidth; + data.mCbCrSize.width = halfWidth; + data.mCbCrSize.height = halfHeight; + + image->SetData(data); + return image; + } + + Image *CreateNV12Image() + { + PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin()); + PlanarYCbCrData data; + + const uint32_t yPlaneSize = mImageSize.width * mImageSize.height; + const uint32_t halfWidth = (mImageSize.width + 1) / 2; + const uint32_t halfHeight = (mImageSize.height + 1) / 2; + + // Y plane. + uint8_t *y = mSourceBuffer.Elements(); + data.mYChannel = y; + data.mYSize.width = mImageSize.width; + data.mYSize.height = mImageSize.height; + data.mYStride = mImageSize.width; + data.mYSkip = 0; + + // Cr plane. + uint8_t *cr = y + yPlaneSize; + data.mCrChannel = cr; + data.mCrSkip = 1; + + // Cb plane + uint8_t *cb = y + yPlaneSize + 1; + data.mCbChannel = cb; + data.mCbSkip = 1; + + // 4:2:0. + data.mCbCrStride = mImageSize.width; + data.mCbCrSize.width = halfWidth; + data.mCbCrSize.height = halfHeight; + + image->SetData(data); + return image; + } + + Image *CreateNV21Image() + { + PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin()); + PlanarYCbCrData data; + + const uint32_t yPlaneSize = mImageSize.width * mImageSize.height; + const uint32_t halfWidth = (mImageSize.width + 1) / 2; + const uint32_t halfHeight = (mImageSize.height + 1) / 2; + + // Y plane. + uint8_t *y = mSourceBuffer.Elements(); + data.mYChannel = y; + data.mYSize.width = mImageSize.width; + data.mYSize.height = mImageSize.height; + data.mYStride = mImageSize.width; + data.mYSkip = 0; + + // Cr plane. + uint8_t *cr = y + yPlaneSize + 1; + data.mCrChannel = cr; + data.mCrSkip = 1; + + // Cb plane + uint8_t *cb = y + yPlaneSize; + data.mCbChannel = cb; + data.mCbSkip = 1; + + // 4:2:0. + data.mCbCrStride = mImageSize.width; + data.mCbCrSize.width = halfWidth; + data.mCbCrSize.height = halfHeight; + + image->SetData(data); + return image; + } + +private: + mozilla::gfx::IntSize mImageSize; + nsTArray mSourceBuffer; +}; + +struct InitParam { + bool mShouldSucceed; // This parameter should cause success or fail result + int mWidth; // frame width + int mHeight; // frame height + mozilla::TrackRate mTrackRate; // track rate. 90K is the most commond track rate. +}; + +class TestVP8TrackEncoder: public VP8TrackEncoder +{ +public: + ::testing::AssertionResult TestInit(const InitParam &aParam) + { + nsresult result = Init(aParam.mWidth, aParam.mHeight, aParam.mWidth, aParam.mHeight, aParam.mTrackRate); + + if (((NS_FAILED(result) && aParam.mShouldSucceed)) || (NS_SUCCEEDED(result) && !aParam.mShouldSucceed)) + { + return ::testing::AssertionFailure() + << " width = " << aParam.mWidth + << " height = " << aParam.mHeight + << " TrackRate = " << aParam.mTrackRate << "."; + } + else + { + return ::testing::AssertionSuccess(); + } + } +}; + +// Init test +TEST(VP8VideoTrackEncoder, Initialization) +{ + InitParam params[] = { + // Failure cases. + { false, 640, 480, 0 }, // Trackrate should be larger than 1. + { false, 640, 480, -1 }, // Trackrate should be larger than 1. + { false, 0, 0, 90000 }, // Height/ width should be larger than 1. + { false, 0, 1, 90000 }, // Height/ width should be larger than 1. + { false, 1, 0, 90000}, // Height/ width should be larger than 1. + + // Success cases + { true, 640, 480, 90000}, // Standard VGA + { true, 800, 480, 90000}, // Standard WVGA + { true, 960, 540, 90000}, // Standard qHD + { true, 1280, 720, 90000} // Standard HD + }; + + for (size_t i = 0; i < ArrayLength(params); i++) + { + TestVP8TrackEncoder encoder; + EXPECT_TRUE(encoder.TestInit(params[i])); + } +} + +// Get MetaData test +TEST(VP8VideoTrackEncoder, FetchMetaData) +{ + InitParam params[] = { + // Success cases + { true, 640, 480, 90000}, // Standard VGA + { true, 800, 480, 90000}, // Standard WVGA + { true, 960, 540, 90000}, // Standard qHD + { true, 1280, 720, 90000} // Standard HD + }; + + for (size_t i = 0; i < ArrayLength(params); i++) + { + TestVP8TrackEncoder encoder; + EXPECT_TRUE(encoder.TestInit(params[i])); + + nsRefPtr meta = encoder.GetMetadata(); + nsRefPtr vp8Meta(static_cast(meta.get())); + + // METADATA should be depend on how to initiate encoder. + EXPECT_TRUE(vp8Meta->mWidth == params[i].mWidth); + EXPECT_TRUE(vp8Meta->mHeight == params[i].mHeight); + } +} + +// Encode test +TEST(VP8VideoTrackEncoder, FrameEncode) +{ + // Initiate VP8 encoder + TestVP8TrackEncoder encoder; + InitParam param = {true, 640, 480, 90000}; + encoder.TestInit(param); + + // Create YUV images as source. + nsTArray> images; + YUVBufferGenerator generator; + generator.Init(mozilla::gfx::IntSize(640, 480)); + generator.Generate(images); + + // Put generated YUV frame into video segment. + // Duration of each frame is 1 second. + VideoSegment segment; + for (nsTArray>::size_type i = 0; i < images.Length(); i++) + { + nsRefPtr image = images[i]; + segment.AppendFrame(image.forget(), mozilla::TrackTicks(90000), generator.GetSize()); + } + + // track change notification. + encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, 0, segment); + + // Pull Encoded Data back from encoder. + EncodedFrameContainer container; + EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container))); +} + +// EOS test +TEST(VP8VideoTrackEncoder, EncodeComplete) +{ + // Initiate VP8 encoder + TestVP8TrackEncoder encoder; + InitParam param = {true, 640, 480, 90000}; + encoder.TestInit(param); + + // track end notification. + VideoSegment segment; + encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, MediaStreamListener::TRACK_EVENT_ENDED, segment); + + // Pull Encoded Data back from encoder. Since we have sent + // EOS to encoder, encoder.GetEncodedTrack should return + // NS_OK immidiately. + EncodedFrameContainer container; + EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container))); +} diff --git a/content/media/gtest/moz.build b/content/media/gtest/moz.build index 61cd07a6b8af..089894bffb60 100644 --- a/content/media/gtest/moz.build +++ b/content/media/gtest/moz.build @@ -11,6 +11,10 @@ UNIFIED_SOURCES += [ 'TestTrackEncoder.cpp', ] +if CONFIG['MOZ_WEBM_ENCODER']: + UNIFIED_SOURCES += ['TestVideoTrackEncoder.cpp', +] + EXPORT_LIBRARY = True include('/ipc/chromium/chromium-config.mozbuild') diff --git a/content/svg/content/src/SVGFEImageElement.cpp b/content/svg/content/src/SVGFEImageElement.cpp index 662198ad989a..ac9f0bf282a4 100644 --- a/content/svg/content/src/SVGFEImageElement.cpp +++ b/content/svg/content/src/SVGFEImageElement.cpp @@ -8,6 +8,8 @@ #include "mozilla/EventStates.h" #include "mozilla/dom/SVGFEImageElementBinding.h" #include "mozilla/dom/SVGFilterElement.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "nsContentUtils.h" #include "nsLayoutUtils.h" #include "nsSVGUtils.h" @@ -211,22 +213,16 @@ SVGFEImageElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance, currentRequest->GetImage(getter_AddRefs(imageContainer)); } - nsRefPtr currentFrame; + RefPtr image; if (imageContainer) { - currentFrame = - imageContainer->GetFrame(imgIContainer::FRAME_CURRENT, - imgIContainer::FLAG_SYNC_DECODE); + image = imageContainer->GetFrame(imgIContainer::FRAME_CURRENT, + imgIContainer::FLAG_SYNC_DECODE); } - if (!currentFrame) { + if (!image) { return FilterPrimitiveDescription(PrimitiveType::Empty); } - gfxPlatform* platform = gfxPlatform::GetPlatform(); - DrawTarget* dt = platform->ScreenReferenceDrawTarget(); - RefPtr image = - platform->GetSourceSurfaceForSurface(dt, currentFrame); - IntSize nativeSize; imageContainer->GetWidth(&nativeSize.width); imageContainer->GetHeight(&nativeSize.height); diff --git a/dom/apps/src/AppsUtils.jsm b/dom/apps/src/AppsUtils.jsm index 8581553b9572..d9bc3195b7ca 100644 --- a/dom/apps/src/AppsUtils.jsm +++ b/dom/apps/src/AppsUtils.jsm @@ -9,17 +9,17 @@ const Cc = Components.classes; const Ci = Components.interfaces; const Cr = Components.results; -Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/osfile.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/WebappOSUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Promise.jsm"); -XPCOMUtils.defineLazyServiceGetter(this, "NetworkUtil", - "@mozilla.org/network/util;1", - "nsINetUtil"); +XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", + "resource://gre/modules/FileUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "WebappOSUtils", + "resource://gre/modules/WebappOSUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm"); @@ -342,7 +342,8 @@ this.AppsUtils = { checkManifestContentType(aInstallOrigin, aWebappOrigin, aContentType) { let hadCharset = { }; let charset = { }; - let contentType = NetworkUtil.parseContentType(aContentType, charset, hadCharset); + let netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil); + let contentType = netutil.parseContentType(aContentType, charset, hadCharset); if (aInstallOrigin != aWebappOrigin && contentType != "application/x-web-app-manifest+json") { return false; diff --git a/dom/bluetooth/BluetoothProfileController.h b/dom/bluetooth/BluetoothProfileController.h index fac94151e4ca..faf5131572ae 100644 --- a/dom/bluetooth/BluetoothProfileController.h +++ b/dom/bluetooth/BluetoothProfileController.h @@ -8,7 +8,7 @@ #define mozilla_dom_bluetooth_bluetoothprofilecontroller_h__ #include "BluetoothUuid.h" -#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" #include "nsAutoPtr.h" #include "nsITimer.h" @@ -57,10 +57,12 @@ class BluetoothProfileManagerBase; class BluetoothReplyRunnable; typedef void (*BluetoothProfileControllerCallback)(); -class BluetoothProfileController : public RefCounted +class BluetoothProfileController MOZ_FINAL { + ~BluetoothProfileController(); + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(BluetoothProfileController) + NS_INLINE_DECL_REFCOUNTING(BluetoothProfileController) /** * @param aConnect: If it's a connect request, the value should be set * to true. For disconnect request, set it to false. @@ -83,7 +85,6 @@ public: BluetoothProfileControllerCallback aCallback, uint16_t aServiceUuid, uint32_t aCod = 0); - ~BluetoothProfileController(); /** * The controller starts connecting/disconnecting profiles one by one diff --git a/dom/bluetooth/bluedroid/BluetoothSocket.cpp b/dom/bluetooth/bluedroid/BluetoothSocket.cpp index b1d1a8c25983..32974b889eed 100644 --- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp +++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp @@ -91,9 +91,39 @@ public: , mIOLoop(nullptr) , mFd(aFd) , mShuttingDownOnIOThread(false) + , mChannel(0) + , mAuth(false) + , mEncrypt(false) { } + DroidSocketImpl(BluetoothSocket* aConsumer, + int aChannel, bool aAuth, bool aEncrypt) + : mConsumer(aConsumer) + , mReadMsgForClientFd(false) + , mIOLoop(nullptr) + , mFd(-1) + , mShuttingDownOnIOThread(false) + , mChannel(aChannel) + , mAuth(aAuth) + , mEncrypt(aEncrypt) + { } + + DroidSocketImpl(BluetoothSocket* aConsumer, const nsAString& aDeviceAddress, + int aChannel, bool aAuth, bool aEncrypt) + : mConsumer(aConsumer) + , mReadMsgForClientFd(false) + , mIOLoop(nullptr) + , mFd(-1) + , mShuttingDownOnIOThread(false) + , mDeviceAddress(aDeviceAddress) + , mChannel(aChannel) + , mAuth(aAuth) + , mEncrypt(aEncrypt) + { + MOZ_ASSERT(!mDeviceAddress.IsEmpty()); + } + ~DroidSocketImpl() { MOZ_ASSERT(NS_IsMainThread()); @@ -134,6 +164,9 @@ public: mShuttingDownOnIOThread = true; } + void Connect(); + void Listen(); + void SetUpIO(bool aWrite) { MOZ_ASSERT(!mIOLoop); @@ -236,6 +269,11 @@ private: * If true, do not requeue whatever task we're running */ bool mShuttingDownOnIOThread; + + nsString mDeviceAddress; + int mChannel; + bool mAuth; + bool mEncrypt; }; template @@ -368,19 +406,60 @@ private: UnixSocketRawData* mData; }; -class SocketSetUpIOTask : public Task +class DroidSocketImplTask : public CancelableTask { - virtual void Run() +public: + DroidSocketImpl* GetDroidSocketImpl() const + { + return mDroidSocketImpl; + } + void Cancel() MOZ_OVERRIDE + { + mDroidSocketImpl = nullptr; + } + bool IsCanceled() const + { + return !mDroidSocketImpl; + } +protected: + DroidSocketImplTask(DroidSocketImpl* aDroidSocketImpl) + : mDroidSocketImpl(aDroidSocketImpl) + { + MOZ_ASSERT(mDroidSocketImpl); + } +private: + DroidSocketImpl* mDroidSocketImpl; +}; + +class SocketConnectTask : public DroidSocketImplTask +{ +public: + SocketConnectTask(DroidSocketImpl* aDroidSocketImpl) + : DroidSocketImplTask(aDroidSocketImpl) + { } + + void Run() MOZ_OVERRIDE { MOZ_ASSERT(!NS_IsMainThread()); - mImpl->SetUpIO(mWrite); + MOZ_ASSERT(!IsCanceled()); + GetDroidSocketImpl()->Connect(); } +}; - DroidSocketImpl* mImpl; - bool mWrite; +class SocketListenTask : public DroidSocketImplTask +{ public: - SocketSetUpIOTask(DroidSocketImpl* aImpl, bool aWrite) - : mImpl(aImpl), mWrite(aWrite) { } + SocketListenTask(DroidSocketImpl* aDroidSocketImpl) + : DroidSocketImplTask(aDroidSocketImpl) + { } + + void Run() MOZ_OVERRIDE + { + MOZ_ASSERT(!NS_IsMainThread()); + if (!IsCanceled()) { + GetDroidSocketImpl()->Listen(); + } + } }; class SocketConnectClientFdTask : public Task @@ -396,6 +475,78 @@ public: SocketConnectClientFdTask(DroidSocketImpl* aImpl) : mImpl(aImpl) { } }; +void +DroidSocketImpl::Connect() +{ + MOZ_ASSERT(sBluetoothSocketInterface); + + bt_bdaddr_t remoteBdAddress; + StringToBdAddressType(mDeviceAddress, &remoteBdAddress); + + // TODO: uuid as argument + int fd = -1; + bt_status_t status = + sBluetoothSocketInterface->connect(&remoteBdAddress, + BTSOCK_RFCOMM, + UUID_OBEX_OBJECT_PUSH, + mChannel, + &fd, + (BTSOCK_FLAG_ENCRYPT * mEncrypt) | + (BTSOCK_FLAG_AUTH * mAuth)); + NS_ENSURE_TRUE_VOID(status == BT_STATUS_SUCCESS); + NS_ENSURE_TRUE_VOID(fd >= 0); + + mFd = fd; + + MOZ_ASSERT(!mIOLoop); + mIOLoop = MessageLoopForIO::current(); + + // Set up a read watch + mIOLoop->WatchFileDescriptor(mFd.get(), + true, + MessageLoopForIO::WATCH_READ, + &mReadWatcher, + this); + // Set up a write watch + mIOLoop->WatchFileDescriptor(mFd.get(), + false, + MessageLoopForIO::WATCH_WRITE, + &mWriteWatcher, + this); +} + +void +DroidSocketImpl::Listen() +{ + MOZ_ASSERT(sBluetoothSocketInterface); + + // TODO: uuid and service name as arguments + + int fd = -1; + bt_status_t status = + sBluetoothSocketInterface->listen(BTSOCK_RFCOMM, + "OBEX Object Push", + UUID_OBEX_OBJECT_PUSH, + mChannel, + &fd, + (BTSOCK_FLAG_ENCRYPT * mEncrypt) | + (BTSOCK_FLAG_AUTH * mAuth)); + NS_ENSURE_TRUE_VOID(status == BT_STATUS_SUCCESS); + NS_ENSURE_TRUE_VOID(fd >= 0); + + mFd = fd; + + MOZ_ASSERT(!mIOLoop); + mIOLoop = MessageLoopForIO::current(); + + // Set up a read watch + mIOLoop->WatchFileDescriptor(mFd.get(), + true, + MessageLoopForIO::WATCH_READ, + &mReadWatcher, + this); +} + ssize_t DroidSocketImpl::ReadMsg(int aFd, void *aBuffer, size_t aLength) { @@ -580,65 +731,30 @@ BluetoothSocket::CloseDroidSocket() } bool -BluetoothSocket::CreateDroidSocket(int aFd) +BluetoothSocket::Connect(const nsAString& aDeviceAddress, int aChannel) { MOZ_ASSERT(NS_IsMainThread()); NS_ENSURE_FALSE(mImpl, false); - mImpl = new DroidSocketImpl(this, aFd); + mIsServer = false; + mImpl = new DroidSocketImpl(this, aDeviceAddress, aChannel, mAuth, mEncrypt); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, - new SocketSetUpIOTask(mImpl, !mIsServer)); + new SocketConnectTask(mImpl)); return true; } -bool -BluetoothSocket::Connect(const nsAString& aDeviceAddress, int aChannel) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!aDeviceAddress.IsEmpty()); - NS_ENSURE_TRUE(sBluetoothSocketInterface, false); - - bt_bdaddr_t remoteBdAddress; - StringToBdAddressType(aDeviceAddress, &remoteBdAddress); - - // TODO: uuid as argument - int fd; - NS_ENSURE_TRUE(BT_STATUS_SUCCESS == - sBluetoothSocketInterface->connect(&remoteBdAddress, - BTSOCK_RFCOMM, - UUID_OBEX_OBJECT_PUSH, - aChannel, - &fd, - (mAuth << 1) | mEncrypt), - false); - NS_ENSURE_TRUE(fd >= 0, false); - - mIsServer = false; - return CreateDroidSocket(fd); -} - bool BluetoothSocket::Listen(int aChannel) { MOZ_ASSERT(NS_IsMainThread()); - NS_ENSURE_TRUE(sBluetoothSocketInterface, false); - - // TODO: uuid and service name as arguments - nsAutoCString serviceName("OBEX Object Push"); - int fd; - NS_ENSURE_TRUE(BT_STATUS_SUCCESS == - sBluetoothSocketInterface->listen(BTSOCK_RFCOMM, - serviceName.get(), - UUID_OBEX_OBJECT_PUSH, - aChannel, - &fd, - (mAuth << 1) | mEncrypt), - false); - NS_ENSURE_TRUE(fd >= 0, false); + NS_ENSURE_FALSE(mImpl, false); mIsServer = true; - return CreateDroidSocket(fd); + mImpl = new DroidSocketImpl(this, aChannel, mAuth, mEncrypt); + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, + new SocketListenTask(mImpl)); + return true; } bool diff --git a/dom/bluetooth/bluedroid/BluetoothSocket.h b/dom/bluetooth/bluedroid/BluetoothSocket.h index aa6f290de94e..eda668f80a9e 100644 --- a/dom/bluetooth/bluedroid/BluetoothSocket.h +++ b/dom/bluetooth/bluedroid/BluetoothSocket.h @@ -77,7 +77,6 @@ private: bool mIsServer; int mReceivedSocketInfoLength; - bool CreateDroidSocket(int aFd); bool ReceiveSocketInfo(nsAutoPtr& aMessage); }; diff --git a/dom/browser-element/BrowserElementPanning.js b/dom/browser-element/BrowserElementPanning.js index f1edacfa1d01..dabed75e3a02 100644 --- a/dom/browser-element/BrowserElementPanning.js +++ b/dom/browser-element/BrowserElementPanning.js @@ -29,6 +29,27 @@ const ContentPanning = { hybridEvents: false, init: function cp_init() { + // If APZ is enabled, we do active element handling in C++ + // (see widget/xpwidgets/ActiveElementManager.h), and panning + // itself in APZ, so we don't need to handle any touch events here. + if (docShell.asyncPanZoomEnabled === false) { + this._setupListenersForPanning(); + } + + addEventListener("unload", + this._unloadHandler.bind(this), + /* useCapture = */ false, + /* wantsUntrusted = */ false); + + addMessageListener("Viewport:Change", this._recvViewportChange.bind(this)); + addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this)); + addEventListener("visibilitychange", this._handleVisibilityChange.bind(this)); + kObservedEvents.forEach((topic) => { + Services.obs.addObserver(this, topic, false); + }); + }, + + _setupListenersForPanning: function cp_setupListenersForPanning() { var events; try { content.document.createEvent('TouchEvent'); @@ -60,18 +81,6 @@ const ContentPanning = { this.handleEvent.bind(this), /* useCapture = */ false); }.bind(this)); - - addEventListener("unload", - this._unloadHandler.bind(this), - /* useCapture = */ false, - /* wantsUntrusted = */ false); - - addMessageListener("Viewport:Change", this._recvViewportChange.bind(this)); - addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this)); - addEventListener("visibilitychange", this._handleVisibilityChange.bind(this)); - kObservedEvents.forEach((topic) => { - Services.obs.addObserver(this, topic, false); - }); }, handleEvent: function cp_handleEvent(evt) { @@ -195,8 +204,7 @@ const ContentPanning = { // We prevent start events to avoid sending a focus event at the end of this // touch series. See bug 889717. - if (docShell.asyncPanZoomEnabled === false && - (this.panning || this.preventNextClick)) { + if ((this.panning || this.preventNextClick)) { evt.preventDefault(); } }, @@ -235,7 +243,7 @@ const ContentPanning = { let view = target.ownerDocument ? target.ownerDocument.defaultView : target; view.addEventListener('click', this, true, true); - } else if (docShell.asyncPanZoomEnabled === false) { + } else { // We prevent end events to avoid sending a focus event. See bug 889717. evt.preventDefault(); } @@ -284,18 +292,15 @@ const ContentPanning = { return; } - // If the application is not managed by the AsyncPanZoomController, then - // scroll manually. - if (docShell.asyncPanZoomEnabled === false) { - this.scrollCallback(delta.scale(-1)); - } + // Scroll manually. + this.scrollCallback(delta.scale(-1)); if (!this.panning && isPan) { this.panning = true; this._activationTimer.cancel(); } - if (this.panning && docShell.asyncPanZoomEnabled === false) { + if (this.panning) { // Only do this when we're actually executing a pan gesture. // Otherwise synthetic mouse events will be canceled. evt.stopPropagation(); @@ -592,9 +597,8 @@ const ContentPanning = { delete this.primaryPointerId; this._activationTimer.cancel(); - // If there is a scroll action but the application is not managed by - // the AsyncPanZoom controller, let's do a manual kinetic panning action. - if (this.panning && docShell.asyncPanZoomEnabled === false) { + // If there is a scroll action, let's do a manual kinetic panning action. + if (this.panning) { KineticPanning.start(this); } }, diff --git a/dom/camera/CameraControlImpl.cpp b/dom/camera/CameraControlImpl.cpp index 320920f84a16..b6ead6ea76e7 100644 --- a/dom/camera/CameraControlImpl.cpp +++ b/dom/camera/CameraControlImpl.cpp @@ -284,12 +284,15 @@ CameraControlImpl::OnError(CameraControlListener::CameraErrorContext aContext, "StartCamera", "StopCamera", "AutoFocus", + "StartFaceDetection", + "StopFaceDetection", "TakePicture", "StartRecording", "StopRecording", "SetConfiguration", "StartPreview", "StopPreview", + "ResumeContinuousFocus", "Unspecified" }; if (static_cast(aError) < sizeof(error) / sizeof(error[0]) && @@ -414,30 +417,25 @@ CameraControlImpl::SetConfiguration(const Configuration& aConfig) } nsresult -CameraControlImpl::AutoFocus(bool aCancelExistingCall) +CameraControlImpl::AutoFocus() { class Message : public ControlMessage { public: Message(CameraControlImpl* aCameraControl, - CameraControlListener::CameraErrorContext aContext, - bool aCancelExistingCall) + CameraControlListener::CameraErrorContext aContext) : ControlMessage(aCameraControl, aContext) - , mCancelExistingCall(aCancelExistingCall) { } nsresult RunImpl() MOZ_OVERRIDE { - return mCameraControl->AutoFocusImpl(mCancelExistingCall); + return mCameraControl->AutoFocusImpl(); } - - protected: - bool mCancelExistingCall; }; return mCameraThread->Dispatch( - new Message(this, CameraControlListener::kInAutoFocus, aCancelExistingCall), NS_DISPATCH_NORMAL); + new Message(this, CameraControlListener::kInAutoFocus), NS_DISPATCH_NORMAL); } nsresult @@ -611,6 +609,28 @@ CameraControlImpl::StopPreview() new Message(this, CameraControlListener::kInStopPreview), NS_DISPATCH_NORMAL); } +nsresult +CameraControlImpl::ResumeContinuousFocus() +{ + class Message : public ControlMessage + { + public: + Message(CameraControlImpl* aCameraControl, + CameraControlListener::CameraErrorContext aContext) + : ControlMessage(aCameraControl, aContext) + { } + + nsresult + RunImpl() MOZ_OVERRIDE + { + return mCameraControl->ResumeContinuousFocusImpl(); + } + }; + + return mCameraThread->Dispatch( + new Message(this, CameraControlListener::kInResumeContinuousFocus), NS_DISPATCH_NORMAL); +} + nsresult CameraControlImpl::Stop() { diff --git a/dom/camera/CameraControlImpl.h b/dom/camera/CameraControlImpl.h index 8aaff7e4a4d9..f5d4b252ecb5 100644 --- a/dom/camera/CameraControlImpl.h +++ b/dom/camera/CameraControlImpl.h @@ -19,8 +19,6 @@ #include "DeviceStorageFileDescriptor.h" #include "CameraControlListener.h" -class DeviceStorageFileDescriptor; - namespace mozilla { namespace layers { @@ -42,13 +40,14 @@ public: virtual nsresult SetConfiguration(const Configuration& aConfig) MOZ_OVERRIDE; virtual nsresult StartPreview() MOZ_OVERRIDE; virtual nsresult StopPreview() MOZ_OVERRIDE; - virtual nsresult AutoFocus(bool aCancelExistingCall) MOZ_OVERRIDE; + virtual nsresult AutoFocus() MOZ_OVERRIDE; virtual nsresult StartFaceDetection() MOZ_OVERRIDE; virtual nsresult StopFaceDetection() MOZ_OVERRIDE; virtual nsresult TakePicture() MOZ_OVERRIDE; virtual nsresult StartRecording(DeviceStorageFileDescriptor* aFileDescriptor, const StartRecordingOptions* aOptions) MOZ_OVERRIDE; virtual nsresult StopRecording() MOZ_OVERRIDE; + virtual nsresult ResumeContinuousFocus() MOZ_OVERRIDE; already_AddRefed GetRecorderProfileManager(); uint32_t GetCameraId() { return mCameraId; } @@ -102,13 +101,14 @@ protected: virtual nsresult SetConfigurationImpl(const Configuration& aConfig) = 0; virtual nsresult StartPreviewImpl() = 0; virtual nsresult StopPreviewImpl() = 0; - virtual nsresult AutoFocusImpl(bool aCancelExistingCall) = 0; + virtual nsresult AutoFocusImpl() = 0; virtual nsresult StartFaceDetectionImpl() = 0; virtual nsresult StopFaceDetectionImpl() = 0; virtual nsresult TakePictureImpl() = 0; virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor, const StartRecordingOptions* aOptions) = 0; virtual nsresult StopRecordingImpl() = 0; + virtual nsresult ResumeContinuousFocusImpl() = 0; virtual nsresult PushParametersImpl() = 0; virtual nsresult PullParametersImpl() = 0; virtual already_AddRefed GetRecorderProfileManagerImpl() = 0; diff --git a/dom/camera/CameraControlListener.h b/dom/camera/CameraControlListener.h index b5687273c4ec..ec1ee20395cf 100644 --- a/dom/camera/CameraControlListener.h +++ b/dom/camera/CameraControlListener.h @@ -95,6 +95,7 @@ public: kInSetConfiguration, kInStartPreview, kInStopPreview, + kInResumeContinuousFocus, kInUnspecified }; enum CameraError diff --git a/dom/camera/DOMCameraControl.cpp b/dom/camera/DOMCameraControl.cpp index f49307cdb76a..9ca4fef004e4 100644 --- a/dom/camera/DOMCameraControl.cpp +++ b/dom/camera/DOMCameraControl.cpp @@ -844,6 +844,29 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration, aRv = mCameraControl->SetConfiguration(config); } +class ImmediateErrorCallback : public nsRunnable +{ +public: + ImmediateErrorCallback(CameraErrorCallback* aCallback, const nsAString& aMessage) + : mCallback(aCallback) + , mMessage(aMessage) + { } + + NS_IMETHODIMP + Run() + { + MOZ_ASSERT(NS_IsMainThread()); + ErrorResult ignored; + mCallback->Call(mMessage, ignored); + return NS_OK; + } + +protected: + nsRefPtr mCallback; + nsString mMessage; +}; + + void nsDOMCameraControl::AutoFocus(CameraAutoFocusCallback& aOnSuccess, const Optional >& aOnError, @@ -851,17 +874,16 @@ nsDOMCameraControl::AutoFocus(CameraAutoFocusCallback& aOnSuccess, { MOZ_ASSERT(mCameraControl); - nsRefPtr cb = mAutoFocusOnSuccessCb.forget(); - bool cancel = false; + nsRefPtr cb = mAutoFocusOnSuccessCb; if (cb) { - // we have a callback, which means we're already in the process of - // auto-focusing--cancel the old callback - nsRefPtr ecb = mAutoFocusOnErrorCb.forget(); - if (ecb) { - ErrorResult ignored; - ecb->Call(NS_LITERAL_STRING("Interrupted"), ignored); + if (aOnError.WasPassed()) { + // There is already a call to AutoFocus() in progress, abort this new one + // and invoke the error callback (if one was passed in). + NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(), + NS_LITERAL_STRING("AutoFocusAlreadyInProgress"))); } - cancel = true; + aRv = NS_ERROR_FAILURE; + return; } mAutoFocusOnSuccessCb = &aOnSuccess; @@ -870,7 +892,7 @@ nsDOMCameraControl::AutoFocus(CameraAutoFocusCallback& aOnSuccess, mAutoFocusOnErrorCb = &aOnError.Value(); } - aRv = mCameraControl->AutoFocus(cancel); + aRv = mCameraControl->AutoFocus(); } void @@ -897,11 +919,11 @@ nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions, nsRefPtr cb = mTakePictureOnSuccessCb; if (cb) { - // There is already a call to TakePicture() in progress, abort this one and - // invoke the error callback (if one was passed in). if (aOnError.WasPassed()) { - ErrorResult ignored; - aOnError.Value().Call(NS_LITERAL_STRING("TakePictureAlreadyInProgress"), ignored); + // There is already a call to TakePicture() in progress, abort this new + // one and invoke the error callback (if one was passed in). + NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(), + NS_LITERAL_STRING("TakePictureAlreadyInProgress"))); } aRv = NS_ERROR_FAILURE; return; @@ -958,6 +980,13 @@ nsDOMCameraControl::ReleaseHardware(const OptionalStop(); } +void +nsDOMCameraControl::ResumeContinuousFocus(ErrorResult& aRv) +{ + MOZ_ASSERT(mCameraControl); + aRv = mCameraControl->ResumeContinuousFocus(); +} + void nsDOMCameraControl::Shutdown() { diff --git a/dom/camera/DOMCameraControl.h b/dom/camera/DOMCameraControl.h index a27ac25486ec..d4fa80730250 100644 --- a/dom/camera/DOMCameraControl.h +++ b/dom/camera/DOMCameraControl.h @@ -128,6 +128,7 @@ public: void ReleaseHardware(const dom::Optional >& aOnSuccess, const dom::Optional >& aOnError, ErrorResult& aRv); + void ResumeContinuousFocus(ErrorResult& aRv); virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; diff --git a/dom/camera/DOMCameraManager.cpp b/dom/camera/DOMCameraManager.cpp index 7265546073de..d57b0a1dd718 100644 --- a/dom/camera/DOMCameraManager.cpp +++ b/dom/camera/DOMCameraManager.cpp @@ -9,7 +9,7 @@ #include "nsPIDOMWindow.h" #include "mozilla/Services.h" #include "nsContentPermissionHelper.h" -#include "nsObserverService.h" +#include "nsIObserverService.h" #include "nsIPermissionManager.h" #include "DOMCameraControl.h" #include "nsDOMClassInfo.h" diff --git a/dom/camera/FallbackCameraControl.cpp b/dom/camera/FallbackCameraControl.cpp index 2b732454dc3e..16ac853ee77c 100644 --- a/dom/camera/FallbackCameraControl.cpp +++ b/dom/camera/FallbackCameraControl.cpp @@ -58,19 +58,20 @@ public: protected: ~FallbackCameraControl(); - virtual nsresult StartPreviewImpl() { return NS_ERROR_FAILURE; } - virtual nsresult StopPreviewImpl() { return NS_ERROR_FAILURE; } - virtual nsresult AutoFocusImpl(bool aCancelExistingCall) { return NS_ERROR_FAILURE; } - virtual nsresult StartFaceDetectionImpl() { return NS_ERROR_FAILURE; } - virtual nsresult StopFaceDetectionImpl() { return NS_ERROR_FAILURE; } - virtual nsresult TakePictureImpl() { return NS_ERROR_FAILURE; } + virtual nsresult StartPreviewImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult StopPreviewImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult AutoFocusImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult StartFaceDetectionImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult StopFaceDetectionImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult TakePictureImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor, - const StartRecordingOptions* aOptions = nullptr) + const StartRecordingOptions* aOptions = nullptr) MOZ_OVERRIDE { return NS_ERROR_FAILURE; } - virtual nsresult StopRecordingImpl() { return NS_ERROR_FAILURE; } - virtual nsresult PushParametersImpl() { return NS_ERROR_FAILURE; } - virtual nsresult PullParametersImpl() { return NS_ERROR_FAILURE; } - virtual already_AddRefed GetRecorderProfileManagerImpl() { return nullptr; } + virtual nsresult StopRecordingImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult ResumeContinuousFocusImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult PushParametersImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual nsresult PullParametersImpl() MOZ_OVERRIDE { return NS_ERROR_FAILURE; } + virtual already_AddRefed GetRecorderProfileManagerImpl() MOZ_OVERRIDE { return nullptr; } private: FallbackCameraControl(const FallbackCameraControl&) MOZ_DELETE; diff --git a/dom/camera/GonkCameraControl.cpp b/dom/camera/GonkCameraControl.cpp index 366c1ca45d5b..c15a7af7caa8 100644 --- a/dom/camera/GonkCameraControl.cpp +++ b/dom/camera/GonkCameraControl.cpp @@ -564,15 +564,12 @@ nsGonkCameraControl::PausePreview() } nsresult -nsGonkCameraControl::AutoFocusImpl(bool aCancelExistingCall) +nsGonkCameraControl::AutoFocusImpl() { MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); RETURN_IF_NO_CAMERA_HW(); - if (aCancelExistingCall) { - if (mCameraHw.get()) { - mCameraHw->CancelAutoFocus(); - } - } + + DOM_CAMERA_LOGI("Starting auto focus\n"); if (mCameraHw->AutoFocus() != OK) { return NS_ERROR_FAILURE; @@ -1045,6 +1042,23 @@ nsGonkCameraControl::StopRecordingImpl() return NS_DispatchToMainThread(new RecordingComplete(mVideoFile), NS_DISPATCH_NORMAL); } +nsresult +nsGonkCameraControl::ResumeContinuousFocusImpl() +{ + MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); + RETURN_IF_NO_CAMERA_HW(); + + DOM_CAMERA_LOGI("Resuming continuous autofocus\n"); + + // see + // http://developer.android.com/reference/android/hardware/Camera.Parameters.html#FOCUS_MODE_CONTINUOUS_PICTURE + if (NS_WARN_IF(mCameraHw->CancelAutoFocus() != OK)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + void nsGonkCameraControl::OnAutoFocusComplete(bool aSuccess) { diff --git a/dom/camera/GonkCameraControl.h b/dom/camera/GonkCameraControl.h index 195ba284b387..2691bc7ba6d6 100644 --- a/dom/camera/GonkCameraControl.h +++ b/dom/camera/GonkCameraControl.h @@ -105,13 +105,14 @@ protected: virtual nsresult StartPreviewImpl() MOZ_OVERRIDE; virtual nsresult StopPreviewImpl() MOZ_OVERRIDE; - virtual nsresult AutoFocusImpl(bool aCancelExistingCall) MOZ_OVERRIDE; + virtual nsresult AutoFocusImpl() MOZ_OVERRIDE; virtual nsresult StartFaceDetectionImpl() MOZ_OVERRIDE; virtual nsresult StopFaceDetectionImpl() MOZ_OVERRIDE; virtual nsresult TakePictureImpl() MOZ_OVERRIDE; virtual nsresult StartRecordingImpl(DeviceStorageFileDescriptor* aFileDescriptor, const StartRecordingOptions* aOptions = nullptr) MOZ_OVERRIDE; virtual nsresult StopRecordingImpl() MOZ_OVERRIDE; + virtual nsresult ResumeContinuousFocusImpl() MOZ_OVERRIDE; virtual nsresult PushParametersImpl() MOZ_OVERRIDE; virtual nsresult PullParametersImpl() MOZ_OVERRIDE; virtual already_AddRefed GetRecorderProfileManagerImpl() MOZ_OVERRIDE; diff --git a/dom/camera/GonkCameraHwMgr.cpp b/dom/camera/GonkCameraHwMgr.cpp index 9cee62c33840..ba7464c30047 100644 --- a/dom/camera/GonkCameraHwMgr.cpp +++ b/dom/camera/GonkCameraHwMgr.cpp @@ -292,11 +292,11 @@ GonkCameraHardware::AutoFocus() return mCamera->autoFocus(); } -void +int GonkCameraHardware::CancelAutoFocus() { DOM_CAMERA_LOGI("%s\n", __func__); - mCamera->cancelAutoFocus(); + return mCamera->cancelAutoFocus(); } int diff --git a/dom/camera/GonkCameraHwMgr.h b/dom/camera/GonkCameraHwMgr.h index 30e322f81b2a..d66fdc5bb232 100644 --- a/dom/camera/GonkCameraHwMgr.h +++ b/dom/camera/GonkCameraHwMgr.h @@ -78,7 +78,7 @@ public: virtual int GetSensorOrientation(uint32_t aType = RAW_SENSOR_ORIENTATION); virtual int AutoFocus(); - virtual void CancelAutoFocus(); + virtual int CancelAutoFocus(); virtual int StartFaceDetection(); virtual int StopFaceDetection(); virtual int TakePicture(); diff --git a/dom/camera/ICameraControl.h b/dom/camera/ICameraControl.h index 76aa07f16929..fd225ca0e440 100644 --- a/dom/camera/ICameraControl.h +++ b/dom/camera/ICameraControl.h @@ -10,7 +10,7 @@ #include "nsAutoPtr.h" #include "nsISupportsImpl.h" -class DeviceStorageFileDescriptor; +struct DeviceStorageFileDescriptor; class nsIFile; @@ -152,13 +152,14 @@ public: virtual nsresult StartPreview() = 0; virtual nsresult StopPreview() = 0; - virtual nsresult AutoFocus(bool aCancelExistingCall) = 0; + virtual nsresult AutoFocus() = 0; virtual nsresult TakePicture() = 0; virtual nsresult StartRecording(DeviceStorageFileDescriptor *aFileDescriptor, const StartRecordingOptions* aOptions = nullptr) = 0; virtual nsresult StopRecording() = 0; virtual nsresult StartFaceDetection() = 0; virtual nsresult StopFaceDetection() = 0; + virtual nsresult ResumeContinuousFocus() = 0; virtual nsresult Set(uint32_t aKey, const nsAString& aValue) = 0; virtual nsresult Get(uint32_t aKey, nsAString& aValue) = 0; diff --git a/dom/devicestorage/DeviceStorage.h b/dom/devicestorage/DeviceStorage.h index 3fe4ee00f261..04ec4af5e757 100644 --- a/dom/devicestorage/DeviceStorage.h +++ b/dom/devicestorage/DeviceStorage.h @@ -321,13 +321,7 @@ private: friend class WatchFileEvent; friend class DeviceStorageRequest; - class VolumeNameCache : public mozilla::RefCounted - { - public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeNameCache) - nsTArray mVolumeNames; - }; - static mozilla::StaticRefPtr sVolumeNameCache; + static mozilla::StaticAutoPtr> sVolumeNameCache; #ifdef MOZ_WIDGET_GONK nsString mLastStatus; diff --git a/dom/devicestorage/DeviceStorageFileDescriptor.h b/dom/devicestorage/DeviceStorageFileDescriptor.h index 36749f4245c3..d9fed28d8c8e 100644 --- a/dom/devicestorage/DeviceStorageFileDescriptor.h +++ b/dom/devicestorage/DeviceStorageFileDescriptor.h @@ -9,11 +9,9 @@ #include "mozilla/ipc/FileDescriptor.h" -class DeviceStorageFileDescriptor MOZ_FINAL - : public mozilla::RefCounted +struct DeviceStorageFileDescriptor MOZ_FINAL { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(DeviceStorageFileDescriptor) + NS_INLINE_DECL_REFCOUNTING(DeviceStorageFileDescriptor) nsRefPtr mDSFile; mozilla::ipc::FileDescriptor mFileDescriptor; }; diff --git a/dom/devicestorage/DeviceStorageRequestChild.h b/dom/devicestorage/DeviceStorageRequestChild.h index 83eae6cbff21..d0fcee804448 100644 --- a/dom/devicestorage/DeviceStorageRequestChild.h +++ b/dom/devicestorage/DeviceStorageRequestChild.h @@ -9,7 +9,7 @@ #include "mozilla/dom/devicestorage/PDeviceStorageRequestChild.h" class DeviceStorageFile; -class DeviceStorageFileDescriptor; +struct DeviceStorageFileDescriptor; namespace mozilla { namespace dom { diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index 228afef8a5e1..3d4e0d0e6768 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -115,15 +115,16 @@ DeviceStorageUsedSpaceCache::CreateOrGet() return sDeviceStorageUsedSpaceCache; } -TemporaryRef +already_AddRefed DeviceStorageUsedSpaceCache::GetCacheEntry(const nsAString& aStorageName) { - nsTArray >::size_type numEntries = mCacheEntries.Length(); - nsTArray >::index_type i; + nsTArray>::size_type numEntries = mCacheEntries.Length(); + nsTArray>::index_type i; for (i = 0; i < numEntries; i++) { - RefPtr cacheEntry = mCacheEntries[i]; + nsRefPtr& cacheEntry = mCacheEntries[i]; if (cacheEntry->mStorageName.Equals(aStorageName)) { - return cacheEntry; + nsRefPtr addRefedCacheEntry = cacheEntry; + return addRefedCacheEntry.forget(); } } return nullptr; @@ -149,7 +150,7 @@ DeviceStorageUsedSpaceCache::AccumUsedSizes(const nsAString& aStorageName, uint64_t* aMusicSoFar, uint64_t* aTotalSoFar) { - RefPtr cacheEntry = GetCacheEntry(aStorageName); + nsRefPtr cacheEntry = GetCacheEntry(aStorageName); if (!cacheEntry || cacheEntry->mDirty) { return NS_ERROR_NOT_AVAILABLE; } @@ -174,7 +175,7 @@ DeviceStorageUsedSpaceCache::SetUsedSizes(const nsAString& aStorageName, uint64_t aMusicSize, uint64_t aTotalUsedSize) { - RefPtr cacheEntry = GetCacheEntry(aStorageName); + nsRefPtr cacheEntry = GetCacheEntry(aStorageName); if (!cacheEntry) { cacheEntry = new CacheEntry; cacheEntry->mStorageName = aStorageName; @@ -189,10 +190,10 @@ DeviceStorageUsedSpaceCache::SetUsedSizes(const nsAString& aStorageName, cacheEntry->mDirty = false; } -class GlobalDirs : public RefCounted +class GlobalDirs { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(GlobalDirs) + NS_INLINE_DECL_REFCOUNTING(GlobalDirs) #if !defined(MOZ_WIDGET_GONK) nsCOMPtr pictures; nsCOMPtr videos; @@ -3179,16 +3180,15 @@ nsDOMDeviceStorage::Shutdown() obs->RemoveObserver(this, "disk-space-watcher"); } -StaticRefPtr - nsDOMDeviceStorage::sVolumeNameCache; +StaticAutoPtr> nsDOMDeviceStorage::sVolumeNameCache; // static void nsDOMDeviceStorage::GetOrderedVolumeNames( nsDOMDeviceStorage::VolumeNameArray &aVolumeNames) { - if (sVolumeNameCache && sVolumeNameCache->mVolumeNames.Length() > 0) { - aVolumeNames.AppendElements(sVolumeNameCache->mVolumeNames); + if (sVolumeNameCache && sVolumeNameCache->Length() > 0) { + aVolumeNames.AppendElements(*sVolumeNameCache); return; } #ifdef MOZ_WIDGET_GONK @@ -3209,8 +3209,8 @@ nsDOMDeviceStorage::GetOrderedVolumeNames( if (aVolumeNames.IsEmpty()) { aVolumeNames.AppendElement(EmptyString()); } - sVolumeNameCache = new VolumeNameCache; - sVolumeNameCache->mVolumeNames.AppendElements(aVolumeNames); + sVolumeNameCache = new nsTArray; + sVolumeNameCache->AppendElements(aVolumeNames); } // static diff --git a/dom/devicestorage/nsDeviceStorage.h b/dom/devicestorage/nsDeviceStorage.h index b77fbc780a1d..6623702060b6 100644 --- a/dom/devicestorage/nsDeviceStorage.h +++ b/dom/devicestorage/nsDeviceStorage.h @@ -29,7 +29,6 @@ class nsPIDOMWindow; #include "prtime.h" #include "DeviceStorage.h" #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h" -#include "mozilla/RefPtr.h" #include "mozilla/StaticPtr.h" namespace mozilla { @@ -80,7 +79,7 @@ public: NS_IMETHOD Run() MOZ_OVERRIDE { - mozilla::RefPtr cacheEntry; + nsRefPtr cacheEntry; cacheEntry = mCache->GetCacheEntry(mStorageName); if (cacheEntry) { cacheEntry->mDirty = true; @@ -120,10 +119,10 @@ public: private: friend class InvalidateRunnable; - class CacheEntry : public mozilla::RefCounted + struct CacheEntry { - public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(DeviceStorageUsedSpaceCache::CacheEntry) + NS_INLINE_DECL_REFCOUNTING(DeviceStorageUsedSpaceCache::CacheEntry) + bool mDirty; nsString mStorageName; int64_t mFreeBytes; @@ -132,9 +131,9 @@ private: uint64_t mMusicUsedSize; uint64_t mTotalUsedSize; }; - mozilla::TemporaryRef GetCacheEntry(const nsAString& aStorageName); + already_AddRefed GetCacheEntry(const nsAString& aStorageName); - nsTArray > mCacheEntries; + nsTArray> mCacheEntries; nsCOMPtr mIOThread; diff --git a/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl index 25b14fe1a725..aab632943001 100644 --- a/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl +++ b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl @@ -12,7 +12,7 @@ interface nsIDOMEventListener; interface nsIFile; %{C++ -class DeviceStorageFileDescriptor; +struct DeviceStorageFileDescriptor; %} [ptr] native DeviceStorageFdPtr(DeviceStorageFileDescriptor); diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index e040a7d6acf9..90237db206ec 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -50,6 +50,7 @@ using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/Comp using mozilla::CSSPoint from "Units.h"; using mozilla::CSSToScreenScale from "Units.h"; using mozilla::CommandInt from "mozilla/EventForwards.h"; +using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/layers/GeckoContentController.h"; namespace mozilla { namespace dom { @@ -410,11 +411,10 @@ child: HandleLongTapUp(CSSPoint point, ScrollableLayerGuid aGuid); /** - * Notifies the child that the parent has begun or finished transforming - * the visible child content area. Useful for showing/hiding scrollbars. + * Notifies the child about various APZ state changes. + * See GeckoContentController::NotifyAPZStateChange() for details. */ - NotifyTransformBegin(ViewID aViewId); - NotifyTransformEnd(ViewID aViewId); + NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg); /** * Sending an activate message moves focus to the child. diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 46dbb252120c..e99acd76806f 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -74,6 +74,7 @@ #include "mozilla/gfx/Matrix.h" #include "UnitTransforms.h" #include "ClientLayerManager.h" +#include "ActiveElementManager.h" #include "nsColorPickerProxy.h" @@ -687,6 +688,7 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t , mContextMenuHandled(false) , mWaitingTouchListeners(false) , mIgnoreKeyPressEvent(false) + , mActiveElementManager(new ActiveElementManager()) { if (!sActiveDurationMsSet) { Preferences::AddIntVarCache(&sActiveDurationMs, @@ -1730,23 +1732,49 @@ TabChild::RecvHandleLongTapUp(const CSSPoint& aPoint, const ScrollableLayerGuid& } bool -TabChild::RecvNotifyTransformBegin(const ViewID& aViewId) +TabChild::RecvNotifyAPZStateChange(const ViewID& aViewId, + const APZStateChange& aChange, + const int& aArg) { - nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); - nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf); - if (scrollbarOwner) { - scrollbarOwner->ScrollbarActivityStarted(); + switch (aChange) + { + case APZStateChange::TransformBegin: + { + nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); + nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf); + if (scrollbarOwner) { + scrollbarOwner->ScrollbarActivityStarted(); + } + break; } - return true; -} - -bool -TabChild::RecvNotifyTransformEnd(const ViewID& aViewId) -{ - nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); - nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf); - if (scrollbarOwner) { - scrollbarOwner->ScrollbarActivityStopped(); + case APZStateChange::TransformEnd: + { + nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); + nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf); + if (scrollbarOwner) { + scrollbarOwner->ScrollbarActivityStopped(); + } + break; + } + case APZStateChange::StartTouch: + { + mActiveElementManager->HandleTouchStart(aArg); + break; + } + case APZStateChange::StartPanning: + { + mActiveElementManager->HandlePanStart(); + break; + } + case APZStateChange::EndTouch: + { + mActiveElementManager->HandleTouchEnd(aArg); + break; + } + default: + // APZStateChange has a 'sentinel' value, and the compiler complains + // if an enumerator is not handled and there is no 'default' case. + break; } return true; } @@ -1951,6 +1979,10 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent, return true; } + if (aEvent.message == NS_TOUCH_START && localEvent.touches.Length() > 0) { + mActiveElementManager->SetTargetElement(localEvent.touches[0]->Target()); + } + nsCOMPtr outerWindow = do_GetInterface(WebNavigation()); nsCOMPtr innerWindow = outerWindow->GetCurrentInnerWindow(); diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 6d1f4cce5f36..13e3ebd94cd5 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -42,6 +42,10 @@ namespace layout { class RenderFrameChild; } +namespace widget { +class ActiveElementManager; +} + namespace dom { class TabChild; @@ -228,6 +232,7 @@ class TabChild : public PBrowserChild, typedef mozilla::dom::ClonedMessageData ClonedMessageData; typedef mozilla::layout::RenderFrameChild RenderFrameChild; typedef mozilla::layout::ScrollingBehavior ScrollingBehavior; + typedef mozilla::widget::ActiveElementManager ActiveElementManager; public: /** @@ -296,8 +301,9 @@ public: const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE; virtual bool RecvHandleLongTapUp(const CSSPoint& aPoint, const mozilla::layers::ScrollableLayerGuid& aGuid) MOZ_OVERRIDE; - virtual bool RecvNotifyTransformBegin(const ViewID& aViewId) MOZ_OVERRIDE; - virtual bool RecvNotifyTransformEnd(const ViewID& aViewId) MOZ_OVERRIDE; + virtual bool RecvNotifyAPZStateChange(const ViewID& aViewId, + const APZStateChange& aChange, + const int& aArg) MOZ_OVERRIDE; virtual bool RecvActivate() MOZ_OVERRIDE; virtual bool RecvDeactivate() MOZ_OVERRIDE; virtual bool RecvMouseEvent(const nsString& aType, @@ -544,6 +550,7 @@ private: void FireSingleTapEvent(LayoutDevicePoint aPoint); bool mIgnoreKeyPressEvent; + nsRefPtr mActiveElementManager; DISALLOW_EVIL_CONSTRUCTORS(TabChild); }; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 9e81cb8ac019..b556eea4236b 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -554,17 +554,12 @@ void TabParent::HandleLongTapUp(const CSSPoint& aPoint, } } -void TabParent::NotifyTransformBegin(ViewID aViewId) +void TabParent::NotifyAPZStateChange(ViewID aViewId, + APZStateChange aChange, + int aArg) { if (!mIsDestroyed) { - unused << SendNotifyTransformBegin(aViewId); - } -} - -void TabParent::NotifyTransformEnd(ViewID aViewId) -{ - if (!mIsDestroyed) { - unused << SendNotifyTransformEnd(aViewId); + unused << SendNotifyAPZStateChange(aViewId, aChange, aArg); } } diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 63bc651fb234..c90f851cf615 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -212,8 +212,9 @@ public: void HandleLongTapUp(const CSSPoint& aPoint, int32_t aModifiers, const ScrollableLayerGuid& aGuid); - void NotifyTransformBegin(ViewID aViewId); - void NotifyTransformEnd(ViewID aViewId); + void NotifyAPZStateChange(ViewID aViewId, + APZStateChange aChange, + int aArg); void Activate(); void Deactivate(); diff --git a/dom/media/MediaManager.h b/dom/media/MediaManager.h index b1b9bc6a2c2e..052bd72a69b4 100644 --- a/dom/media/MediaManager.h +++ b/dom/media/MediaManager.h @@ -11,7 +11,7 @@ #include "nsGlobalWindow.h" #include "nsClassHashtable.h" #include "nsRefPtrHashtable.h" -#include "nsObserverService.h" +#include "nsIObserver.h" #include "nsIPrefService.h" #include "nsIPrefBranch.h" diff --git a/dom/system/gonk/AutoMounter.cpp b/dom/system/gonk/AutoMounter.cpp index 250fc1a0b41b..e2fe392e6fee 100644 --- a/dom/system/gonk/AutoMounter.cpp +++ b/dom/system/gonk/AutoMounter.cpp @@ -163,12 +163,12 @@ private: /***************************************************************************/ -class AutoMounter : public RefCounted +class AutoMounter { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(AutoMounter) + NS_INLINE_DECL_REFCOUNTING(AutoMounter) - typedef nsTArray > VolumeArray; + typedef nsTArray> VolumeArray; AutoMounter() : mResponseCallback(new AutoMounterResponseCallback), @@ -692,21 +692,21 @@ UsbCableEventIOThread() * **************************************************************************/ -class UsbCableObserver : public SwitchObserver, - public RefCounted +class UsbCableObserver MOZ_FINAL : public SwitchObserver { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(UsbCableObserver) - UsbCableObserver() - { - RegisterSwitchObserver(SWITCH_USB, this); - } - ~UsbCableObserver() { UnregisterSwitchObserver(SWITCH_USB, this); } +public: + NS_INLINE_DECL_REFCOUNTING(UsbCableObserver) + + UsbCableObserver() + { + RegisterSwitchObserver(SWITCH_USB, this); + } + virtual void Notify(const SwitchEvent& aEvent) { DBG("UsbCable switch device: %d state: %s\n", diff --git a/dom/system/gonk/Volume.h b/dom/system/gonk/Volume.h index 9eb5302c964b..7bb3d32bfe43 100644 --- a/dom/system/gonk/Volume.h +++ b/dom/system/gonk/Volume.h @@ -9,7 +9,7 @@ #include "nsIVolume.h" #include "nsString.h" #include "mozilla/Observer.h" -#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" #include "nsWhitespaceTokenizer.h" namespace mozilla { @@ -24,10 +24,11 @@ namespace system { * ***************************************************************************/ -class Volume : public RefCounted +class Volume MOZ_FINAL { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(Volume) + NS_INLINE_DECL_REFCOUNTING(Volume) + Volume(const nsCSubstring& aVolumeName); typedef long STATE; // States are now defined in nsIVolume.idl diff --git a/dom/system/gonk/VolumeCommand.h b/dom/system/gonk/VolumeCommand.h index 8041185fdb56..a2e7c69b82b0 100644 --- a/dom/system/gonk/VolumeCommand.h +++ b/dom/system/gonk/VolumeCommand.h @@ -6,6 +6,7 @@ #define mozilla_system_volumecommand_h__ #include "nsString.h" +#include "nsISupportsImpl.h" #include "mozilla/RefPtr.h" #include #include @@ -32,15 +33,16 @@ class VolumeCommand; * ***************************************************************************/ -class VolumeResponseCallback : public RefCounted +class VolumeResponseCallback { +protected: + virtual ~VolumeResponseCallback() {} + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeResponseCallback) + NS_INLINE_DECL_REFCOUNTING(VolumeResponseCallback) VolumeResponseCallback() : mResponseCode(0), mPending(false) {} - virtual ~VolumeResponseCallback() {} - bool Done() const { // Response codes from the 200, 400, and 500 series all indicated that @@ -106,10 +108,14 @@ private: * ***************************************************************************/ -class VolumeCommand : public RefCounted +class VolumeCommand { +protected: + virtual ~VolumeCommand() {} + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeCommand) + NS_INLINE_DECL_REFCOUNTING(VolumeCommand) + VolumeCommand(VolumeResponseCallback* aCallback) : mBytesConsumed(0), mCallback(aCallback) @@ -124,8 +130,6 @@ public: SetCmd(aCommand); } - virtual ~VolumeCommand() {} - void SetCmd(const nsACString& aCommand) { mCmd.Truncate(); diff --git a/dom/system/gonk/VolumeManager.h b/dom/system/gonk/VolumeManager.h index c3f34316ada1..6dd4ebda78bd 100644 --- a/dom/system/gonk/VolumeManager.h +++ b/dom/system/gonk/VolumeManager.h @@ -11,7 +11,7 @@ #include "base/message_loop.h" #include "mozilla/FileUtils.h" #include "mozilla/Observer.h" -#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" #include "nsString.h" #include "nsTArray.h" @@ -73,16 +73,16 @@ namespace system { * ***************************************************************************/ -class VolumeManager : public MessageLoopForIO::LineWatcher, - public RefCounted +class VolumeManager MOZ_FINAL : public MessageLoopForIO::LineWatcher { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeManager) + virtual ~VolumeManager(); - typedef nsTArray > VolumeArray; +public: + NS_INLINE_DECL_REFCOUNTING(VolumeManager) + + typedef nsTArray> VolumeArray; VolumeManager(); - virtual ~VolumeManager(); //----------------------------------------------------------------------- // diff --git a/dom/system/gonk/VolumeServiceIOThread.h b/dom/system/gonk/VolumeServiceIOThread.h index 835ccf64be25..0c2a6a62f24a 100644 --- a/dom/system/gonk/VolumeServiceIOThread.h +++ b/dom/system/gonk/VolumeServiceIOThread.h @@ -19,14 +19,15 @@ class nsVolumeService; * class, but whose methods are called from IOThread. */ class VolumeServiceIOThread : public VolumeManager::StateObserver, - public Volume::EventObserver, - public RefCounted + public Volume::EventObserver { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(VolumeServiceIOThread) - VolumeServiceIOThread(nsVolumeService* aVolumeService); ~VolumeServiceIOThread(); +public: + NS_INLINE_DECL_REFCOUNTING(VolumeServiceIOThread) + + VolumeServiceIOThread(nsVolumeService* aVolumeService); + private: void UpdateAllVolumes(); diff --git a/dom/webidl/CameraControl.webidl b/dom/webidl/CameraControl.webidl index 7ec6c79c6760..ed7bdddc72f7 100644 --- a/dom/webidl/CameraControl.webidl +++ b/dom/webidl/CameraControl.webidl @@ -334,6 +334,20 @@ interface CameraControl : MediaStream void setConfiguration(optional CameraConfiguration configuration, optional CameraSetConfigurationCallback onSuccess, optional CameraErrorCallback onError); + + /* if focusMode is set to either 'continuous-picture' or 'continuous-video', + then calling autoFocus() will trigger its onSuccess callback immediately + if the camera was either successfully focused, or if no focus could be + acquired; if the focus acquisition is still in progress, the onSuccess + callback will be invoked later, its argument indicating success or + failure. + + once autoFocus() is called with a continuous autofocus mode set, the + continuous autofocus process is stopped and focus is locked in the + current state until this method is called. + */ + [Throws] + void resumeContinuousFocus(); }; /* The coordinates of a point, relative to the camera sensor, of the center of diff --git a/dom/xbl/test/file_bug821850.xhtml b/dom/xbl/test/file_bug821850.xhtml index 61b86212e7f6..b3ccc160a48f 100644 --- a/dom/xbl/test/file_bug821850.xhtml +++ b/dom/xbl/test/file_bug821850.xhtml @@ -53,11 +53,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=821850 is(typeof bound.wrappedJSObject.unexposedProperty, 'undefined', "Unexposed property should not be defined in content"); - // Check that here document.QueryInterface works - ok("QueryInterface" in document, - "Should have a document.QueryInterface here"); - is(document.QueryInterface(Components.interfaces.nsIDOMDocument), - document, "Should be able to QI the document"); + // Check that here HTMLImageElement.QueryInterface works + var img = document.querySelector("img"); + ok("QueryInterface" in img, + "Should have a img.QueryInterface here"); + is(img.QueryInterface(Components.interfaces.nsIImageLoadingContent), + img, "Should be able to QI the image"); // Make sure standard constructors work right in the presence of // sandboxPrototype and Xray-resolved constructors. @@ -289,6 +290,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=821850
Bound element
Bound element
+
 
diff --git a/editor/libeditor/html/tests/browserscope/lib/richtext2/richtext2/tests/insert.py b/editor/libeditor/html/tests/browserscope/lib/richtext2/richtext2/tests/insert.py index edf602ad712a..a2e79c27c863 100644 --- a/editor/libeditor/html/tests/browserscope/lib/richtext2/richtext2/tests/insert.py +++ b/editor/libeditor/html/tests/browserscope/lib/richtext2/richtext2/tests/insert.py @@ -165,34 +165,34 @@ INSERT_TESTS = { 'tests': [ { 'id': 'IIMG:url_TEXT-1_SC', 'rte1-id': 'a-insertimage-0', - 'desc': 'Insert image with URL "http://goo.gl/bar.png"', - 'value': 'http://goo.gl/bar.png', + 'desc': 'Insert image with URL "bar.png"', + 'value': 'bar.png', 'checkAttrs': True, 'pad': 'foo^bar', - 'expected': [ 'foo|bar', - 'foo^bar' ] }, + 'expected': [ 'foo|bar', + 'foo^bar' ] }, { 'id': 'IIMG:url_IMG-1_SO', 'desc': 'Change existing image to new URL, selection on ', - 'value': 'http://baz.com/quz.png', + 'value': 'quz.png', 'checkAttrs': True, - 'pad': 'foo{}bar', - 'expected': [ 'foo|bar', - 'foo^bar' ] }, + 'pad': 'foo{}bar', + 'expected': [ 'foo|bar', + 'foo^bar' ] }, { 'id': 'IIMG:url_SPAN-IMG-1_SO', 'desc': 'Change existing image to new URL, selection in text surrounding ', - 'value': 'http://baz.com/quz.png', + 'value': 'quz.png', 'checkAttrs': True, - 'pad': 'foo[]bar', - 'expected': [ 'foo|bar', - 'foo^bar' ] }, + 'pad': 'foo[]bar', + 'expected': [ 'foo|bar', + 'foo^bar' ] }, { 'id': 'IIMG:._SPAN-IMG-1_SO', 'desc': 'Remove existing image or URL, selection on ', 'value': '', 'checkAttrs': True, - 'pad': 'foo{}bar', + 'pad': 'foo{}bar', 'expected': [ 'foo^bar', 'foo|bar', 'foo^bar', @@ -203,7 +203,7 @@ INSERT_TESTS = { 'desc': 'Remove existing image or URL, selection in text surrounding ', 'value': '', 'checkAttrs': True, - 'pad': 'foo[]bar', + 'pad': 'foo[]bar', 'expected': [ 'foo^bar', 'foo|bar', 'foo^bar', diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index d77df2a558b2..a0aa2143e648 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -416,7 +416,7 @@ public: */ virtual TemporaryRef GetDataSurface(); - DebugOnly mIsMapped; + bool mIsMapped; }; /* This is an abstract object that accepts path segments. */ diff --git a/gfx/2d/DataSurfaceHelpers.h b/gfx/2d/DataSurfaceHelpers.h index 61231e9fb1f1..b0ac1e8cb150 100644 --- a/gfx/2d/DataSurfaceHelpers.h +++ b/gfx/2d/DataSurfaceHelpers.h @@ -25,19 +25,21 @@ CopySurfaceDataToPackedArray(uint8_t* aSrc, uint8_t* aDst, IntSize aSrcSize, /** * Convert aSurface to a packed buffer in BGRA format. The pixel data is - * returned in a buffer allocated with new uint8_t[]. + * returned in a buffer allocated with new uint8_t[]. The caller then has + * ownership of the buffer and is responsible for delete[]'ing it. */ uint8_t* SurfaceToPackedBGRA(DataSourceSurface *aSurface); /** * Convert aSurface to a packed buffer in BGR format. The pixel data is - * returned in a buffer allocated with new uint8_t[]. + * returned in a buffer allocated with new uint8_t[]. The caller then has + * ownership of the buffer and is responsible for delete[]'ing it. * * This function is currently only intended for use with surfaces of format - * SurfaceFormat::B8G8R8X8 since the X components of the pixel data are simply - * dropped (no attempt is made to un-pre-multiply alpha from the color - * components). + * SurfaceFormat::B8G8R8X8 since the X components of the pixel data (if any) + * are simply dropped (no attempt is made to un-pre-multiply alpha from the + * color components). */ uint8_t* SurfaceToPackedBGR(DataSourceSurface *aSurface); diff --git a/gfx/gl/SharedSurfaceGL.cpp b/gfx/gl/SharedSurfaceGL.cpp index 011c2690b01d..1aab56f26a2c 100644 --- a/gfx/gl/SharedSurfaceGL.cpp +++ b/gfx/gl/SharedSurfaceGL.cpp @@ -24,6 +24,8 @@ SharedSurface_GL::ProdCopy(SharedSurface_GL* src, SharedSurface_GL* dest, { GLContext* gl = src->GL(); + gl->MakeCurrent(); + if (src->AttachType() == AttachmentType::Screen && dest->AttachType() == AttachmentType::Screen) { diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index d65bc3080e34..2afaed7b1201 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -26,6 +26,7 @@ #include "mozilla/layers/CompositorTypes.h" #include "FrameMetrics.h" #include "FilterSupport.h" +#include "mozilla/layers/GeckoContentController.h" #ifdef _MSC_VER #pragma warning( disable : 4800 ) @@ -1069,6 +1070,16 @@ struct ParamTraits } }; +typedef mozilla::layers::GeckoContentController::APZStateChange APZStateChange; + +template <> +struct ParamTraits + : public ContiguousTypedEnumSerializer< + APZStateChange, + APZStateChange::TransformBegin, + APZStateChange::APZStateChangeSentinel> +{}; + } /* namespace IPC */ #endif /* __GFXMESSAGEUTILS_H__ */ diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index f255ea076517..d869d1c4f766 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -137,18 +137,12 @@ enum SurfaceInitMode /** * A base class for a platform-dependent helper for use by TextureHost. */ -class CompositorBackendSpecificData : public RefCounted +class CompositorBackendSpecificData { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositorBackendSpecificData) - CompositorBackendSpecificData() - { - MOZ_COUNT_CTOR(CompositorBackendSpecificData); - } - virtual ~CompositorBackendSpecificData() - { - MOZ_COUNT_DTOR(CompositorBackendSpecificData); - } + NS_INLINE_DECL_REFCOUNTING(CompositorBackendSpecificData) + +protected: + virtual ~CompositorBackendSpecificData() {} }; /** @@ -195,21 +189,20 @@ public: * The target and viewport methods can be called before any DrawQuad call and * affect any subsequent DrawQuad calls. */ -class Compositor : public RefCounted +class Compositor { +protected: + virtual ~Compositor() {} + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(Compositor) + NS_INLINE_DECL_REFCOUNTING(Compositor) + Compositor(PCompositorParent* aParent = nullptr) : mCompositorID(0) , mDiagnosticTypes(DIAGNOSTIC_NONE) , mParent(aParent) , mScreenRotation(ROTATION_0) { - MOZ_COUNT_CTOR(Compositor); - } - virtual ~Compositor() - { - MOZ_COUNT_DTOR(Compositor); } virtual TemporaryRef CreateDataTextureSource(TextureFlags aFlags = 0) = 0; diff --git a/gfx/layers/Effects.h b/gfx/layers/Effects.h index c46880393dc9..ebf20035caa5 100644 --- a/gfx/layers/Effects.h +++ b/gfx/layers/Effects.h @@ -37,15 +37,18 @@ namespace layers { * to the compositor by the compositable host as a parameter to DrawQuad. */ -struct Effect : public RefCounted +struct Effect { - MOZ_DECLARE_REFCOUNTED_TYPENAME(Effect) + NS_INLINE_DECL_REFCOUNTING(Effect) + Effect(EffectTypes aType) : mType(aType) {} EffectTypes mType; + virtual void PrintInfo(nsACString& aTo, const char* aPrefix) = 0; + +protected: virtual ~Effect() {} - virtual void PrintInfo(nsACString& aTo, const char* aPrefix) =0; }; // Render from a texture diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 4f915ae3cc85..16f58c0517f9 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -68,14 +68,16 @@ class TextureClientData; * where we have a different way of interfacing with the textures - in terms of * drawing into the compositable and/or passing its contents to the compostior. */ -class CompositableClient : public AtomicRefCounted +class CompositableClient { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableClient) - CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = 0); - +protected: virtual ~CompositableClient(); +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableClient) + + CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = 0); + virtual TextureInfo GetTextureInfo() const = 0; LayersBackend GetCompositorBackendType() const; diff --git a/gfx/layers/client/SimpleTextureClientPool.h b/gfx/layers/client/SimpleTextureClientPool.h index fb402718e196..ccdf2295a4ee 100644 --- a/gfx/layers/client/SimpleTextureClientPool.h +++ b/gfx/layers/client/SimpleTextureClientPool.h @@ -19,14 +19,8 @@ namespace layers { class ISurfaceAllocator; -class SimpleTextureClientPool : public RefCounted +class SimpleTextureClientPool { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(SimpleTextureClientPool) - - SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, - ISurfaceAllocator *aAllocator); - ~SimpleTextureClientPool() { for (auto it = mOutstandingTextureClients.begin(); it != mOutstandingTextureClients.end(); ++it) { @@ -34,6 +28,12 @@ public: } } +public: + NS_INLINE_DECL_REFCOUNTING(SimpleTextureClientPool) + + SimpleTextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, + ISurfaceAllocator *aAllocator); + /** * If a TextureClient is AutoRecycled, when the last reference is * released this object will be automatically return to the pool as diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 35173c827c11..28163507d1d5 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -75,23 +75,17 @@ namespace layers { * TextureClient's data until the compositor side confirmed that it is safe to * deallocte or recycle the it. */ -class TextureChild : public PTextureChild - , public AtomicRefCounted +class TextureChild MOZ_FINAL : public PTextureChild { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureChild) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TextureChild) + TextureChild() : mForwarder(nullptr) , mTextureData(nullptr) , mTextureClient(nullptr) , mIPCOpen(false) { - MOZ_COUNT_CTOR(TextureChild); - } - - ~TextureChild() - { - MOZ_COUNT_DTOR(TextureChild); } bool Recv__delete__() MOZ_OVERRIDE; diff --git a/gfx/layers/client/TextureClientPool.h b/gfx/layers/client/TextureClientPool.h index a9ebbe0433ce..ff2c707bce60 100644 --- a/gfx/layers/client/TextureClientPool.h +++ b/gfx/layers/client/TextureClientPool.h @@ -18,13 +18,15 @@ namespace layers { class ISurfaceAllocator; -class TextureClientPool : public RefCounted +class TextureClientPool MOZ_FINAL { + ~TextureClientPool(); + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureClientPool) + NS_INLINE_DECL_REFCOUNTING(TextureClientPool) + TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aSize, ISurfaceAllocator *aAllocator); - ~TextureClientPool(); /** * Gets an allocated TextureClient of size and format that are determined diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h index 8b02d4b13d79..732b0724184e 100644 --- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -47,11 +47,13 @@ class ClientLayerManager; // A class to help implement copy-on-write semantics for shared tiles. -class gfxSharedReadLock : public AtomicRefCounted { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(gfxSharedReadLock) +class gfxSharedReadLock { +protected: virtual ~gfxSharedReadLock() {} +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxSharedReadLock) + virtual int32_t ReadLock() = 0; virtual int32_t ReadUnlock() = 0; virtual int32_t GetReadCount() = 0; diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp index eecb5f9c175d..f14de3171d8c 100644 --- a/gfx/layers/composite/APZCTreeManager.cpp +++ b/gfx/layers/composite/APZCTreeManager.cpp @@ -779,7 +779,6 @@ APZCTreeManager::HandOffFling(AsyncPanZoomController* aPrev, ScreenPoint aVeloci next->TakeOverFling(transformedVelocity); } - bool APZCTreeManager::FlushRepaintsForOverscrollHandoffChain() { @@ -796,6 +795,30 @@ APZCTreeManager::FlushRepaintsForOverscrollHandoffChain() return true; } +bool +APZCTreeManager::CanBePanned(AsyncPanZoomController* aApzc) +{ + MonitorAutoLock lock(mTreeLock); // to access mOverscrollHandoffChain + + // Find |aApzc| in the handoff chain. + uint32_t i; + for (i = 0; i < mOverscrollHandoffChain.length(); ++i) { + if (mOverscrollHandoffChain[i] == aApzc) { + break; + } + } + + // See whether any APZC in the handoff chain starting from |aApzc| + // has room to be panned. + for (uint32_t j = i; j < mOverscrollHandoffChain.length(); ++j) { + if (mOverscrollHandoffChain[j]->IsPannable()) { + return true; + } + } + + return false; +} + bool APZCTreeManager::HitTestAPZC(const ScreenIntPoint& aPoint) { diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h index 1cc4aad6470c..5d3e2e12f437 100644 --- a/gfx/layers/composite/APZCTreeManager.h +++ b/gfx/layers/composite/APZCTreeManager.h @@ -214,6 +214,7 @@ public: * Sets allowed touch behavior values for current touch-session for specific apzc (determined by guid). * Should be invoked by the widget. Each value of the aValues arrays corresponds to the different * touch point that is currently active. + * Must be called after receiving the TOUCH_START event that starts the touch-session. */ void SetAllowedTouchBehavior(const ScrollableLayerGuid& aGuid, const nsTArray& aValues); @@ -271,6 +272,13 @@ public: bool FlushRepaintsForOverscrollHandoffChain(); + /** + * Determine whether |aApzc|, or any APZC along its overscroll handoff chain, + * has room to be panned. + * Expects the overscroll handoff chain to already be built. + */ + bool CanBePanned(AsyncPanZoomController* aApzc); + protected: // Protected destructor, to discourage deletion outside of Release(): virtual ~APZCTreeManager(); diff --git a/gfx/layers/composite/AsyncCompositionManager.h b/gfx/layers/composite/AsyncCompositionManager.h index 6e60ac3e8c4d..0ce44feef8d9 100644 --- a/gfx/layers/composite/AsyncCompositionManager.h +++ b/gfx/layers/composite/AsyncCompositionManager.h @@ -61,22 +61,21 @@ struct ViewTransform { * short circuit that stuff to directly affect layers as they are composited, * for example, off-main thread animation, async video, async pan/zoom. */ -class AsyncCompositionManager MOZ_FINAL : public RefCounted +class AsyncCompositionManager MOZ_FINAL { friend class AutoResolveRefLayers; public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(AsyncCompositionManager) + NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager) + AsyncCompositionManager(LayerManagerComposite* aManager) : mLayerManager(aManager) , mIsFirstPaint(false) , mLayersUpdated(false) , mReadyForCompose(true) { - MOZ_COUNT_CTOR(AsyncCompositionManager); } ~AsyncCompositionManager() { - MOZ_COUNT_DTOR(AsyncCompositionManager); } /** diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index f43ffb9f2fc8..10c42745dcf9 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -56,18 +56,18 @@ struct EffectChain; /** * A base class for doing CompositableHost and platform dependent task on TextureHost. */ -class CompositableBackendSpecificData : public RefCounted +class CompositableBackendSpecificData { +protected: + virtual ~CompositableBackendSpecificData() { } + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableBackendSpecificData) + NS_INLINE_DECL_REFCOUNTING(CompositableBackendSpecificData) + CompositableBackendSpecificData() { - MOZ_COUNT_CTOR(CompositableBackendSpecificData); - } - virtual ~CompositableBackendSpecificData() - { - MOZ_COUNT_DTOR(CompositableBackendSpecificData); } + virtual void SetCompositor(Compositor* aCompositor) {} virtual void ClearData() { @@ -124,14 +124,15 @@ protected: * will use its TextureHost(s) and call Compositor::DrawQuad to do the actual * rendering. */ -class CompositableHost : public RefCounted +class CompositableHost { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositableHost) - CompositableHost(const TextureInfo& aTextureInfo); - +protected: virtual ~CompositableHost(); +public: + NS_INLINE_DECL_REFCOUNTING(CompositableHost) + CompositableHost(const TextureInfo& aTextureInfo); + static TemporaryRef Create(const TextureInfo& aTextureInfo); virtual CompositableType GetType() = 0; diff --git a/gfx/layers/composite/TextRenderer.h b/gfx/layers/composite/TextRenderer.h index eddcb2e78b89..530fbe5bd950 100644 --- a/gfx/layers/composite/TextRenderer.h +++ b/gfx/layers/composite/TextRenderer.h @@ -7,6 +7,7 @@ #define GFX_TextRenderer_H #include "mozilla/gfx/2D.h" +#include "nsISupportsImpl.h" #include namespace mozilla { @@ -14,10 +15,11 @@ namespace layers { class Compositor; -class TextRenderer : public RefCounted +class TextRenderer { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(TextRenderer) + NS_INLINE_DECL_REFCOUNTING(TextRenderer) + TextRenderer(Compositor *aCompositor) : mCompositor(aCompositor) { diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h index e9392498240a..ea50d114a7e3 100644 --- a/gfx/layers/composite/TextureHost.h +++ b/gfx/layers/composite/TextureHost.h @@ -80,13 +80,16 @@ public: * * This class is used on the compositor side. */ -class TextureSource : public RefCounted +class TextureSource { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(TextureSource) - TextureSource(); +protected: virtual ~TextureSource(); +public: + NS_INLINE_DECL_REFCOUNTING(TextureSource) + + TextureSource(); + /** * Return the size of the texture in texels. * If this is a tile iterator, GetSize must return the size of the current tile. diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 02e2a6af0be1..7b976564cbc8 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -132,6 +132,7 @@ namespace mozilla { namespace layers { typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior; +typedef GeckoContentController::APZStateChange APZStateChange; /* * The following prefs are used to control the behaviour of the APZC. @@ -420,9 +421,6 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId, mCurrentAsyncScrollOffset(0, 0), mAsyncScrollTimeoutTask(nullptr), mHandlingTouchQueue(false), - mAllowedTouchBehaviorSet(false), - mPreventDefault(false), - mPreventDefaultSet(false), mTreeManager(aTreeManager), mScrollParentId(FrameMetrics::NULL_SCROLL_ID), mAPZCId(sAsyncPanZoomControllerCount++), @@ -498,6 +496,12 @@ AsyncPanZoomController::GetTouchStartTolerance() } nsEventStatus AsyncPanZoomController::ReceiveInputEvent(const InputData& aEvent) { + if (aEvent.mInputType == MULTITOUCH_INPUT && + aEvent.AsMultiTouchInput().mType == MultiTouchInput::MULTITOUCH_START) { + // Starting a new touch block, clear old touch block state. + mTouchBlockState = TouchBlockState(); + } + // If we may have touch listeners and touch action property is enabled, we // enable the machinery that allows touch listeners to preventDefault any touch inputs // and also waits for the allowed touch behavior values to be received from the outside. @@ -509,10 +513,6 @@ nsEventStatus AsyncPanZoomController::ReceiveInputEvent(const InputData& aEvent) (mState == NOTHING || mState == TOUCHING || IsPanningState(mState))) { const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput(); if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) { - mAllowedTouchBehaviors.Clear(); - mAllowedTouchBehaviorSet = false; - mPreventDefault = false; - mPreventDefaultSet = false; SetState(WAITING_CONTENT_RESPONSE); } } @@ -615,11 +615,18 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent case FLING: CancelAnimation(); // Fall through. - case NOTHING: + case NOTHING: { mX.StartTouch(point.x); mY.StartTouch(point.y); + APZCTreeManager* treeManagerLocal = mTreeManager; + if (treeManagerLocal) { + bool touchCanBePan = treeManagerLocal->CanBePanned(this); + mGeckoContentController->NotifyAPZStateChange( + GetGuid(), APZStateChange::StartTouch, touchCanBePan); + } SetState(TOUCHING); break; + } case TOUCHING: case PANNING: case PANNING_LOCKED_X: @@ -698,6 +705,8 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent) nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) { APZC_LOG("%p got a touch-end in state %d\n", this, mState); + OnTouchEndOrCancel(); + // In case no touch behavior triggered previously we can avoid sending // scroll events or requesting content repaint. This condition is added // to make tests consistent - in case touch-action is NONE (and therefore @@ -764,6 +773,7 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEvent) { APZC_LOG("%p got a touch-cancel in state %d\n", this, mState); + OnTouchEndOrCancel(); SetState(NOTHING); return nsEventStatus_eConsumeNoDefault; } @@ -929,15 +939,12 @@ nsEventStatus AsyncPanZoomController::OnLongPressUp(const TapGestureInput& aEven return nsEventStatus_eIgnore; } -nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) { - APZC_LOG("%p got a single-tap-up in state %d\n", this, mState); +nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers) { nsRefPtr controller = GetGeckoContentController(); - // If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before - // sending event to content - if (controller && !mZoomConstraints.mAllowDoubleTapZoom) { - int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers); + if (controller) { CSSPoint geckoScreenPoint; - if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) { + if (ConvertToGecko(aPoint, &geckoScreenPoint)) { + int32_t modifiers = WidgetModifiersToDOMModifiers(aModifiers); // Because this may be being running as part of APZCTreeManager::ReceiveInputEvent, // calling controller->HandleSingleTap directly might mean that content receives // the single tap message before the corresponding touch-up. To avoid that we @@ -947,30 +954,33 @@ nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEven NewRunnableMethod(controller.get(), &GeckoContentController::HandleSingleTap, geckoScreenPoint, modifiers, GetGuid()), 0); + mTouchBlockState.mSingleTapOccurred = true; return nsEventStatus_eConsumeNoDefault; } } return nsEventStatus_eIgnore; } -nsEventStatus AsyncPanZoomController::OnSingleTapConfirmed(const TapGestureInput& aEvent) { - APZC_LOG("%p got a single-tap-confirmed in state %d\n", this, mState); - nsRefPtr controller = GetGeckoContentController(); - if (controller) { - int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers); - CSSPoint geckoScreenPoint; - if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) { - // See comment in OnSingleTapUp as to why we do this in PostDelayedTask. - controller->PostDelayedTask( - NewRunnableMethod(controller.get(), &GeckoContentController::HandleSingleTap, - geckoScreenPoint, modifiers, GetGuid()), - 0); - return nsEventStatus_eConsumeNoDefault; - } +void AsyncPanZoomController::OnTouchEndOrCancel() { + mGeckoContentController->NotifyAPZStateChange( + GetGuid(), APZStateChange::EndTouch, mTouchBlockState.mSingleTapOccurred); +} + +nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) { + APZC_LOG("%p got a single-tap-up in state %d\n", this, mState); + // If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before + // sending event to content + if (!mZoomConstraints.mAllowDoubleTapZoom) { + return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers); } return nsEventStatus_eIgnore; } +nsEventStatus AsyncPanZoomController::OnSingleTapConfirmed(const TapGestureInput& aEvent) { + APZC_LOG("%p got a single-tap-confirmed in state %d\n", this, mState); + return GenerateSingleTap(aEvent.mPoint, aEvent.modifiers); +} + nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent) { APZC_LOG("%p got a double-tap in state %d\n", this, mState); nsRefPtr controller = GetGeckoContentController(); @@ -1092,15 +1102,17 @@ nsEventStatus AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent } else { if (GetAxisLockMode() == FREE) { SetState(PANNING); - return nsEventStatus_eConsumeNoDefault; + } else { + HandlePanning(angle); } - - HandlePanning(angle); } + if (IsPanningState(mState)) { + mGeckoContentController->NotifyAPZStateChange(GetGuid(), APZStateChange::StartPanning); + return nsEventStatus_eConsumeNoDefault; + } // Don't consume an event that didn't trigger a panning. - return IsPanningState(mState) ? nsEventStatus_eConsumeNoDefault - : nsEventStatus_eIgnore; + return nsEventStatus_eIgnore; } void AsyncPanZoomController::UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent) { @@ -1445,6 +1457,11 @@ void AsyncPanZoomController::FlushRepaintForOverscrollHandoff() { UpdateSharedCompositorFrameMetrics(); } +bool AsyncPanZoomController::IsPannable() const { + ReentrantMonitorAutoEnter lock(mMonitor); + return mX.HasRoomToPan() || mY.HasRoomToPan(); +} + void AsyncPanZoomController::RequestContentRepaint() { RequestContentRepaint(mFrameMetrics); } @@ -1890,8 +1907,8 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) { } void AsyncPanZoomController::ContentReceivedTouch(bool aPreventDefault) { - mPreventDefaultSet = true; - mPreventDefault = aPreventDefault; + mTouchBlockState.mPreventDefaultSet = true; + mTouchBlockState.mPreventDefault = aPreventDefault; CheckContentResponse(); } @@ -1899,11 +1916,11 @@ void AsyncPanZoomController::CheckContentResponse() { bool canProceedToTouchState = true; if (mFrameMetrics.mMayHaveTouchListeners) { - canProceedToTouchState &= mPreventDefaultSet; + canProceedToTouchState &= mTouchBlockState.mPreventDefaultSet; } if (mTouchActionPropertyEnabled) { - canProceedToTouchState &= mAllowedTouchBehaviorSet; + canProceedToTouchState &= mTouchBlockState.mAllowedTouchBehaviorSet; } if (!canProceedToTouchState) { @@ -1916,14 +1933,14 @@ void AsyncPanZoomController::CheckContentResponse() { } if (mState == WAITING_CONTENT_RESPONSE) { - if (!mPreventDefault) { + if (!mTouchBlockState.mPreventDefault) { SetState(NOTHING); } mHandlingTouchQueue = true; while (!mTouchQueue.IsEmpty()) { - if (!mPreventDefault) { + if (!mTouchBlockState.mPreventDefault) { HandleInputEvent(mTouchQueue[0]); } @@ -1947,8 +1964,8 @@ bool AsyncPanZoomController::TouchActionAllowZoom() { // Pointer events specification implies all touch points to allow zoom // to perform it. - for (size_t i = 0; i < mAllowedTouchBehaviors.Length(); i++) { - if (!(mAllowedTouchBehaviors[i] & AllowedTouchBehavior::ZOOM)) { + for (size_t i = 0; i < mTouchBlockState.mAllowedTouchBehaviors.Length(); i++) { + if (!(mTouchBlockState.mAllowedTouchBehaviors[i] & AllowedTouchBehavior::ZOOM)) { return false; } } @@ -1958,8 +1975,8 @@ bool AsyncPanZoomController::TouchActionAllowZoom() { AsyncPanZoomController::TouchBehaviorFlags AsyncPanZoomController::GetTouchBehavior(uint32_t touchIndex) { - if (touchIndex < mAllowedTouchBehaviors.Length()) { - return mAllowedTouchBehaviors[touchIndex]; + if (touchIndex < mTouchBlockState.mAllowedTouchBehaviors.Length()) { + return mTouchBlockState.mAllowedTouchBehaviors[touchIndex]; } return DefaultTouchBehavior; } @@ -1973,9 +1990,9 @@ AsyncPanZoomController::GetAllowedTouchBehavior(ScreenIntPoint& aPoint) { } void AsyncPanZoomController::SetAllowedTouchBehavior(const nsTArray& aBehaviors) { - mAllowedTouchBehaviors.Clear(); - mAllowedTouchBehaviors.AppendElements(aBehaviors); - mAllowedTouchBehaviorSet = true; + mTouchBlockState.mAllowedTouchBehaviors.Clear(); + mTouchBlockState.mAllowedTouchBehaviors.AppendElements(aBehaviors); + mTouchBlockState.mAllowedTouchBehaviorSet = true; CheckContentResponse(); } @@ -1992,11 +2009,11 @@ void AsyncPanZoomController::SetState(PanZoomState aNewState) { if (mGeckoContentController) { if (!IsTransformingState(oldState) && IsTransformingState(aNewState)) { - mGeckoContentController->NotifyTransformBegin( - ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.GetScrollId())); + mGeckoContentController->NotifyAPZStateChange( + GetGuid(), APZStateChange::TransformBegin); } else if (IsTransformingState(oldState) && !IsTransformingState(aNewState)) { - mGeckoContentController->NotifyTransformEnd( - ScrollableLayerGuid(mLayersId, mFrameMetrics.mPresShellId, mFrameMetrics.GetScrollId())); + mGeckoContentController->NotifyAPZStateChange( + GetGuid(), APZStateChange::TransformEnd); } } } diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index c89d43bb9c68..c44a5d0a8552 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -315,6 +315,8 @@ public: * Sets allowed touch behavior for current touch session. * This method is invoked by the APZCTreeManager which in its turn invoked by * the widget after performing touch-action values retrieving. + * Must be called after receiving the TOUCH_START even that started the + * touch session. */ void SetAllowedTouchBehavior(const nsTArray& aBehaviors); @@ -332,6 +334,11 @@ public: mTestAsyncScrollOffset = aPoint; } + /** + * Returns whether this APZC has room to be panned (in any direction). + */ + bool IsPannable() const; + protected: // Protected destructor, to discourage deletion outside of Release(): ~AsyncPanZoomController(); @@ -557,6 +564,36 @@ private: was not set yet. we still need to abort animations. */ }; + // State related to a single touch block. Does not persist across touch blocks. + struct TouchBlockState { + + TouchBlockState() + : mAllowedTouchBehaviorSet(false), + mPreventDefault(false), + mPreventDefaultSet(false), + mSingleTapOccurred(false) + {} + + // Values of allowed touch behavior for touch points of this touch block. + // Since there are maybe a few current active touch points per time (multitouch case) + // and each touch point should have its own value of allowed touch behavior- we're + // keeping an array of allowed touch behavior values, not the single value. + nsTArray mAllowedTouchBehaviors; + + // Specifies whether mAllowedTouchBehaviors is set for this touch events block. + bool mAllowedTouchBehaviorSet; + + // Flag used to specify that content prevented the default behavior of this + // touch events block. + bool mPreventDefault; + + // Specifies whether mPreventDefault property is set for this touch events block. + bool mPreventDefaultSet; + + // Specifies whether a single tap event was generated during this touch block. + bool mSingleTapOccurred; + }; + /* * Returns whether current touch behavior values allow zooming. */ @@ -617,6 +654,12 @@ private: // changes, as it corresponds to the scale portion of those transforms. void UpdateTransformScale(); + // Helper function for OnSingleTapUp() and OnSingleTapConfirmed(). + nsEventStatus GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers); + + // Common processing at the end of a touch block. + void OnTouchEndOrCancel(); + uint64_t mLayersId; nsRefPtr mCompositorParent; PCompositorParent* mCrossProcessCompositorParent; @@ -643,7 +686,9 @@ protected: // monitor should be held. When setting |mState|, either the SetState() // function can be used, or the monitor can be held and then |mState| updated. // IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h. - ReentrantMonitor mMonitor; + // This is mutable to allow entering it from 'const' methods; doing otherwise + // would significantly limit what methods could be 'const'. + mutable ReentrantMonitor mMonitor; // Specifies whether we should use touch-action css property. Initialized from // the preferences. This property (in comparison with the global one) simplifies @@ -718,21 +763,8 @@ private: // and we don't want to queue the events back up again. bool mHandlingTouchQueue; - // Values of allowed touch behavior for current touch points. - // Since there are maybe a few current active touch points per time (multitouch case) - // and each touch point should have its own value of allowed touch behavior- we're - // keeping an array of allowed touch behavior values, not the single value. - nsTArray mAllowedTouchBehaviors; - - // Specifies whether mAllowedTouchBehaviors is set for current touch events block. - bool mAllowedTouchBehaviorSet; - - // Flag used to specify that content prevented the default behavior of the current - // touch events block. - bool mPreventDefault; - - // Specifies whether mPreventDefault property is set for current touch events block. - bool mPreventDefaultSet; + // Stores information about the current touch block. + TouchBlockState mTouchBlockState; // Extra offset to add in SampleContentTransformForFrame for testing CSSPoint mTestAsyncScrollOffset; diff --git a/gfx/layers/ipc/Axis.cpp b/gfx/layers/ipc/Axis.cpp index 00e22093c285..e92a211538f0 100644 --- a/gfx/layers/ipc/Axis.cpp +++ b/gfx/layers/ipc/Axis.cpp @@ -207,30 +207,30 @@ void Axis::SetVelocity(float aVelocity) { mVelocity = aVelocity; } -float Axis::GetCompositionEnd() { +float Axis::GetCompositionEnd() const { return GetOrigin() + GetCompositionLength(); } -float Axis::GetPageEnd() { +float Axis::GetPageEnd() const { return GetPageStart() + GetPageLength(); } -float Axis::GetOrigin() { +float Axis::GetOrigin() const { CSSPoint origin = mAsyncPanZoomController->GetFrameMetrics().GetScrollOffset(); return GetPointOffset(origin); } -float Axis::GetCompositionLength() { +float Axis::GetCompositionLength() const { const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics(); return GetRectLength(metrics.CalculateCompositedRectInCssPixels()); } -float Axis::GetPageStart() { +float Axis::GetPageStart() const { CSSRect pageRect = mAsyncPanZoomController->GetFrameMetrics().mScrollableRect; return GetRectOffset(pageRect); } -float Axis::GetPageLength() { +float Axis::GetPageLength() const { CSSRect pageRect = mAsyncPanZoomController->GetFrameMetrics().mScrollableRect; return GetRectLength(pageRect); } @@ -244,23 +244,29 @@ bool Axis::ScaleWillOverscrollBothSides(float aScale) { return GetRectLength(metrics.mScrollableRect) < GetRectLength(cssCompositionBounds); } +bool Axis::HasRoomToPan() const { + return GetOrigin() > GetPageStart() + || GetCompositionEnd() < GetPageEnd(); +} + + AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController) : Axis(aAsyncPanZoomController) { } -float AxisX::GetPointOffset(const CSSPoint& aPoint) +float AxisX::GetPointOffset(const CSSPoint& aPoint) const { return aPoint.x; } -float AxisX::GetRectLength(const CSSRect& aRect) +float AxisX::GetRectLength(const CSSRect& aRect) const { return aRect.width; } -float AxisX::GetRectOffset(const CSSRect& aRect) +float AxisX::GetRectOffset(const CSSRect& aRect) const { return aRect.x; } @@ -271,17 +277,17 @@ AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController) } -float AxisY::GetPointOffset(const CSSPoint& aPoint) +float AxisY::GetPointOffset(const CSSPoint& aPoint) const { return aPoint.y; } -float AxisY::GetRectLength(const CSSRect& aRect) +float AxisY::GetRectLength(const CSSRect& aRect) const { return aRect.height; } -float AxisY::GetRectOffset(const CSSRect& aRect) +float AxisY::GetRectOffset(const CSSRect& aRect) const { return aRect.y; } diff --git a/gfx/layers/ipc/Axis.h b/gfx/layers/ipc/Axis.h index dd544da07cfd..f58cf8c40f25 100644 --- a/gfx/layers/ipc/Axis.h +++ b/gfx/layers/ipc/Axis.h @@ -170,18 +170,23 @@ public: */ bool ScaleWillOverscrollBothSides(float aScale); - float GetOrigin(); - float GetCompositionLength(); - float GetPageStart(); - float GetPageLength(); - float GetCompositionEnd(); - float GetPageEnd(); + /** + * Returns whether there is room to pan on this axis in either direction. + */ + bool HasRoomToPan() const; + + float GetOrigin() const; + float GetCompositionLength() const; + float GetPageStart() const; + float GetPageLength() const; + float GetCompositionEnd() const; + float GetPageEnd() const; int32_t GetPos() const { return mPos; } - virtual float GetPointOffset(const CSSPoint& aPoint) = 0; - virtual float GetRectLength(const CSSRect& aRect) = 0; - virtual float GetRectOffset(const CSSRect& aRect) = 0; + virtual float GetPointOffset(const CSSPoint& aPoint) const = 0; + virtual float GetRectLength(const CSSRect& aRect) const = 0; + virtual float GetRectOffset(const CSSRect& aRect) const = 0; protected: int32_t mPos; @@ -195,17 +200,17 @@ protected: class AxisX : public Axis { public: AxisX(AsyncPanZoomController* mAsyncPanZoomController); - virtual float GetPointOffset(const CSSPoint& aPoint); - virtual float GetRectLength(const CSSRect& aRect); - virtual float GetRectOffset(const CSSRect& aRect); + virtual float GetPointOffset(const CSSPoint& aPoint) const; + virtual float GetRectLength(const CSSRect& aRect) const; + virtual float GetRectOffset(const CSSRect& aRect) const; }; class AxisY : public Axis { public: AxisY(AsyncPanZoomController* mAsyncPanZoomController); - virtual float GetPointOffset(const CSSPoint& aPoint); - virtual float GetRectLength(const CSSRect& aRect); - virtual float GetRectOffset(const CSSRect& aRect); + virtual float GetPointOffset(const CSSPoint& aPoint) const; + virtual float GetRectLength(const CSSRect& aRect) const; + virtual float GetRectOffset(const CSSRect& aRect) const; }; } diff --git a/gfx/layers/ipc/GeckoContentController.h b/gfx/layers/ipc/GeckoContentController.h index ae0a64e4b669..c6d34016dd3d 100644 --- a/gfx/layers/ipc/GeckoContentController.h +++ b/gfx/layers/ipc/GeckoContentController.h @@ -113,13 +113,42 @@ public: return false; } + MOZ_BEGIN_NESTED_ENUM_CLASS(APZStateChange, int8_t) + /** + * APZ started modifying the view (including panning, zooming, and fling). + */ + TransformBegin, + /** + * APZ finished modifying the view. + */ + TransformEnd, + /** + * APZ started a touch. + * |aArg| is 1 if touch can be a pan, 0 otherwise. + */ + StartTouch, + /** + * APZ started a pan. + */ + StartPanning, + /** + * APZ finished processing a touch. + * |aArg| is 1 if touch was a click, 0 otherwise. + */ + EndTouch, + APZStateChangeSentinel + MOZ_END_NESTED_ENUM_CLASS(APZStateChange) + /** - * General tranformation notices for consumers. These fire any time - * the apzc is modifying the view, including panning, zooming, and - * fling. + * General notices of APZ state changes for consumers. + * |aGuid| identifies the APZC originating the state change. + * |aChange| identifies the type of state change + * |aArg| is used by some state changes to pass extra information (see + * the documentation for each state change above) */ - virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid) {} - virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid) {} + virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, + APZStateChange aChange, + int aArg = 0) {} GeckoContentController() {} @@ -128,6 +157,8 @@ protected: virtual ~GeckoContentController() {} }; +MOZ_FINISH_NESTED_ENUM_CLASS(GeckoContentController::APZStateChange) + } } diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 252c8999a151..9da26754f9a3 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -331,10 +331,6 @@ static void ReleaseImageClientNow(ImageClient* aClient) // static void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient) { - if (!IsCreated()) { - return; - } - sImageBridgeChildSingleton->GetMessageLoop()->PostTask( FROM_HERE, NewRunnableFunction(&ReleaseImageClientNow, aClient)); @@ -349,10 +345,6 @@ static void ReleaseTextureClientNow(TextureClient* aClient) // static void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient) { - if (!IsCreated()) { - return; - } - sImageBridgeChildSingleton->GetMessageLoop()->PostTask( FROM_HERE, NewRunnableFunction(&ReleaseTextureClientNow, aClient)); @@ -372,10 +364,6 @@ static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContaine void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient, ImageContainer* aContainer) { - if (!IsCreated()) { - return; - } - if (InImageBridgeChildThread()) { UpdateImageClientNow(aClient, aContainer); return; @@ -400,10 +388,6 @@ static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer, //static void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront) { - if (!IsCreated()) { - return; - } - if (InImageBridgeChildThread()) { FlushAllImagesNow(aClient, aContainer, aExceptFront); return; @@ -593,14 +577,15 @@ bool ImageBridgeChild::StartUpOnThread(Thread* aThread) void ImageBridgeChild::DestroyBridge() { - if (!IsCreated()) { - return; - } NS_ABORT_IF_FALSE(!InImageBridgeChildThread(), "This method must not be called in this thread."); // ...because we are about to dispatch synchronous messages to the // ImageBridgeChild thread. + if (!IsCreated()) { + return; + } + ReentrantMonitor barrier("ImageBridgeDestroyTask lock"); ReentrantMonitorAutoEnter autoMon(barrier); @@ -622,8 +607,7 @@ void ImageBridgeChild::DestroyBridge() bool InImageBridgeChildThread() { - return ImageBridgeChild::IsCreated() && - sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId(); + return sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId(); } MessageLoop * ImageBridgeChild::GetMessageLoop() const diff --git a/gfx/layers/ipc/LayerTransactionChild.h b/gfx/layers/ipc/LayerTransactionChild.h index eeaee444cf4c..22d57abd4c35 100644 --- a/gfx/layers/ipc/LayerTransactionChild.h +++ b/gfx/layers/ipc/LayerTransactionChild.h @@ -23,10 +23,9 @@ class RenderFrameChild; namespace layers { class LayerTransactionChild : public PLayerTransactionChild - , public AtomicRefCounted { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(LayerTransactionChild) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LayerTransactionChild) /** * Clean this up, finishing with Send__delete__(). * @@ -43,8 +42,6 @@ protected: : mIPCOpen(false) {} ~LayerTransactionChild() { } - friend class AtomicRefCounted; - friend class detail::RefCounted; virtual PGrallocBufferChild* AllocPGrallocBufferChild(const IntSize&, diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 1f3863a3f428..1793f63d1367 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -64,13 +64,14 @@ struct EffectChain; * This is primarily intended for direct texturing APIs that need to attach * shared objects (such as an EGLImage) to a gl texture. */ -class CompositorTexturePoolOGL : public RefCounted +class CompositorTexturePoolOGL { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(CompositorTexturePoolOGL) - +protected: virtual ~CompositorTexturePoolOGL() {} +public: + NS_INLINE_DECL_REFCOUNTING(CompositorTexturePoolOGL) + virtual void Clear() = 0; virtual GLuint GetTexture(GLenum aTarget, GLenum aEnum) = 0; diff --git a/gfx/src/FilterSupport.cpp b/gfx/src/FilterSupport.cpp index d4c12965f9a1..62e2d75b56f8 100644 --- a/gfx/src/FilterSupport.cpp +++ b/gfx/src/FilterSupport.cpp @@ -230,10 +230,10 @@ namespace FilterWrappers { // Internally, this is achieved by wrapping the original FilterNode with // conversion FilterNodes. These filter nodes are cached in such a way that no // repeated or back-and-forth conversions happen. -class FilterCachedColorModels : public RefCounted +class FilterCachedColorModels { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(FilterCachedColorModels) + NS_INLINE_DECL_REFCOUNTING(FilterCachedColorModels) // aFilter can be null. In that case, ForColorModel will return a non-null // completely transparent filter for all color models. FilterCachedColorModels(DrawTarget* aDT, diff --git a/gfx/src/nsRenderingContext.h b/gfx/src/nsRenderingContext.h index 5f21cd57c845..bd22030e2961 100644 --- a/gfx/src/nsRenderingContext.h +++ b/gfx/src/nsRenderingContext.h @@ -34,7 +34,7 @@ typedef enum { nsLineStyle_kDotted = 3 } nsLineStyle; -class nsRenderingContext +class nsRenderingContext MOZ_FINAL { typedef mozilla::gfx::UserData UserData; typedef mozilla::gfx::UserDataKey UserDataKey; @@ -42,7 +42,6 @@ class nsRenderingContext public: nsRenderingContext() : mP2A(0.) {} - // ~nsRenderingContext() {} NS_INLINE_DECL_REFCOUNTING(nsRenderingContext) @@ -130,7 +129,12 @@ public: return mUserData.Remove(key); } -protected: +private: + // Private destructor, to discourage deletion outside of Release(): + ~nsRenderingContext() + { + } + int32_t GetMaxChunkLength(); nsRefPtr mThebes; diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 357f84d730a7..3fffa214284b 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -168,7 +168,14 @@ FrameMetrics TestFrameMetrics() { * consumed them and triggered scrolling behavior. */ static -void ApzcPan(AsyncPanZoomController* apzc, TestAPZCTreeManager* aTreeManager, int& aTime, int aTouchStartY, int aTouchEndY, bool expectIgnoredPan = false, bool hasTouchListeners = false) { +void ApzcPan(AsyncPanZoomController* apzc, + TestAPZCTreeManager* aTreeManager, + int& aTime, + int aTouchStartY, + int aTouchEndY, + bool expectIgnoredPan = false, + bool hasTouchListeners = false, + nsTArray* aAllowedTouchBehaviors = nullptr) { const int TIME_BETWEEN_TOUCH_EVENT = 100; const int OVERCOME_TOUCH_TOLERANCE = 100; @@ -198,6 +205,11 @@ void ApzcPan(AsyncPanZoomController* apzc, TestAPZCTreeManager* aTreeManager, in EXPECT_EQ(status, touchStartStatus); // APZC should be in TOUCHING state + // Allowed touch behaviours must be set after sending touch-start. + if (aAllowedTouchBehaviors) { + apzc->SetAllowedTouchBehavior(*aAllowedTouchBehaviors); + } + nsEventStatus touchMoveStatus; if (expectIgnoredPan) { // APZC should ignore panning, be in TOUCHING state and therefore return eIgnore. @@ -254,12 +266,11 @@ void DoPanTest(bool aShouldTriggerScroll, bool aShouldUseTouchAction, uint32_t a ScreenPoint pointOut; ViewTransform viewTransformOut; - nsTArray values; - values.AppendElement(aBehavior); + nsTArray allowedTouchBehaviors; + allowedTouchBehaviors.AppendElement(aBehavior); // Pan down - apzc->SetAllowedTouchBehavior(values); - ApzcPan(apzc, tm, time, touchStart, touchEnd, !aShouldTriggerScroll); + ApzcPan(apzc, tm, time, touchStart, touchEnd, !aShouldTriggerScroll, false, &allowedTouchBehaviors); apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); if (aShouldTriggerScroll) { @@ -271,8 +282,7 @@ void DoPanTest(bool aShouldTriggerScroll, bool aShouldUseTouchAction, uint32_t a } // Pan back - apzc->SetAllowedTouchBehavior(values); - ApzcPan(apzc, tm, time, touchEnd, touchStart, !aShouldTriggerScroll); + ApzcPan(apzc, tm, time, touchEnd, touchStart, !aShouldTriggerScroll, false, &allowedTouchBehaviors); apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut); EXPECT_EQ(pointOut, ScreenPoint()); @@ -613,11 +623,10 @@ TEST_F(AsyncPanZoomControllerTester, PanWithPreventDefault) { ViewTransform viewTransformOut; // Pan down - nsTArray values; - values.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN); + nsTArray allowedTouchBehaviors; + allowedTouchBehaviors.AppendElement(mozilla::layers::AllowedTouchBehavior::VERTICAL_PAN); apzc->SetTouchActionEnabled(true); - apzc->SetAllowedTouchBehavior(values); - ApzcPan(apzc, tm, time, touchStart, touchEnd, true, true); + ApzcPan(apzc, tm, time, touchStart, touchEnd, true, true, &allowedTouchBehaviors); // Send the signal that content has handled and preventDefaulted the touch // events. This flushes the event queue. @@ -746,16 +755,18 @@ DoLongPressTest(bool aShouldUseTouchAction, uint32_t aBehavior) { apzc->NotifyLayersUpdated(TestFrameMetrics(), true); apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0))); - nsTArray values; - values.AppendElement(aBehavior); apzc->SetTouchActionEnabled(aShouldUseTouchAction); - apzc->SetAllowedTouchBehavior(values); int time = 0; nsEventStatus status = ApzcDown(apzc, 10, 10, time); EXPECT_EQ(nsEventStatus_eConsumeNoDefault, status); + // SetAllowedTouchBehavior() must be called after sending touch-start. + nsTArray allowedTouchBehaviors; + allowedTouchBehaviors.AppendElement(aBehavior); + apzc->SetAllowedTouchBehavior(allowedTouchBehaviors); + MockFunction check; { diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index e26485acd2e7..597d540c33b1 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -73,12 +73,14 @@ #include "TexturePoolOGL.h" #endif -#ifdef USE_SKIA #include "mozilla/Hal.h" +#ifdef USE_SKIA #include "skia/SkGraphics.h" #include "SkiaGLGlue.h" - +#else +class mozilla::gl::SkiaGLGlue : public GenericAtomicRefCounted { +}; #endif #include "mozilla/Preferences.h" @@ -491,6 +493,12 @@ gfxPlatform::Shutdown() mozilla::gl::GLContextProviderEGL::Shutdown(); #endif + // This will block this thread untill the ImageBridge protocol is completely + // deleted. + ImageBridgeChild::ShutDown(); + + CompositorParent::ShutDown(); + delete gGfxPlatformPrefsLock; gfxPrefs::DestroySingleton(); @@ -922,7 +930,9 @@ gfxPlatform::InitializeSkiaCacheLimits() printf_stderr("Determined SkiaGL cache limits: Size %i, Items: %i\n", cacheSizeLimit, cacheItemLimit); #endif +#ifdef USE_SKIA_GPU mSkiaGlue->GetGrContext()->setTextureCacheLimits(cacheItemLimit, cacheSizeLimit); +#endif } } diff --git a/hal/HalWakeLock.cpp b/hal/HalWakeLock.cpp index b4d6c8f8e16f..3cd73e26aae7 100644 --- a/hal/HalWakeLock.cpp +++ b/hal/HalWakeLock.cpp @@ -12,7 +12,7 @@ #include "nsDataHashtable.h" #include "nsHashKeys.h" #include "nsIPropertyBag2.h" -#include "nsObserverService.h" +#include "nsIObserverService.h" using namespace mozilla; using namespace mozilla::hal; diff --git a/hal/cocoa/CocoaBattery.cpp b/hal/cocoa/CocoaBattery.cpp index dec1c655d4dc..cbca794957a3 100644 --- a/hal/cocoa/CocoaBattery.cpp +++ b/hal/cocoa/CocoaBattery.cpp @@ -12,7 +12,8 @@ #include #include -#include +#include +#include #include diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp index 92875335b428..ea56e8646d16 100644 --- a/hal/gonk/GonkHal.cpp +++ b/hal/gonk/GonkHal.cpp @@ -294,11 +294,11 @@ public: } // anonymous namespace -class BatteryObserver : public IUeventObserver, - public RefCounted +class BatteryObserver : public IUeventObserver { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(BatteryObserver) + NS_INLINE_DECL_REFCOUNTING(BatteryObserver) + BatteryObserver() :mUpdater(new BatteryUpdater()) { diff --git a/hal/gonk/GonkSwitch.cpp b/hal/gonk/GonkSwitch.cpp index 38494f3c1025..1b2f6d4ee11f 100644 --- a/hal/gonk/GonkSwitch.cpp +++ b/hal/gonk/GonkSwitch.cpp @@ -51,10 +51,11 @@ namespace hal_impl { * SWITCH_STATE=0 * SEQNUM=5038 */ -class SwitchHandler : public RefCounted +class SwitchHandler { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(SwitchHandler) + NS_INLINE_DECL_REFCOUNTING(SwitchHandler) + SwitchHandler(const char* aDevPath, SwitchDevice aDevice) : mDevPath(aDevPath), mState(SWITCH_STATE_UNKNOWN), @@ -230,21 +231,20 @@ private: SwitchEvent mEvent; }; -class SwitchEventObserver : public IUeventObserver, - public RefCounted +class SwitchEventObserver MOZ_FINAL : public IUeventObserver { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(SwitchEventObserver) - SwitchEventObserver() : mEnableCount(0) - { - Init(); - } - ~SwitchEventObserver() { mHandler.Clear(); } +public: + NS_INLINE_DECL_REFCOUNTING(SwitchEventObserver) + SwitchEventObserver() : mEnableCount(0) + { + Init(); + } + int GetEnableCount() { return mEnableCount; diff --git a/image/public/imgIContainer.idl b/image/public/imgIContainer.idl index 884f27e30838..a500558fa553 100644 --- a/image/public/imgIContainer.idl +++ b/image/public/imgIContainer.idl @@ -13,6 +13,8 @@ #include "gfxRect.h" #include "GraphicsFilter.h" #include "gfxASurface.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "nsRect.h" #include "nsSize.h" #include "limits.h" @@ -55,7 +57,7 @@ native nsSize(nsSize); native Orientation(mozilla::image::Orientation); [ref] native TimeStamp(mozilla::TimeStamp); [ptr] native SVGImageContext(mozilla::SVGImageContext); -native already_AddRefed_gfxASurface(already_AddRefed); +native TempRefSourceSurface(mozilla::TemporaryRef); /** @@ -65,7 +67,7 @@ native already_AddRefed_gfxASurface(already_AddRefed); * * Internally, imgIContainer also manages animation of images. */ -[scriptable, builtinclass, uuid(8b7db7dd-bfe9-40d3-9114-3a79c0658afd)] +[scriptable, builtinclass, uuid(503a830c-734d-4362-91f6-73f83ac59646)] interface imgIContainer : nsISupports { /** @@ -150,6 +152,7 @@ interface imgIContainer : nsISupports const long FLAG_DECODE_NO_COLORSPACE_CONVERSION = 0x4; const long FLAG_CLAMP = 0x8; const long FLAG_HIGH_QUALITY_SCALING = 0x10; + const long FLAG_WANT_DATA_SURFACE = 0x20; /** * Constants for specifying various "special" frames. @@ -173,9 +176,8 @@ interface imgIContainer : nsISupports * @param aWhichFrame Frame specifier of the FRAME_* variety. * @param aFlags Flags of the FLAG_* variety */ - [noscript, notxpcom] already_AddRefed_gfxASurface - getFrame(in uint32_t aWhichFrame, - in uint32_t aFlags); + [noscript, notxpcom] TempRefSourceSurface getFrame(in uint32_t aWhichFrame, + in uint32_t aFlags); /** * Whether the given frame is opaque; that is, needs the background painted diff --git a/image/src/ClippedImage.cpp b/image/src/ClippedImage.cpp index e7f63c8525a5..722e72c9f624 100644 --- a/image/src/ClippedImage.cpp +++ b/image/src/ClippedImage.cpp @@ -6,11 +6,15 @@ #include "gfxDrawable.h" #include "gfxPlatform.h" #include "gfxUtils.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "ClippedImage.h" #include "Orientation.h" #include "SVGImageContext.h" +using namespace mozilla; +using namespace mozilla::gfx; using mozilla::layers::LayerManager; using mozilla::layers::ImageContainer; @@ -20,7 +24,7 @@ namespace image { class ClippedImageCachedSurface { public: - ClippedImageCachedSurface(mozilla::gfx::DrawTarget* aSurface, + ClippedImageCachedSurface(TemporaryRef aSurface, const nsIntSize& aViewportSize, const SVGImageContext* aSVGContext, float aFrame, @@ -49,13 +53,12 @@ public: mFlags == aFlags; } - already_AddRefed Surface() { - nsRefPtr surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mSurface); - return surf.forget(); + TemporaryRef Surface() { + return mSurface; } private: - nsRefPtr mSurface; + RefPtr mSurface; const nsIntSize mViewportSize; Maybe mSVGContext; const float mFrame; @@ -209,14 +212,14 @@ ClippedImage::GetIntrinsicRatio(nsSize* aRatio) return NS_OK; } -NS_IMETHODIMP_(already_AddRefed) +NS_IMETHODIMP_(TemporaryRef) ClippedImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) { return GetFrameInternal(mClip.Size(), nullptr, aWhichFrame, aFlags); } -already_AddRefed +TemporaryRef ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize, const SVGImageContext* aSVGContext, uint32_t aWhichFrame, @@ -232,13 +235,11 @@ ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize, frameToDraw, aFlags)) { // Create a surface to draw into. - mozilla::RefPtr target; - nsRefPtr ctx; + RefPtr target = gfxPlatform::GetPlatform()-> + CreateOffscreenContentDrawTarget(IntSize(mClip.width, mClip.height), + SurfaceFormat::B8G8R8A8); - target = gfxPlatform::GetPlatform()-> - CreateOffscreenContentDrawTarget(gfx::IntSize(mClip.width, mClip.height), - gfx::SurfaceFormat::B8G8R8A8); - ctx = new gfxContext(target); + nsRefPtr ctx = new gfxContext(target); // Create our callback. nsRefPtr drawTileCallback = @@ -254,7 +255,7 @@ ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize, GraphicsFilter::FILTER_FAST); // Cache the resulting surface. - mCachedSurface = new ClippedImageCachedSurface(target, + mCachedSurface = new ClippedImageCachedSurface(target->Snapshot(), aViewportSize, aSVGContext, frameToDraw, @@ -322,7 +323,7 @@ ClippedImage::Draw(gfxContext* aContext, if (MustCreateSurface(aContext, aUserSpaceToImageSpace, sourceRect, aSubimage, aFlags)) { // Create a temporary surface containing a single tile of this image. // GetFrame will call DrawSingleTile internally. - nsRefPtr surface = + RefPtr surface = GetFrameInternal(aViewportSize, aSVGContext, aWhichFrame, aFlags); NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); diff --git a/image/src/ClippedImage.h b/image/src/ClippedImage.h index 69c609fdece1..3aa3e7735315 100644 --- a/image/src/ClippedImage.h +++ b/image/src/ClippedImage.h @@ -7,7 +7,9 @@ #define MOZILLA_IMAGELIB_CLIPPEDIMAGE_H_ #include "ImageWrapper.h" +#include "mozilla/gfx/2D.h" #include "mozilla/Maybe.h" +#include "mozilla/RefPtr.h" namespace mozilla { namespace image { @@ -24,6 +26,8 @@ class DrawSingleTileCallback; */ class ClippedImage : public ImageWrapper { + typedef mozilla::gfx::SourceSurface SourceSurface; + public: NS_DECL_ISUPPORTS @@ -35,8 +39,8 @@ public: NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE; NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE; NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE; - NS_IMETHOD_(already_AddRefed) GetFrame(uint32_t aWhichFrame, - uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(mozilla::TemporaryRef) + GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager, mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE; NS_IMETHOD Draw(gfxContext* aContext, @@ -55,10 +59,11 @@ protected: ClippedImage(Image* aImage, nsIntRect aClip); private: - already_AddRefed GetFrameInternal(const nsIntSize& aViewportSize, - const SVGImageContext* aSVGContext, - uint32_t aWhichFrame, - uint32_t aFlags); + mozilla::TemporaryRef + GetFrameInternal(const nsIntSize& aViewportSize, + const SVGImageContext* aSVGContext, + uint32_t aWhichFrame, + uint32_t aFlags); bool ShouldClip(); bool MustCreateSurface(gfxContext* aContext, const gfxMatrix& aTransform, diff --git a/image/src/FrozenImage.cpp b/image/src/FrozenImage.cpp index 2b2607953449..48bcf21f0be8 100644 --- a/image/src/FrozenImage.cpp +++ b/image/src/FrozenImage.cpp @@ -5,6 +5,8 @@ #include "FrozenImage.h" +using namespace mozilla::gfx; + namespace mozilla { namespace image { @@ -40,7 +42,7 @@ FrozenImage::GetAnimated(bool* aAnimated) return rv; } -NS_IMETHODIMP_(already_AddRefed) +NS_IMETHODIMP_(TemporaryRef) FrozenImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) { diff --git a/image/src/FrozenImage.h b/image/src/FrozenImage.h index 947dc322a553..1d466b7eb17e 100644 --- a/image/src/FrozenImage.h +++ b/image/src/FrozenImage.h @@ -7,6 +7,8 @@ #define MOZILLA_IMAGELIB_FROZENIMAGE_H_ #include "ImageWrapper.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" namespace mozilla { namespace image { @@ -24,6 +26,8 @@ namespace image { */ class FrozenImage : public ImageWrapper { + typedef mozilla::gfx::SourceSurface SourceSurface; + public: NS_DECL_ISUPPORTS @@ -34,8 +38,8 @@ public: virtual void DecrementAnimationConsumers() MOZ_OVERRIDE; NS_IMETHOD GetAnimated(bool* aAnimated) MOZ_OVERRIDE; - NS_IMETHOD_(already_AddRefed) GetFrame(uint32_t aWhichFrame, - uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(TemporaryRef) + GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD_(bool) FrameIsOpaque(uint32_t aWhichFrame) MOZ_OVERRIDE; NS_IMETHOD GetImageContainer(layers::LayerManager* aManager, layers::ImageContainer** _retval) MOZ_OVERRIDE; diff --git a/image/src/ImageWrapper.cpp b/image/src/ImageWrapper.cpp index aaba02f77c96..c1cabd78ad17 100644 --- a/image/src/ImageWrapper.cpp +++ b/image/src/ImageWrapper.cpp @@ -4,10 +4,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ImageWrapper.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "Orientation.h" #include "mozilla/MemoryReporting.h" +using mozilla::gfx::DataSourceSurface; +using mozilla::gfx::SourceSurface; using mozilla::layers::LayerManager; using mozilla::layers::ImageContainer; @@ -196,7 +200,7 @@ ImageWrapper::GetAnimated(bool* aAnimated) return mInnerImage->GetAnimated(aAnimated); } -NS_IMETHODIMP_(already_AddRefed) +NS_IMETHODIMP_(TemporaryRef) ImageWrapper::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) { diff --git a/image/src/OrientedImage.cpp b/image/src/OrientedImage.cpp index d558aa7abcbc..47d11539ee23 100644 --- a/image/src/OrientedImage.cpp +++ b/image/src/OrientedImage.cpp @@ -11,6 +11,8 @@ #include "OrientedImage.h" +using namespace mozilla::gfx; + using std::swap; using mozilla::layers::LayerManager; using mozilla::layers::ImageContainer; @@ -75,7 +77,7 @@ OrientedImage::GetIntrinsicRatio(nsSize* aRatio) return rv; } -NS_IMETHODIMP_(already_AddRefed) +NS_IMETHODIMP_(TemporaryRef) OrientedImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) { @@ -87,12 +89,12 @@ OrientedImage::GetFrame(uint32_t aWhichFrame, // Get the underlying dimensions. int32_t width, height; + rv = InnerImage()->GetWidth(&width); + NS_ENSURE_SUCCESS(rv, nullptr); + rv = InnerImage()->GetHeight(&height); + NS_ENSURE_SUCCESS(rv, nullptr); if (mOrientation.SwapsWidthAndHeight()) { - rv = InnerImage()->GetWidth(&height); - rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&width); - } else { - rv = InnerImage()->GetWidth(&width); - rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&height); + swap(width, height); } NS_ENSURE_SUCCESS(rv, nullptr); @@ -108,12 +110,12 @@ OrientedImage::GetFrame(uint32_t aWhichFrame, } // Create a surface to draw into. - mozilla::RefPtr target; - target = gfxPlatform::GetPlatform()-> - CreateOffscreenContentDrawTarget(gfx::IntSize(width, height), surfaceFormat); + mozilla::RefPtr target = + gfxPlatform::GetPlatform()-> + CreateOffscreenContentDrawTarget(IntSize(width, height), surfaceFormat); // Create our drawable. - nsRefPtr innerSurface = + RefPtr innerSurface = InnerImage()->GetFrame(aWhichFrame, aFlags); NS_ENSURE_TRUE(innerSurface, nullptr); nsRefPtr drawable = @@ -126,10 +128,7 @@ OrientedImage::GetFrame(uint32_t aWhichFrame, imageRect, imageRect, imageRect, imageRect, imageFormat, GraphicsFilter::FILTER_FAST); - nsRefPtr surface = gfxPlatform::GetPlatform()-> - GetThebesSurfaceForDrawTarget(target); - - return surface.forget(); + return target->Snapshot(); } NS_IMETHODIMP diff --git a/image/src/OrientedImage.h b/image/src/OrientedImage.h index 1c1886bd655e..6bd8170f22e2 100644 --- a/image/src/OrientedImage.h +++ b/image/src/OrientedImage.h @@ -7,6 +7,8 @@ #define MOZILLA_IMAGELIB_ORIENTEDIMAGE_H_ #include "ImageWrapper.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "Orientation.h" namespace mozilla { @@ -21,6 +23,8 @@ namespace image { */ class OrientedImage : public ImageWrapper { + typedef mozilla::gfx::SourceSurface SourceSurface; + public: NS_DECL_ISUPPORTS @@ -32,8 +36,8 @@ public: NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE; NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE; NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE; - NS_IMETHOD_(already_AddRefed) GetFrame(uint32_t aWhichFrame, - uint32_t aFlags) MOZ_OVERRIDE; + NS_IMETHOD_(mozilla::TemporaryRef) + GetFrame(uint32_t aWhichFrame, uint32_t aFlags) MOZ_OVERRIDE; NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager, mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE; NS_IMETHOD Draw(gfxContext* aContext, diff --git a/image/src/RasterImage.cpp b/image/src/RasterImage.cpp index 22630d7d78fa..700e3652d849 100644 --- a/image/src/RasterImage.cpp +++ b/image/src/RasterImage.cpp @@ -3,13 +3,17 @@ * 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 "base/histogram.h" +// Must #include ImageLogging.h before any IPDL-generated files or other files that #include prlog.h #include "ImageLogging.h" + +#include "RasterImage.h" + +#include "base/histogram.h" +#include "gfxPlatform.h" #include "nsComponentManagerUtils.h" #include "imgDecoderObserver.h" #include "nsError.h" #include "Decoder.h" -#include "RasterImage.h" #include "nsAutoPtr.h" #include "prenv.h" #include "prsystem.h" @@ -30,6 +34,8 @@ #include "gfxContext.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Services.h" #include "mozilla/Preferences.h" @@ -48,6 +54,7 @@ #endif using namespace mozilla; +using namespace mozilla::gfx; using namespace mozilla::image; using namespace mozilla::layers; @@ -880,9 +887,9 @@ RasterImage::CopyFrame(uint32_t aWhichFrame, } //****************************************************************************** -/* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame, - * in uint32_t aFlags); */ -NS_IMETHODIMP_(already_AddRefed) +/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame, + * in uint32_t aFlags); */ +NS_IMETHODIMP_(TemporaryRef) RasterImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) { @@ -951,7 +958,22 @@ RasterImage::GetFrame(uint32_t aWhichFrame, framesurf = imgsurf; } - return framesurf.forget(); + RefPtr result; + + // As far as Moz2D is concerned, SourceSurface contains premultiplied alpha. + // If we're abusing it to contain non-premultiplied alpha then we want to + // avoid having Moz2D do any conversions on it (like copy to another + // surface). Hence why we try to wrap framesurf's data here for + // FLAG_DECODE_NO_PREMULTIPLY_ALPHA. + if ((aFlags & FLAG_WANT_DATA_SURFACE) != 0 || + (aFlags & FLAG_DECODE_NO_PREMULTIPLY_ALPHA) != 0) { + result = gfxPlatform::GetPlatform()->GetWrappedDataSourceSurface(framesurf); + } + if (!result) { + result = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, + framesurf); + } + return result.forget(); } already_AddRefed @@ -964,8 +986,8 @@ RasterImage::GetCurrentImage() return nullptr; } - nsRefPtr imageSurface = GetFrame(FRAME_CURRENT, FLAG_NONE); - if (!imageSurface) { + RefPtr surface = GetFrame(FRAME_CURRENT, FLAG_NONE); + if (!surface) { // The OS threw out some or all of our buffer. Start decoding again. // GetFrame will only return null in the case that the image was // discarded. We already checked that the image is decoded, so other @@ -982,7 +1004,7 @@ RasterImage::GetCurrentImage() CairoImage::Data cairoData; GetWidth(&cairoData.mSize.width); GetHeight(&cairoData.mSize.height); - cairoData.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, imageSurface); + cairoData.mSourceSurface = surface; nsRefPtr image = mImageContainer->CreateImage(ImageFormat::CAIRO_SURFACE); NS_ASSERTION(image, "Failed to create Image"); diff --git a/image/src/SurfaceCache.cpp b/image/src/SurfaceCache.cpp index 2a8ff1dffaac..a27ded36698f 100644 --- a/image/src/SurfaceCache.cpp +++ b/image/src/SurfaceCache.cpp @@ -110,10 +110,11 @@ private: * A CachedSurface associates a surface with a key that uniquely identifies that * surface. */ -class CachedSurface : public RefCounted +class CachedSurface { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(CachedSurface) + NS_INLINE_DECL_REFCOUNTING(CachedSurface) + CachedSurface(DrawTarget* aTarget, const IntSize aTargetSize, const Cost aCost, @@ -156,10 +157,11 @@ private: * destroyed or invalidated. Since this will happen frequently, it makes sense * to make it cheap by storing the surfaces for each image separately. */ -class ImageSurfaceCache : public RefCounted +class ImageSurfaceCache { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(ImageSurfaceCache) + NS_INLINE_DECL_REFCOUNTING(ImageSurfaceCache) + typedef nsRefPtrHashtable, CachedSurface> SurfaceTable; bool IsEmpty() const { return mSurfaces.Count() == 0; } diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index 64842cd1928d..2c74f226e2fe 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -649,9 +649,9 @@ VectorImage::FrameIsOpaque(uint32_t aWhichFrame) } //****************************************************************************** -/* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame, - * in uint32_t aFlags; */ -NS_IMETHODIMP_(already_AddRefed) +/* [noscript] SourceSurface getFrame(in uint32_t aWhichFrame, + * in uint32_t aFlags; */ +NS_IMETHODIMP_(TemporaryRef) VectorImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) { @@ -674,27 +674,14 @@ VectorImage::GetFrame(uint32_t aWhichFrame, return nullptr; } - // Create a surface that we'll ultimately return - // --------------------------------------------- // Make our surface the size of what will ultimately be drawn to it. // (either the full image size, or the restricted region) - gfxIntSize surfaceSize(imageIntSize.width, imageIntSize.height); - - nsRefPtr surface = - new gfxImageSurface(surfaceSize, gfxImageFormat::ARGB32); - - RefPtr drawTarget = - Factory::CreateDrawTargetForData(BackendType::CAIRO, - surface->Data(), - IntSize(imageIntSize.width, + RefPtr dt = gfxPlatform::GetPlatform()-> + CreateOffscreenContentDrawTarget(IntSize(imageIntSize.width, imageIntSize.height), - surface->Stride(), SurfaceFormat::B8G8R8A8); + nsRefPtr context = new gfxContext(dt); - nsRefPtr context = new gfxContext(drawTarget); - - // Draw to our surface! - // -------------------- nsresult rv = Draw(context, GraphicsFilter::FILTER_NEAREST, gfxMatrix(), gfxRect(gfxPoint(0,0), gfxIntSize(imageIntSize.width, imageIntSize.height)), @@ -702,7 +689,7 @@ VectorImage::GetFrame(uint32_t aWhichFrame, imageIntSize, nullptr, aWhichFrame, aFlags); NS_ENSURE_SUCCESS(rv, nullptr); - return surface.forget(); + return dt->Snapshot(); } //****************************************************************************** diff --git a/image/src/imgTools.cpp b/image/src/imgTools.cpp index f763e9820bbf..cae25b8fce2d 100644 --- a/image/src/imgTools.cpp +++ b/image/src/imgTools.cpp @@ -6,6 +6,7 @@ #include "imgTools.h" +#include "gfxUtils.h" #include "mozilla/gfx/2D.h" #include "mozilla/RefPtr.h" #include "nsCOMPtr.h" @@ -97,20 +98,6 @@ NS_IMETHODIMP imgTools::DecodeImage(nsIInputStream* aInStr, return NS_OK; } -static TemporaryRef -GetFirstImageFrame(imgIContainer *aContainer) -{ - nsRefPtr frame = - aContainer->GetFrame(imgIContainer::FRAME_FIRST, - imgIContainer::FLAG_SYNC_DECODE); - NS_ENSURE_TRUE(frame, nullptr); - - nsRefPtr imageSurface = frame->CopyToARGB32ImageSurface(); - NS_ENSURE_TRUE(imageSurface, nullptr); - - return imageSurface->CopyToB8G8R8A8DataSourceSurface(); -} - /** * This takes a DataSourceSurface rather than a SourceSurface because some * of the callers have a DataSourceSurface and we don't want to call @@ -161,10 +148,22 @@ NS_IMETHODIMP imgTools::EncodeImage(imgIContainer *aContainer, nsIInputStream **aStream) { // Use frame 0 from the image container. - RefPtr frame = GetFirstImageFrame(aContainer); + RefPtr frame = + aContainer->GetFrame(imgIContainer::FRAME_FIRST, + imgIContainer::FLAG_SYNC_DECODE); NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE); - RefPtr dataSurface = frame->GetDataSurface(); + RefPtr dataSurface; + + if (frame->GetFormat() == SurfaceFormat::B8G8R8A8) { + dataSurface = frame->GetDataSurface(); + } else { + // Convert format to SurfaceFormat::B8G8R8A8 + dataSurface = gfxUtils:: + CopySurfaceToDataSourceSurfaceWithFormat(frame, + SurfaceFormat::B8G8R8A8); + } + NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE); return EncodeImageData(dataSurface, aMimeType, aOutputOptions, aStream); @@ -186,7 +185,9 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer, } // Use frame 0 from the image container. - RefPtr frame = GetFirstImageFrame(aContainer); + RefPtr frame = + aContainer->GetFrame(imgIContainer::FRAME_FIRST, + imgIContainer::FLAG_SYNC_DECODE); NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE); int32_t frameWidth = frame->GetSize().width; @@ -247,7 +248,9 @@ NS_IMETHODIMP imgTools::EncodeCroppedImage(imgIContainer *aContainer, } // Use frame 0 from the image container. - RefPtr frame = GetFirstImageFrame(aContainer); + RefPtr frame = + aContainer->GetFrame(imgIContainer::FRAME_FIRST, + imgIContainer::FLAG_SYNC_DECODE); NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE); int32_t frameWidth = frame->GetSize().width; diff --git a/ipc/netd/Netd.cpp b/ipc/netd/Netd.cpp index 48135f934d14..0bedac7ceb5b 100644 --- a/ipc/netd/Netd.cpp +++ b/ipc/netd/Netd.cpp @@ -16,6 +16,7 @@ #include "nsAutoPtr.h" #include "nsString.h" #include "nsThreadUtils.h" +#include "mozilla/RefPtr.h" #define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args) diff --git a/ipc/netd/Netd.h b/ipc/netd/Netd.h index d9481b815009..31d0dc03cc13 100644 --- a/ipc/netd/Netd.h +++ b/ipc/netd/Netd.h @@ -5,7 +5,7 @@ #ifndef mozilla_system_netd_h__ #define mozilla_system_netd_h__ -#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" #include "nsAutoPtr.h" #include "base/message_loop.h" #include "mozilla/FileUtils.h" @@ -26,11 +26,14 @@ struct NetdCommand size_t mSize; }; -class NetdConsumer : public mozilla::RefCounted +class NetdConsumer { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(NetdConsumer) +protected: virtual ~NetdConsumer() { } + +public: + NS_INLINE_DECL_REFCOUNTING(NetdConsumer) + virtual void MessageReceived(NetdCommand* aMessage) = 0; }; @@ -39,15 +42,15 @@ class NetdWriteTask : public Task virtual void Run(); }; -class NetdClient : public MessageLoopForIO::LineWatcher, - public RefCounted +class NetdClient : public MessageLoopForIO::LineWatcher { + virtual ~NetdClient(); + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(NetdClient) + NS_INLINE_DECL_REFCOUNTING(NetdClient) typedef std::queue NetdCommandQueue; NetdClient(); - virtual ~NetdClient(); static void Start(); static void SendNetdCommandIOThread(NetdCommand* aMessage); diff --git a/ipc/unixsocket/UnixSocket.h b/ipc/unixsocket/UnixSocket.h index 46b3553803f2..7e643906fc22 100644 --- a/ipc/unixsocket/UnixSocket.h +++ b/ipc/unixsocket/UnixSocket.h @@ -135,14 +135,16 @@ enum SocketConnectionStatus { SOCKET_CONNECTED = 3 }; -class UnixSocketConsumer : public AtomicRefCounted +class UnixSocketConsumer { -public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(UnixSocketConsumer) - UnixSocketConsumer(); - +protected: virtual ~UnixSocketConsumer(); +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UnixSocketConsumer) + + UnixSocketConsumer(); + SocketConnectionStatus GetConnectionStatus() const { MOZ_ASSERT(NS_IsMainThread()); diff --git a/js/ipc/JavaScriptChild.cpp b/js/ipc/JavaScriptChild.cpp index 0958eb3368cc..c554f9a108ac 100644 --- a/js/ipc/JavaScriptChild.cpp +++ b/js/ipc/JavaScriptChild.cpp @@ -439,6 +439,8 @@ JavaScriptChild::AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs, boo if (!obj) return false; + JSAutoCompartment comp(cx, obj); + bool extensible; if (!JS_IsExtensible(cx, obj, &extensible)) return fail(cx, rs); diff --git a/js/src/jit-test/tests/ion/bug892794.js b/js/src/jit-test/tests/ion/bug892794.js new file mode 100644 index 000000000000..25b9f8459fa5 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug892794.js @@ -0,0 +1,13 @@ +// |jit-test| ion-eager + +function test0(v) { + return (2147483648-Math.max(1.1,-(((2<<(-v|v))-3)|0)))|0; +} +assertEq(test0(1.6), 2147483645); +assertEq(test0(437348122.9), 2147483646); + +function test1(v) { + return (2147483648+Math.min(v,0))|0; +} +assertEq(test1(2.1), -2147483648) +assertEq(test1(-0.1), 2147483647) diff --git a/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js b/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js index b93f79640880..873a8771675b 100644 --- a/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js +++ b/js/src/jit-test/tests/proxy/testDirectProxyConstruct2.js @@ -1,6 +1,9 @@ +load(libdir + "asserts.js"); /* * Call the trap with the handler as the this value, the target as the first * argument, and the original arguments as the third argument. + * + * Hooks that don't return an object must throw. */ var target = function () {}; var handler = { @@ -12,4 +15,4 @@ var handler = { assertEq(args[1], 3); } } -assertEq(new (new Proxy(target, handler))(2, 3), undefined); +assertThrowsInstanceOf(function () {new (new Proxy(target, handler))(2, 3)}, TypeError); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 67bc19745803..ac4769262606 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -4374,6 +4374,7 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler &masm) // Load function in scratchReg and ensure that it has a jit script. masm.loadPtr(Address(BaselineStubReg, ICGetElemNativeGetterStub::offsetOfGetter()), scratchReg); + masm.branchIfFunctionHasNoScript(scratchReg, popR1 ? &failurePopR1 : &failure); masm.loadPtr(Address(scratchReg, JSFunction::offsetOfNativeOrScript()), scratchReg); masm.loadBaselineOrIonRaw(scratchReg, scratchReg, SequentialExecution, popR1 ? &failurePopR1 : &failure); @@ -4805,6 +4806,22 @@ ICGetElem_Arguments::Compiler::generateStubCode(MacroAssembler &masm) // SetElem_Fallback // +static bool +SetElemDenseAddHasSameShapes(ICSetElem_DenseAdd *stub, JSObject *obj) +{ + size_t numShapes = stub->protoChainDepth() + 1; + for (size_t i = 0; i < numShapes; i++) { + static const size_t MAX_DEPTH = ICSetElem_DenseAdd::MAX_PROTO_CHAIN_DEPTH; + if (obj->lastProperty() != stub->toImplUnchecked()->shape(i)) + return false; + obj = obj->getProto(); + if (!obj && i != numShapes - 1) + return false; + } + + return true; +} + static bool DenseSetElemStubExists(JSContext *cx, ICStub::Kind kind, ICSetElem_Fallback *stub, HandleObject obj) { @@ -4819,11 +4836,8 @@ DenseSetElemStubExists(JSContext *cx, ICStub::Kind kind, ICSetElem_Fallback *stu if (kind == ICStub::SetElem_DenseAdd && iter->isSetElem_DenseAdd()) { ICSetElem_DenseAdd *dense = iter->toSetElem_DenseAdd(); - if (obj->lastProperty() == dense->toImplUnchecked<0>()->shape(0) && - obj->getType(cx) == dense->type()) - { + if (obj->getType(cx) == dense->type() && SetElemDenseAddHasSameShapes(dense, obj)) return true; - } } } return false; diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index f86e6d363bf1..cf0c71c5c01a 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -3555,6 +3555,7 @@ class ICSetElem_DenseAdd : public ICUpdatedStub return type_; } size_t protoChainDepth() const { + MOZ_ASSERT(extra_ <= MAX_PROTO_CHAIN_DEPTH); return extra_; } diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 5d4815caee04..a1cae7ce80ca 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -3016,9 +3016,6 @@ AutoDebugModeInvalidation::~AutoDebugModeInvalidation() if (needInvalidation_ == NoNeed) return; - // Invalidate the stack if any compartments toggled from on->off, because - // we allow scripts to be on stack when turning off debug mode. - bool invalidateStack = needInvalidation_ == ToggledOff; Zone *zone = zone_ ? zone_ : comp_->zone(); JSRuntime *rt = zone->runtimeFromMainThread(); FreeOp *fop = rt->defaultFreeOp(); @@ -3030,31 +3027,24 @@ AutoDebugModeInvalidation::~AutoDebugModeInvalidation() StopAllOffThreadCompilations(comp); } - if (invalidateStack) { - jit::MarkActiveBaselineScripts(zone); + jit::MarkActiveBaselineScripts(zone); - for (JitActivationIterator iter(rt); !iter.done(); ++iter) { - JSCompartment *comp = iter.activation()->compartment(); - if ((comp_ && comp_ == comp) || - (zone_ && zone_ == comp->zone() && comp->principals)) - { - IonContext ictx(CompileRuntime::get(rt)); - AutoFlushCache afc("AutoDebugModeInvalidation", rt->jitRuntime()); - IonSpew(IonSpew_Invalidate, "Invalidating frames for debug mode toggle"); - InvalidateActivation(fop, iter.jitTop(), true); - } + for (JitActivationIterator iter(rt); !iter.done(); ++iter) { + JSCompartment *comp = iter.activation()->compartment(); + if ((comp_ && comp_ == comp) || (zone_ && zone_ == comp->zone())) { + IonContext ictx(CompileRuntime::get(rt)); + AutoFlushCache afc("AutoDebugModeInvalidation", rt->jitRuntime()); + IonSpew(IonSpew_Invalidate, "Invalidating frames for debug mode toggle"); + InvalidateActivation(fop, iter.jitTop(), true); } } for (gc::CellIter i(zone, gc::FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get(); - if ((comp_ && script->compartment() == comp_) || - (zone_ && script->compartment()->principals)) - { + if ((comp_ && script->compartment() == comp_) || zone_) { FinishInvalidation(fop, script); FinishInvalidation(fop, script); FinishDiscardBaselineScript(fop, script); - // script->clearAnalysis(); script->resetUseCount(); } else if (script->hasBaselineScript()) { script->baselineScript()->resetActive(); diff --git a/js/src/js.msg b/js/src/js.msg index 65f50e7f7eb3..eab7c9b51092 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -437,3 +437,5 @@ MSG_DEF(JSMSG_SETPROTOTYPEOF_FAIL, 382, 1, JSEXN_TYPEERR, "[[SetPrototypeOf MSG_DEF(JSMSG_INVALID_ARG_TYPE, 383, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}") MSG_DEF(JSMSG_TERMINATED, 384, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}") MSG_DEF(JSMSG_NO_SUCH_SELF_HOSTED_PROP, 385, 1, JSEXN_ERR, "No such property on self-hosted object: {0}") +MSG_DEF(JSMSG_PROXY_EXTENSIBILITY, 386, 0, JSEXN_TYPEERR, "proxy must report same extensiblitity as target") +MSG_DEF(JSMSG_PROXY_CONSTRUCT_OBJECT, 387, 0, JSEXN_TYPEERR, "proxy [[Construct]] must return an object") diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index 62af5faffc10..74ada0855bdd 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -1077,12 +1077,6 @@ ScriptedIndirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, un ScriptedIndirectProxyHandler ScriptedIndirectProxyHandler::singleton; -static JSObject * -GetDirectProxyHandlerObject(JSObject *proxy) -{ - return proxy->as().extra(0).toObjectOrNull(); -} - /* Derived class for all scripted direct proxy handlers. */ class ScriptedDirectProxyHandler : public DirectProxyHandler { public: @@ -1114,6 +1108,9 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler { virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) MOZ_OVERRIDE; + /* ES6 Harmony traps */ + virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE; + /* Spidermonkey extensions. */ virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE; @@ -1365,6 +1362,16 @@ IdToValue(JSContext *cx, HandleId id, MutableHandleValue value) return true; } +// Get the [[ProxyHandler]] of a scripted direct proxy. +// +// NB: This *must* stay synched with proxy(). +static JSObject * +GetDirectProxyHandlerObject(JSObject *proxy) +{ + JS_ASSERT(proxy->as().handler() == &ScriptedDirectProxyHandler::singleton); + return proxy->as().extra(0).toObjectOrNull(); +} + // TrapGetOwnProperty(O, P) static bool TrapGetOwnProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue rval) @@ -2225,6 +2232,42 @@ ScriptedDirectProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector return ArrayToIdVector(cx, proxy, target, trapResult, props, JSITER_OWNONLY, cx->names().keys); } +// ES6 (5 April, 2014) 9.5.3 Proxy.[[IsExtensible]](P) +bool +ScriptedDirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) +{ + RootedObject handler(cx, GetDirectProxyHandlerObject(proxy)); + + RootedObject target(cx, proxy->as().target()); + + RootedValue trap(cx); + if (!JSObject::getProperty(cx, handler, handler, cx->names().isExtensible, &trap)) + return false; + + if (trap.isUndefined()) + return DirectProxyHandler::isExtensible(cx, proxy, extensible); + + Value argv[] = { + ObjectValue(*target) + }; + RootedValue trapResult(cx); + if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult)) + return false; + + bool booleanTrapResult = ToBoolean(trapResult); + bool targetResult; + if (!JSObject::isExtensible(cx, target, &targetResult)) + return false; + + if (targetResult != booleanTrapResult) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_EXTENSIBILITY); + return false; + } + + *extensible = booleanTrapResult; + return true; +} + bool ScriptedDirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp) @@ -2305,7 +2348,13 @@ ScriptedDirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const C ObjectValue(*argsArray) }; RootedValue thisValue(cx, ObjectValue(*handler)); - return Invoke(cx, thisValue, trap, ArrayLength(constructArgv), constructArgv, args.rval()); + if (!Invoke(cx, thisValue, trap, ArrayLength(constructArgv), constructArgv, args.rval())) + return false; + if (!args.rval().isObject()) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_CONSTRUCT_OBJECT); + return false; + } + return true; } ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton; diff --git a/js/src/tests/ecma_6/Proxy/proxy-constructNonObject.js b/js/src/tests/ecma_6/Proxy/proxy-constructNonObject.js new file mode 100644 index 000000000000..04cee11e963a --- /dev/null +++ b/js/src/tests/ecma_6/Proxy/proxy-constructNonObject.js @@ -0,0 +1,18 @@ +function bogusConstruct(target) { return 4; } +function bogusConstructUndefined(target) { } + +var handler = { construct: bogusConstruct } + +function callable() {} + +var p = new Proxy(callable, handler); + +assertThrowsInstanceOf(function () { new p(); }, TypeError, + "[[Construct must throw if an object is not returned."); + +handler.construct = bogusConstructUndefined; +assertThrowsInstanceOf(function () { new p(); }, TypeError, + "[[Construct must throw if an object is not returned."); + +if (typeof reportCompare === "function") + reportCompare(0,0, "OK"); diff --git a/js/src/tests/ecma_6/Proxy/proxy-isExtensible.js b/js/src/tests/ecma_6/Proxy/proxy-isExtensible.js new file mode 100644 index 000000000000..0317c377e87f --- /dev/null +++ b/js/src/tests/ecma_6/Proxy/proxy-isExtensible.js @@ -0,0 +1,94 @@ +// Test ES6 Proxy trap compliance for Object.isExtensible() on exotic proxy +// objects. +var unsealed = {}; +var sealed = Object.seal({}); +var handler = {}; + +assertEq(Object.isExtensible(unsealed), true); +assertEq(Object.isExtensible(sealed), false); + +var targetSealed = new Proxy(sealed, handler); +var targetUnsealed = new Proxy(unsealed, handler); + +var handlerCalled = false; + +// without traps, forward to the target +// First, make sure we get the obvious answer on a non-exotic target. +assertEq(Object.isExtensible(targetSealed), false, "Must forward to target without hook."); +assertEq(Object.isExtensible(targetUnsealed), true, "Must forward to target without hook."); + +// Now, keep everyone honest. What if the target itself is a proxy? +function ensureCalled() { handlerCalled = true; return true; } +var proxyTarget = new Proxy({}, { isExtensible : ensureCalled }); +assertEq(Object.isExtensible(new Proxy(proxyTarget, {})), true, "Must forward to target without hook."); +assertEq(handlerCalled, true, "Must forward to target without hook."); + +// with traps, makes sure that the handler is called, and that we throw if the +// trap disagrees with the target +function testExtensible(obj, shouldThrow, expectedResult) +{ + handlerCalled = false; + if (shouldThrow) + assertThrowsInstanceOf(function () { Object.isExtensible(obj); }, + TypeError, "Must throw if handler and target disagree."); + else + assertEq(Object.isExtensible(obj), expectedResult, "Must return the correct value."); + assertEq(handlerCalled, true, "Must call handler trap if present"); +} + +// What if the trap says it's necessarily sealed? +function fakeSealed() { handlerCalled = true; return false; } +handler.isExtensible = fakeSealed; +testExtensible(targetSealed, false, false); +testExtensible(targetUnsealed, true); + +// What if the trap says it's never sealed? +function fakeUnsealed() { handlerCalled = true; return true; } +handler.isExtensible = fakeUnsealed; +testExtensible(targetSealed, true); +testExtensible(targetUnsealed, false, true); + +// make sure we are able to prevent further extensions mid-flight and throw if the +// hook tries to lie. +function makeSealedTruth(target) { handlerCalled = true; Object.preventExtensions(target); return false; } +function makeSealedLie(target) { handlerCalled = true; Object.preventExtensions(target); return true; } +handler.isExtensible = makeSealedTruth; +testExtensible(new Proxy({}, handler), false, false); +handler.isExtensible = makeSealedLie; +testExtensible(new Proxy({}, handler), true); + +// What if the trap doesn't directly return a boolean? +function falseyNonBool() { handlerCalled = true; return undefined; } +handler.isExtensible = falseyNonBool; +testExtensible(targetSealed, false, false); +testExtensible(targetUnsealed, true); + +function truthyNonBool() { handlerCalled = true; return {}; } +handler.isExtensible = truthyNonBool; +testExtensible(targetSealed, true); +testExtensible(targetUnsealed, false, true); + +// What if the trap throws? +function ExtensibleError() { } +ExtensibleError.prototype = new Error(); +ExtensibleError.prototype.constructor = ExtensibleError; +function throwFromTrap() { throw new ExtensibleError(); } +handler.isExtensible = throwFromTrap; + +// exercise some other code paths and make sure that they invoke the trap and +// can handle the ensuing error. +assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); }, + ExtensibleError, "Must throw if the trap does."); +assertThrowsInstanceOf(function () { Object.isFrozen(targetSealed); }, + ExtensibleError, "Must throw if the trap does."); +assertThrowsInstanceOf(function () { Object.isSealed(targetSealed); }, + ExtensibleError, "Must throw if the trap does."); + + +// What if the trap likes to re-ask old questions? +function recurse() { return Object.isExtensible(targetSealed); } +handler.isExtensible = recurse; +assertThrowsInstanceOf(function () { Object.isExtensible(targetSealed); }, + InternalError, "Should allow and detect infinite recurison."); + +reportCompare(0, 0, "OK"); diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h index 9d99223ae69a..42df723bfc2a 100644 --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -103,6 +103,7 @@ macro(int8, int8, "int8") \ macro(int16, int16, "int16") \ macro(int32, int32, "int32") \ + macro(isExtensible, isExtensible, "isExtensible") \ macro(iterator, iterator, "iterator") \ macro(iteratorIntrinsic, iteratorIntrinsic, "__iterator__") \ macro(join, join, "join") \ diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h index e576dfd348f9..2ef8726a7031 100644 --- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -286,7 +286,7 @@ macro(JSOP_UNUSED52, 52, "unused52", NULL, 1, 0, 0, JOF_BYTE) \ \ macro(JSOP_GETPROP, 53, "getprop", NULL, 5, 1, 1, JOF_ATOM|JOF_PROP|JOF_TYPESET|JOF_TMPSLOT3) \ - macro(JSOP_SETPROP, 54, "setprop", NULL, 5, 2, 1, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING|JOF_TMPSLOT) \ + macro(JSOP_SETPROP, 54, "setprop", NULL, 5, 2, 1, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) \ macro(JSOP_GETELEM, 55, "getelem", NULL, 1, 2, 1, JOF_BYTE |JOF_ELEM|JOF_TYPESET|JOF_LEFTASSOC) \ macro(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_DETECTING) \ macro(JSOP_UNUSED57, 57, "unused57", NULL, 1, 0, 0, JOF_BYTE) \ diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index e9e6ce865ddc..1581557da120 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -46,9 +46,10 @@ enum LayerState { LAYER_SVG_EFFECTS }; -class RefCountedRegion : public RefCounted { +class RefCountedRegion { public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(RefCountedRegion) + NS_INLINE_DECL_REFCOUNTING(RefCountedRegion) + RefCountedRegion() : mIsInfinite(false) {} nsRegion mRegion; bool mIsInfinite; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index f474595c9b16..15ee803a1e7b 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5397,21 +5397,12 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement, return result; if (!noRasterize || imgContainer->GetType() == imgIContainer::TYPE_RASTER) { - bool wantImageSurface = (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) != 0; - if (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA) { - wantImageSurface = true; - } - - nsRefPtr gfxsurf = - imgContainer->GetFrame(whichFrame, frameFlags); - if (!gfxsurf) - return result; - - if (wantImageSurface) { - result.mSourceSurface = gfxPlatform::GetPlatform()->GetWrappedDataSourceSurface(gfxsurf); + if (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) { + frameFlags |= imgIContainer::FLAG_WANT_DATA_SURFACE; } + result.mSourceSurface = imgContainer->GetFrame(whichFrame, frameFlags); if (!result.mSourceSurface) { - result.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, gfxsurf); + return result; } } else { result.mDrawInfo.mImgContainer = imgContainer; diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index 8cc543d150ad..1985b54703b1 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -1084,7 +1084,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = { { "@mozilla.org/inspector/deep-tree-walker;1", &kIN_DEEPTREEWALKER_CID }, { "@mozilla.org/inspector/flasher;1", &kIN_FLASHER_CID }, { "@mozilla.org/inspector/search;1?type=cssvalue", &kIN_CSSVALUESEARCH_CID }, - { "@mozilla.org/inspector/dom-utils;1", &kIN_DOMUTILS_CID }, + { IN_DOMUTILS_CONTRACTID, &kIN_DOMUTILS_CID }, { "@mozilla.org/xml/xml-document;1", &kNS_XMLDOCUMENT_CID }, { "@mozilla.org/svg/svg-document;1", &kNS_SVGDOCUMENT_CID }, { NS_DOMMULTIPARTBLOB_CONTRACTID, &kNS_DOMMULTIPARTBLOB_CID }, diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 951aacc4eb48..1e8e9d95a540 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -215,7 +215,7 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder, nsPoint offset = ToReferenceFrame(); nsRect bgClipRect = frame->CanvasArea() + offset; - nsRenderingContext context; + nsRefPtr context; nsRefPtr dest = aCtx->ThebesContext(); nsRefPtr surf; RefPtr dt; @@ -254,13 +254,14 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder, ctx = new gfxContext(dt); } ctx->Translate(-gfxPoint(destRect.x, destRect.y)); - context.Init(aCtx->DeviceContext(), ctx); + context = new nsRenderingContext(); + context->Init(aCtx->DeviceContext(), ctx); } } #endif PaintInternal(aBuilder, - (surf || dt) ? &context : aCtx, + (surf || dt) ? context.get() : aCtx, (surf || dt) ? bgClipRect: mVisibleRect, &bgClipRect); diff --git a/layout/inspector/inDOMView.cpp b/layout/inspector/inDOMView.cpp index 5dc616b86c3e..46288310d61d 100644 --- a/layout/inspector/inDOMView.cpp +++ b/layout/inspector/inDOMView.cpp @@ -24,6 +24,7 @@ #include "nsITreeColumns.h" #include "nsITreeBoxObject.h" #include "mozilla/dom/Element.h" +#include "mozilla/Services.h" #ifdef ACCESSIBILITY #include "nsIAccessible.h" @@ -790,7 +791,7 @@ inDOMView::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer, nsCOMPtr childDOMNode(do_QueryInterface(aChild)); nsCOMPtr parent; if (!mDOMUtils) { - mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1"); + mDOMUtils = services::GetInDOMUtils(); if (!mDOMUtils) { return; } @@ -1189,7 +1190,7 @@ inDOMView::GetChildNodesFor(nsIDOMNode* aNode, nsCOMArray& aResult) if (mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT) { nsCOMPtr kids; if (!mDOMUtils) { - mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1"); + mDOMUtils = services::GetInDOMUtils(); if (!mDOMUtils) { return NS_ERROR_FAILURE; } @@ -1234,7 +1235,7 @@ inDOMView::AppendKidsToArray(nsIDOMNodeList* aKids, // Try and get DOM Utils in case we don't have one yet. if (!mShowWhitespaceNodes && !mDOMUtils) { - mDOMUtils = do_CreateInstance("@mozilla.org/inspector/dom-utils;1"); + mDOMUtils = services::GetInDOMUtils(); } for (uint32_t i = 0; i < l; ++i) { diff --git a/layout/inspector/inIDOMUtils.idl b/layout/inspector/inIDOMUtils.idl index b2a609a0bfda..c42dedd15d0a 100644 --- a/layout/inspector/inIDOMUtils.idl +++ b/layout/inspector/inIDOMUtils.idl @@ -104,3 +104,7 @@ interface inIDOMUtils : nsISupports */ void parseStyleSheet(in nsIDOMCSSStyleSheet aSheet, in DOMString aInput); }; + +%{ C++ +#define IN_DOMUTILS_CONTRACTID "@mozilla.org/inspector/dom-utils;1" +%} diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 742a42a8a9e5..c5a841ef106f 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -658,33 +658,20 @@ public: return true; } - virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid) + virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, + APZStateChange aChange, + int aArg) { if (MessageLoop::current() != mUILoop) { mUILoop->PostTask( FROM_HERE, - NewRunnableMethod(this, &RemoteContentController::NotifyTransformBegin, - aGuid)); + NewRunnableMethod(this, &RemoteContentController::NotifyAPZStateChange, + aGuid, aChange, aArg)); return; } if (mRenderFrame) { TabParent* browser = static_cast(mRenderFrame->Manager()); - browser->NotifyTransformBegin(aGuid.mScrollId); - } - } - - virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid) - { - if (MessageLoop::current() != mUILoop) { - mUILoop->PostTask( - FROM_HERE, - NewRunnableMethod(this, &RemoteContentController::NotifyTransformEnd, - aGuid)); - return; - } - if (mRenderFrame) { - TabParent* browser = static_cast(mRenderFrame->Manager()); - browser->NotifyTransformEnd(aGuid.mScrollId); + browser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg); } } diff --git a/layout/svg/nsFilterInstance.cpp b/layout/svg/nsFilterInstance.cpp index 5debe7efcb51..4a99eca59c45 100644 --- a/layout/svg/nsFilterInstance.cpp +++ b/layout/svg/nsFilterInstance.cpp @@ -318,11 +318,11 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource, ctx->Translate(-neededRect.TopLeft()); - nsRenderingContext tmpCtx; - tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx); + nsRefPtr tmpCtx(new nsRenderingContext()); + tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx); gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert(); - gfxContext *gfx = tmpCtx.ThebesContext(); + gfxContext *gfx = tmpCtx->ThebesContext(); gfx->Multiply(deviceToFilterSpace); gfx->Save(); @@ -401,8 +401,8 @@ nsFilterInstance::BuildSourceImage(gfxASurface* aTargetSurface, ctx->Translate(-neededRect.TopLeft()); - nsRenderingContext tmpCtx; - tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx); + nsRefPtr tmpCtx(new nsRenderingContext()); + tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx); gfxRect r = FilterSpaceToUserSpace(neededRect); r.RoundOut(); @@ -422,8 +422,8 @@ nsFilterInstance::BuildSourceImage(gfxASurface* aTargetSurface, // code more complex while being hard to get right without introducing // subtle bugs, and in practice it probably makes no real difference.) gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert(); - tmpCtx.ThebesContext()->Multiply(deviceToFilterSpace); - mPaintCallback->Paint(&tmpCtx, mTargetFrame, &dirty, mTransformRoot); + tmpCtx->ThebesContext()->Multiply(deviceToFilterSpace); + mPaintCallback->Paint(tmpCtx, mTargetFrame, &dirty, mTransformRoot); RefPtr sourceGraphicSource; diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index 131c2da5c6d4..05af41ac7473 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -605,8 +605,8 @@ PaintFrameCallback::operator()(gfxContext* aContext, mFrame->AddStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER); - nsRenderingContext context; - context.Init(mFrame->PresContext()->DeviceContext(), aContext); + nsRefPtr context(new nsRenderingContext()); + context->Init(mFrame->PresContext()->DeviceContext(), aContext); aContext->Save(); // Clip to aFillRect so that we don't paint outside. @@ -644,7 +644,7 @@ PaintFrameCallback::operator()(gfxContext* aContext, if (mFlags & nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES) { flags |= nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES; } - nsLayoutUtils::PaintFrame(&context, mFrame, + nsLayoutUtils::PaintFrame(context, mFrame, dirty, NS_RGBA(0, 0, 0, 0), flags); diff --git a/layout/svg/nsSVGMaskFrame.cpp b/layout/svg/nsSVGMaskFrame.cpp index 690550d18903..4ce0cc093f68 100644 --- a/layout/svg/nsSVGMaskFrame.cpp +++ b/layout/svg/nsSVGMaskFrame.cpp @@ -226,9 +226,9 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRenderingContext *aContext, gfxMatrix matrix = gfx->CurrentMatrix() * gfxMatrix().Translate(-clipExtents.TopLeft()); - nsRenderingContext tmpCtx; - tmpCtx.Init(this->PresContext()->DeviceContext(), image); - tmpCtx.ThebesContext()->SetMatrix(matrix); + nsRefPtr tmpCtx(new nsRenderingContext); + tmpCtx->Init(this->PresContext()->DeviceContext(), image); + tmpCtx->ThebesContext()->SetMatrix(matrix); mMaskParent = aParent; if (mMaskParentMatrix) { @@ -244,7 +244,7 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRenderingContext *aContext, if (SVGFrame) { SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED); } - nsSVGUtils::PaintFrameWithEffects(&tmpCtx, nullptr, kid); + nsSVGUtils::PaintFrameWithEffects(tmpCtx, nullptr, kid); } uint8_t *data = image->Data(); diff --git a/layout/svg/nsSVGPatternFrame.cpp b/layout/svg/nsSVGPatternFrame.cpp index e4f62b6b831e..fa35d73fb289 100644 --- a/layout/svg/nsSVGPatternFrame.cpp +++ b/layout/svg/nsSVGPatternFrame.cpp @@ -372,9 +372,9 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface, if (!tmpSurface || tmpSurface->CairoStatus()) return NS_ERROR_FAILURE; - nsRenderingContext context; - context.Init(aSource->PresContext()->DeviceContext(), tmpSurface); - gfxContext* gfx = context.ThebesContext(); + nsRefPtr context(new nsRenderingContext()); + context->Init(aSource->PresContext()->DeviceContext(), tmpSurface); + gfxContext* gfx = context->ThebesContext(); // Fill with transparent black gfx->SetOperator(gfxContext::OPERATOR_CLEAR); @@ -406,7 +406,7 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface, if (SVGFrame) { SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED); } - nsSVGUtils::PaintFrameWithEffects(&context, nullptr, kid); + nsSVGUtils::PaintFrameWithEffects(context, nullptr, kid); } patternFrame->RemoveStateBits(NS_FRAME_DRAWING_AS_PAINTSERVER); } diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index f80b8a567469..5f10e68a87a4 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1471,11 +1471,12 @@ nsSVGUtils::PaintSVGGlyph(Element* aElement, gfxContext* aContext, if (!svgFrame) { return false; } - nsRenderingContext context; - context.Init(frame->PresContext()->DeviceContext(), aContext); - context.AddUserData(&gfxTextContextPaint::sUserDataKey, aContextPaint, nullptr); + nsRefPtr context(new nsRenderingContext()); + context->Init(frame->PresContext()->DeviceContext(), aContext); + context->AddUserData(&gfxTextContextPaint::sUserDataKey, aContextPaint, + nullptr); svgFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED); - nsresult rv = svgFrame->PaintSVG(&context, nullptr, frame); + nsresult rv = svgFrame->PaintSVG(context, nullptr, frame); return NS_SUCCEEDED(rv); } diff --git a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c index 49bad4a710d8..48850155afa8 100644 --- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c +++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp_token.c @@ -1578,7 +1578,7 @@ sdp_result_e sdp_build_media (sdp_t *sdp_p, u16 level, flex_string *fs) } } else { /* Add port to SDP if transport is DTLS/SCTP */ - flex_string_sprintf(fs, " %u ", (u32)mca_p->sctpport); + flex_string_sprintf(fs, " %u", (u32)mca_p->sctpport); } flex_string_sprintf(fs, "\r\n"); diff --git a/media/webrtc/signaling/test/signaling_unittests.cpp b/media/webrtc/signaling/test/signaling_unittests.cpp index b0d0566230b6..0a428e19f957 100644 --- a/media/webrtc/signaling/test/signaling_unittests.cpp +++ b/media/webrtc/signaling/test/signaling_unittests.cpp @@ -2817,7 +2817,7 @@ TEST_F(SignalingTest, missingUfrag) "a=candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ host\r\n" "a=candidate:1 2 UDP 1694236670 77.9.79.167 50769 typ srflx raddr " "192.168.178.20 rport 50769\r\n" - "m=application 54054 DTLS/SCTP 5000 \r\n" + "m=application 54054 DTLS/SCTP 5000\r\n" "c=IN IP4 77.9.79.167\r\n" "a=fmtp:HuRUu]Dtcl\\zM,7(OmEU%O$gU]x/z\tD protocol=webrtc-datachannel;" "streams=16\r\n" diff --git a/netwerk/base/src/NetworkActivityMonitor.cpp b/netwerk/base/src/NetworkActivityMonitor.cpp index 5c940058b046..71086022be02 100644 --- a/netwerk/base/src/NetworkActivityMonitor.cpp +++ b/netwerk/base/src/NetworkActivityMonitor.cpp @@ -151,18 +151,22 @@ nsNetMon_AcceptRead(PRFileDesc *listenSock, class NotifyNetworkActivity : public nsRunnable { public: - NotifyNetworkActivity(nsIObserverService* aObs, - NetworkActivityMonitor::Direction aDirection) - : mObs(aObs) - , mDirection(aDirection) + NotifyNetworkActivity(NetworkActivityMonitor::Direction aDirection) + : mDirection(aDirection) {} NS_IMETHOD Run() { - mObs->NotifyObservers(nullptr, - mDirection == NetworkActivityMonitor::kUpload - ? NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC - : NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC, - nullptr); + MOZ_ASSERT(NS_IsMainThread()); + + nsCOMPtr obs = mozilla::services::GetObserverService(); + if (!obs) + return NS_ERROR_FAILURE; + + obs->NotifyObservers(nullptr, + mDirection == NetworkActivityMonitor::kUpload + ? NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC + : NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC, + nullptr); return NS_OK; } private: @@ -176,12 +180,15 @@ NetworkActivityMonitor::NetworkActivityMonitor() : mLayerIdentity(PR_INVALID_IO_LAYER) , mBlipInterval(PR_INTERVAL_NO_TIMEOUT) { + MOZ_COUNT_CTOR(NetworkActivityMonitor); + NS_ASSERTION(gInstance==nullptr, "multiple NetworkActivityMonitor instances!"); } NetworkActivityMonitor::~NetworkActivityMonitor() { + MOZ_COUNT_DTOR(NetworkActivityMonitor); gInstance = nullptr; } @@ -229,10 +236,6 @@ NetworkActivityMonitor::Init_Internal(int32_t blipInterval) mLayerMethods.sendto = nsNetMon_SendTo; mLayerMethods.acceptread = nsNetMon_AcceptRead; - mObserverService = mozilla::services::GetObserverService(); - if (!mObserverService) - return NS_ERROR_FAILURE; - mBlipInterval = PR_MillisecondsToInterval(blipInterval); // Set the last notification times to time that has just expired, so any // activity even right now will trigger notification. @@ -287,7 +290,6 @@ NetworkActivityMonitor::DataInOut(Direction direction) void NetworkActivityMonitor::PostNotification(Direction direction) { - nsRefPtr ev = new NotifyNetworkActivity(mObserverService, - direction); + nsRefPtr ev = new NotifyNetworkActivity(direction); NS_DispatchToMainThread(ev); } diff --git a/netwerk/base/src/NetworkActivityMonitor.h b/netwerk/base/src/NetworkActivityMonitor.h index 2c96f45021ff..26ecaffe321f 100644 --- a/netwerk/base/src/NetworkActivityMonitor.h +++ b/netwerk/base/src/NetworkActivityMonitor.h @@ -7,12 +7,11 @@ #ifndef NetworkActivityMonitor_h___ #define NetworkActivityMonitor_h___ -#include "nsCOMPtr.h" +#include +#include "nscore.h" #include "prio.h" #include "prinrval.h" -class nsIObserverService; - namespace mozilla { namespace net { class NetworkActivityMonitor @@ -41,7 +40,6 @@ private: PRIOMethods mLayerMethods; PRIntervalTime mBlipInterval; PRIntervalTime mLastNotificationTime[2]; - nsCOMPtr mObserverService; }; }} // namespace mozilla::net diff --git a/security/manager/ssl/src/SharedCertVerifier.h b/security/manager/ssl/src/SharedCertVerifier.h index 4e7e3510b5cf..32a92a3eb68f 100644 --- a/security/manager/ssl/src/SharedCertVerifier.h +++ b/security/manager/ssl/src/SharedCertVerifier.h @@ -11,11 +11,14 @@ namespace mozilla { namespace psm { -class SharedCertVerifier : public mozilla::psm::CertVerifier, - public mozilla::AtomicRefCounted +class SharedCertVerifier : public mozilla::psm::CertVerifier { +protected: + ~SharedCertVerifier(); + public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedCertVerifier) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedCertVerifier) + SharedCertVerifier(implementation_config ic, #ifndef NSS_NO_LIBPKIX missing_cert_download_config ac, crl_download_config cdc, @@ -29,7 +32,6 @@ public: odc, osc, ogc) { } - ~SharedCertVerifier(); }; } } // namespace mozilla::psm diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp index 75c7b755c7a8..16e8e2c5df1a 100644 --- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp @@ -139,8 +139,12 @@ GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, } SECItemArray* arr = SECITEM_AllocArray(aArena, nullptr, 1); - arr->items[0].data = response ? response->data : nullptr; - arr->items[0].len = response ? response->len : 0; + if (!arr) { + PrintPRError("SECITEM_AllocArray failed"); + return nullptr; + } + arr->items[0].data = response->data; + arr->items[0].len = response->len; return arr; } diff --git a/testing/xpcshell/head.js b/testing/xpcshell/head.js index f72719152c61..640ceb57dbda 100644 --- a/testing/xpcshell/head.js +++ b/testing/xpcshell/head.js @@ -19,6 +19,8 @@ var _cleanupFunctions = []; var _pendingTimers = []; var _profileInitialized = false; +let _Promise = Components.utils.import("resource://gre/modules/Promise.jsm", this).Promise; + let _log = function (action, params) { if (typeof _XPCSHELL_PROCESS != "undefined") { params.process = _XPCSHELL_PROCESS; @@ -180,7 +182,7 @@ function _do_main() { function _do_quit() { _log("test_info", {_message: "TEST-INFO | (xpcshell/head.js) | exiting test\n"}); - + _Promise.Debugging.flushUncaughtErrors(); _quit = true; } @@ -348,6 +350,15 @@ function _execute_test() { // Call do_get_idle() to restore the factory and get the service. _fakeIdleService.activate(); + _Promise.Debugging.clearUncaughtErrorObservers(); + _Promise.Debugging.addUncaughtErrorObserver(function observer({message, date, fileName, stack, lineNumber}) { + let text = "Once bug 976205 has landed, THIS ERROR WILL CAUSE A TEST FAILURE.\n" + + " A promise chain failed to handle a rejection: " + + message + " - rejection date: " + date; + _log_message_with_stack("test_known_fail", + text, stack, fileName); + }); + // _HEAD_FILES is dynamically defined by . _load_files(_HEAD_FILES); // _TEST_FILE is dynamically defined by . @@ -1428,10 +1439,12 @@ function run_next_test() "run_next_test() should not be called from inside add_task() " + "under any circumstances!"); } - + function _run_next_test() { if (_gTestIndex < _gTests.length) { + // Flush uncaught errors as early and often as possible. + _Promise.Debugging.flushUncaughtErrors(); let _isTask; [_isTask, _gRunningTest] = _gTests[_gTestIndex++]; print("TEST-INFO | " + _TEST_FILE + " | Starting " + _gRunningTest.name); diff --git a/toolkit/components/social/test/browser/browser.ini b/toolkit/components/social/test/browser/browser.ini index 781dfd5d1681..09f28ec25b40 100644 --- a/toolkit/components/social/test/browser/browser.ini +++ b/toolkit/components/social/test/browser/browser.ini @@ -19,6 +19,6 @@ support-files = # These tests are currently unreliable on ASAN builds with remote frameworkers. [browser_frameworker.js] -skip-if = asan || (os == 'linux' && debug) # Bug 994798 for Linux debug disabling +skip-if = asan || (os == 'linux' && debug) || (os == 'mac' && debug) # Bug 994798 for Linux debug disabling, bug 994300 for Mac debug disabling [browser_frameworker_sandbox.js] -skip-if = asan || (os == 'linux' && debug) # Bug 994798 for Linux debug disabling +skip-if = asan || (os == 'linux' && debug) || (os == 'mac' && debug) # Bug 994798 for Linux debug disabling, bug 994300 for Mac debug disabling diff --git a/toolkit/content/widgets/findbar.xml b/toolkit/content/widgets/findbar.xml index 9dc0d5ef76b8..d401bd159fd0 100644 --- a/toolkit/content/widgets/findbar.xml +++ b/toolkit/content/widgets/findbar.xml @@ -174,13 +174,6 @@ disabled="true" xbl:inherits="accesskey=findnextaccesskey"/> - - - - - + + + + thebesSurface = + RefPtr surface = image->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE); - if (!thebesSurface) { - continue; - } - RefPtr surface = - gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface( - gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget(), thebesSurface); if (!surface) { continue; } diff --git a/widget/cocoa/nsCocoaUtils.mm b/widget/cocoa/nsCocoaUtils.mm index dd59db27dd95..10aa9a7022f2 100644 --- a/widget/cocoa/nsCocoaUtils.mm +++ b/widget/cocoa/nsCocoaUtils.mm @@ -5,6 +5,7 @@ #include "gfxImageSurface.h" #include "gfxPlatform.h" +#include "gfxUtils.h" #include "nsCocoaUtils.h" #include "nsChildView.h" #include "nsMenuBarX.h" @@ -26,7 +27,12 @@ using namespace mozilla; using namespace mozilla::widget; +using mozilla::gfx::BackendType; using mozilla::gfx::DataSourceSurface; +using mozilla::gfx::DrawTarget; +using mozilla::gfx::Factory; +using mozilla::gfx::IntPoint; +using mozilla::gfx::IntRect; using mozilla::gfx::IntSize; using mozilla::gfx::SurfaceFormat; using mozilla::gfx::SourceSurface; @@ -278,10 +284,19 @@ void data_ss_release_callback(void *aDataSourceSurface, nsresult nsCocoaUtils::CreateCGImageFromSurface(SourceSurface* aSurface, CGImageRef* aResult) { - RefPtr dataSurface = aSurface->GetDataSurface(); + RefPtr dataSurface; - MOZ_ASSERT(dataSurface->GetFormat() == SurfaceFormat::B8G8R8A8, - "We assume B8G8R8A8 when calling CGImageCreate"); + if (aSurface->GetFormat() == SurfaceFormat::B8G8R8A8) { + dataSurface = aSurface->GetDataSurface(); + } else { + // CGImageCreate only supports 16- and 32-bit bit-depth + // Convert format to SurfaceFormat::B8G8R8A8 + dataSurface = gfxUtils:: + CopySurfaceToDataSourceSurfaceWithFormat(aSurface, + SurfaceFormat::B8G8R8A8); + } + + NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE); int32_t width = dataSurface->GetSize().width; int32_t height = dataSurface->GetSize().height; @@ -401,17 +416,7 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer *aImage, ui surface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, frame); } else { - nsRefPtr thebesSurface = - aImage->GetFrame(aWhichFrame, imgIContainer::FLAG_SYNC_DECODE); - NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE); - - nsRefPtr thebesImageSurface = - thebesSurface->GetAsReadableARGB32ImageSurface(); - NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE); - - surface = - gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, - thebesImageSurface); + surface = aImage->GetFrame(aWhichFrame, imgIContainer::FLAG_SYNC_DECODE); } NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm index d4fba7232e3c..25b6b8356a71 100644 --- a/widget/cocoa/nsMenuItemIconX.mm +++ b/widget/cocoa/nsMenuItemIconX.mm @@ -387,18 +387,14 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest) if (mImageRegionRect.IsEmpty()) { mImageRegionRect.SetRect(0, 0, origWidth, origHeight); } - - nsRefPtr thebesSurface = + + RefPtr surface = imageContainer->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE); - if (!thebesSurface) { + if (!surface) { [mNativeMenuItem setImage:nil]; return NS_ERROR_FAILURE; } - RefPtr surface = - gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, - thebesSurface); - NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); CGImageRef origImage = NULL; nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &origImage); diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp index 2d62c4937bad..9fd763c43052 100644 --- a/widget/gonk/HwcComposer2D.cpp +++ b/widget/gonk/HwcComposer2D.cpp @@ -242,10 +242,6 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer, if (ContainerLayer* container = aLayer->AsContainerLayer()) { - if (container->UseIntermediateSurface()) { - LOGD("Container layer needs intermediate surface"); - return false; - } nsAutoTArray children; container->SortChildrenBy3DZOrder(children); @@ -330,12 +326,24 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer, } HwcLayer& hwcLayer = mList->hwLayers[current]; + hwcLayer.flags = 0; + + if (ContainerLayer* parent = aLayer->GetParent()) { + if (parent->UseIntermediateSurface()) { + LOGD("Parent container needs intermediate surface"); + hwcLayer.flags = HWC_SKIP_LAYER; +#if ANDROID_VERSION < 18 + // No partial HWC Composition on older versions + return false; +#endif + } + } + hwcLayer.displayFrame = displayFrame; setCrop(&hwcLayer, sourceCrop); buffer_handle_t handle = fillColor ? nullptr : state.mSurface->getNativeBuffer()->handle; hwcLayer.handle = handle; - hwcLayer.flags = 0; hwcLayer.hints = 0; hwcLayer.blending = isOpaque ? HWC_BLENDING_NONE : HWC_BLENDING_PREMULT; #if ANDROID_VERSION >= 17 diff --git a/widget/gtk/nsImageToPixbuf.cpp b/widget/gtk/nsImageToPixbuf.cpp index bc5456302132..98b1f81f5d8d 100644 --- a/widget/gtk/nsImageToPixbuf.cpp +++ b/widget/gtk/nsImageToPixbuf.cpp @@ -43,7 +43,7 @@ nsImageToPixbuf::ConvertImageToPixbuf(imgIContainer* aImage) GdkPixbuf* nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage) { - nsRefPtr thebesSurface = + RefPtr surface = aImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE); @@ -51,15 +51,10 @@ nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage) // in an imgINotificationObserver event, meaning that we're not allowed request // a sync decode. Presumably the originating event is something sensible like // OnStopFrame(), so we can just retry the call without a sync decode. - if (!thebesSurface) - thebesSurface = aImage->GetFrame(imgIContainer::FRAME_CURRENT, - imgIContainer::FLAG_NONE); + if (!surface) + surface = aImage->GetFrame(imgIContainer::FRAME_CURRENT, + imgIContainer::FLAG_NONE); - NS_ENSURE_TRUE(thebesSurface, nullptr); - - RefPtr surface = - gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, - thebesSurface); NS_ENSURE_TRUE(surface, nullptr); return SourceSurfaceToPixbuf(surface, diff --git a/widget/qt/nsClipboard.cpp b/widget/qt/nsClipboard.cpp index e3d341a0211d..d79c83e8d612 100644 --- a/widget/qt/nsClipboard.cpp +++ b/widget/qt/nsClipboard.cpp @@ -179,15 +179,9 @@ nsClipboard::SetNativeClipboardData( nsITransferable *aTransferable, if (!image) // Not getting an image for an image mime type!? continue; - nsRefPtr thebesSurface = + RefPtr surface = image->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE); - if (!thebesSurface) - continue; - - RefPtr surface = - gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, - thebesSurface); if (!surface) continue; diff --git a/widget/windows/WinUtils.cpp b/widget/windows/WinUtils.cpp index ee224c5f8332..8f209080fe16 100644 --- a/widget/windows/WinUtils.cpp +++ b/widget/windows/WinUtils.cpp @@ -731,12 +731,8 @@ AsyncFaviconDataReady::OnComplete(nsIURI *aFaviconURI, getter_AddRefs(container)); NS_ENSURE_SUCCESS(rv, rv); - nsRefPtr imgFrame = - container->GetFrame(imgIContainer::FRAME_FIRST, 0); - NS_ENSURE_TRUE(imgFrame, NS_ERROR_FAILURE); - RefPtr surface = - gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, imgFrame); + container->GetFrame(imgIContainer::FRAME_FIRST, 0); NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); RefPtr dataSurface; diff --git a/widget/windows/nsImageClipboard.cpp b/widget/windows/nsImageClipboard.cpp index 0b6999c125ed..eb73df5f8682 100644 --- a/widget/windows/nsImageClipboard.cpp +++ b/widget/windows/nsImageClipboard.cpp @@ -3,10 +3,13 @@ * 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 "nsImageClipboard.h" + +#include "gfxUtils.h" #include "mozilla/gfx/2D.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" #include "mozilla/RefPtr.h" #include "nsITransferable.h" -#include "nsImageClipboard.h" #include "nsGfxCIID.h" #include "nsMemory.h" #include "prmem.h" @@ -120,22 +123,24 @@ nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap nsresult rv; *outBitmap = nullptr; - nsRefPtr thebesSurface = + RefPtr surface = inImage->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE); - NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); - nsRefPtr thebesImageSurface = - thebesSurface->GetAsReadableARGB32ImageSurface(); - NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE); + MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::B8G8R8A8 || + surface->GetFormat() == SurfaceFormat::B8G8R8X8); - IntSize surfaceSize(thebesImageSurface->GetSize().width, - thebesImageSurface->GetSize().height); - RefPtr dataSurface = - Factory::CreateWrappingDataSourceSurface(thebesImageSurface->Data(), - thebesImageSurface->Stride(), - surfaceSize, - SurfaceFormat::B8G8R8A8); + RefPtr dataSurface; + if (surface->GetFormat() == SurfaceFormat::B8G8R8A8) { + dataSurface = surface->GetDataSurface(); + } else { + // XXXjwatt Bug 995923 - get rid of this copy and handle B8G8R8X8 + // directly below once bug 995807 is fixed. + dataSurface = gfxUtils:: + CopySurfaceToDataSourceSurfaceWithFormat(surface, + SurfaceFormat::B8G8R8A8); + } NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE); nsCOMPtr encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/bmp", &rv); @@ -153,11 +158,15 @@ nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap format = imgIEncoder::INPUT_FORMAT_HOSTARGB; options.AppendInt(32); break; +#if 0 + // XXXjwatt Bug 995923 - fix |format| and reenable once bug 995807 is fixed. case SurfaceFormat::B8G8R8X8: format = imgIEncoder::INPUT_FORMAT_RGB; options.AppendInt(24); break; +#endif default: + NS_NOTREACHED("Unexpected surface format"); return NS_ERROR_INVALID_ARG; } diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp index 38d09b9d9dde..bdcbb9c01135 100644 --- a/widget/windows/nsWindowGfx.cpp +++ b/widget/windows/nsWindowGfx.cpp @@ -53,7 +53,6 @@ using mozilla::plugins::PluginInstanceParent; #include "nsUXThemeData.h" #include "nsUXThemeConstants.h" -#include "mozilla/gfx/2D.h" extern "C" { #define PIXMAN_DONT_DEFINE_STDINT @@ -616,31 +615,26 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer, (aScaledSize.width == 0 && aScaledSize.height == 0)); // Get the image data - nsRefPtr thebesSurface = + RefPtr surface = aContainer->GetFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_SYNC_DECODE); - NS_ENSURE_TRUE(thebesSurface, NS_ERROR_NOT_AVAILABLE); + NS_ENSURE_TRUE(surface, NS_ERROR_NOT_AVAILABLE); - RefPtr surface = - gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, - thebesSurface); - NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); - - IntSize surfaceSize(surface->GetSize().width, surface->GetSize().height); - if (surfaceSize.IsEmpty()) { + IntSize frameSize = surface->GetSize(); + if (frameSize.IsEmpty()) { return NS_ERROR_FAILURE; } IntSize iconSize(aScaledSize.width, aScaledSize.height); if (iconSize == IntSize(0, 0)) { // use frame's intrinsic size - iconSize = surfaceSize; + iconSize = frameSize; } RefPtr dataSurface; bool mappedOK; DataSourceSurface::MappedSurface map; - if (iconSize != surfaceSize) { + if (iconSize != frameSize) { // Scale the surface dataSurface = Factory::CreateDataSourceSurface(iconSize, SurfaceFormat::B8G8R8A8); @@ -656,7 +650,7 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer, SurfaceFormat::B8G8R8A8); dt->DrawSurface(surface, Rect(0, 0, iconSize.width, iconSize.height), - Rect(0, 0, surfaceSize.width, surfaceSize.height), + Rect(0, 0, frameSize.width, frameSize.height), DrawSurfaceOptions(), DrawOptions(1.0f, CompositionOp::OP_SOURCE)); } else if (surface->GetFormat() != SurfaceFormat::B8G8R8A8) { diff --git a/widget/windows/winrt/APZController.cpp b/widget/windows/winrt/APZController.cpp index 79f48554b4ae..c03f514cebd9 100644 --- a/widget/windows/winrt/APZController.cpp +++ b/widget/windows/winrt/APZController.cpp @@ -303,25 +303,37 @@ class TransformedEndEvent : public nsRunnable }; void -APZController::NotifyTransformBegin(const ScrollableLayerGuid& aGuid) +APZController::NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, + APZStateChange aChange, + int aArg) { - if (NS_IsMainThread()) { - MetroUtils::FireObserver("apzc-transform-begin", L""); - return; + switch (aChange) { + case APZStateChange::TransformBegin: + { + if (NS_IsMainThread()) { + MetroUtils::FireObserver("apzc-transform-begin", L""); + return; + } + nsCOMPtr runnable = new TransformedStartEvent(); + NS_DispatchToMainThread(runnable); + break; + } + case APZStateChange::TransformEnd: + { + if (NS_IsMainThread()) { + MetroUtils::FireObserver("apzc-transform-end", L""); + return; + } + nsCOMPtr runnable = new TransformedEndEvent(); + NS_DispatchToMainThread(runnable); + break; + } + default: + { + // We don't currently care about other state changes. + break; + } } - nsCOMPtr runnable = new TransformedStartEvent(); - NS_DispatchToMainThread(runnable); -} - -void -APZController::NotifyTransformEnd(const ScrollableLayerGuid& aGuid) -{ - if (NS_IsMainThread()) { - MetroUtils::FireObserver("apzc-transform-end", L""); - return; - } - nsCOMPtr runnable = new TransformedEndEvent(); - NS_DispatchToMainThread(runnable); } } } } diff --git a/widget/windows/winrt/APZController.h b/widget/windows/winrt/APZController.h index e17ee6db2a24..e41fe3bf7859 100644 --- a/widget/windows/winrt/APZController.h +++ b/widget/windows/winrt/APZController.h @@ -49,8 +49,9 @@ public: virtual void SendAsyncScrollDOMEvent(bool aIsRoot, const mozilla::CSSRect &aContentRect, const mozilla::CSSSize &aScrollableSize); virtual void PostDelayedTask(Task* aTask, int aDelayMs); virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints); - virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid); - virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid); + virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid, + APZStateChange aChange, + int aArg); void SetWidgetListener(nsIWidgetListener* aWidgetListener); diff --git a/widget/xpwidgets/ActiveElementManager.cpp b/widget/xpwidgets/ActiveElementManager.cpp new file mode 100644 index 000000000000..b9c1900ad7a7 --- /dev/null +++ b/widget/xpwidgets/ActiveElementManager.cpp @@ -0,0 +1,151 @@ +/* -*- 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 "ActiveElementManager.h" +#include "mozilla/EventStates.h" +#include "mozilla/Preferences.h" +#include "mozilla/Services.h" +#include "inIDOMUtils.h" +#include "nsIDOMDocument.h" +#include "nsIDOMElement.h" +#include "nsIDOMEventTarget.h" +#include "base/message_loop.h" +#include "base/task.h" + +namespace mozilla { +namespace widget { + +static int32_t sActivationDelayMs = 100; +static bool sActivationDelayMsSet = false; + +ActiveElementManager::ActiveElementManager() + : mDomUtils(services::GetInDOMUtils()), + mCanBePan(false), + mCanBePanSet(false), + mSetActiveTask(nullptr) +{ + if (!sActivationDelayMsSet) { + Preferences::AddIntVarCache(&sActivationDelayMs, + "ui.touch_activation.delay_ms", + sActivationDelayMs); + sActivationDelayMsSet = true; + } +} + +ActiveElementManager::~ActiveElementManager() {} + +void +ActiveElementManager::SetTargetElement(nsIDOMEventTarget* aTarget) +{ + if (mTarget) { + // Multiple fingers on screen (since HandleTouchEnd clears mTarget). + ResetActive(); + return; + } + + mTarget = do_QueryInterface(aTarget); + TriggerElementActivation(); +} + +void +ActiveElementManager::HandleTouchStart(bool aCanBePan) +{ + mCanBePan = aCanBePan; + mCanBePanSet = true; + TriggerElementActivation(); +} + +void +ActiveElementManager::TriggerElementActivation() +{ + // Both HandleTouchStart() and SetTargetElement() call this. They can be + // called in either order. One will set mCanBePanSet, and the other, mTarget. + // We want to actually trigger the activation once both are set. + if (!(mTarget && mCanBePanSet)) { + return; + } + + // If the touch cannot be a pan, make mTarget :active right away. + // Otherwise, wait a bit to see if the user will pan or not. + if (!mCanBePan) { + SetActive(mTarget); + } else { + mSetActiveTask = NewRunnableMethod( + this, &ActiveElementManager::SetActiveTask, mTarget); + MessageLoop::current()->PostDelayedTask( + FROM_HERE, mSetActiveTask, sActivationDelayMs); + } +} + +void +ActiveElementManager::HandlePanStart() +{ + // The user started to pan, so we don't want mTarget to be :active. + // Make it not :active, and clear any pending task to make it :active. + CancelTask(); + ResetActive(); +} + +void +ActiveElementManager::HandleTouchEnd(bool aWasClick) +{ + // If the touch was a click, make mTarget :active right away. + // nsEventStateManager will reset the active element when processing + // the mouse-down event generated by the click. + CancelTask(); + if (aWasClick) { + SetActive(mTarget); + } + + // Clear mTarget for next touch. + mTarget = nullptr; +} + +void +ActiveElementManager::SetActive(nsIDOMElement* aTarget) +{ + if (mDomUtils) { + mDomUtils->SetContentState(aTarget, NS_EVENT_STATE_ACTIVE.GetInternalValue());; + } +} + +void +ActiveElementManager::ResetActive() +{ + // Clear the :active flag from mTarget by setting it on the document root. + if (mTarget) { + nsCOMPtr doc; + mTarget->GetOwnerDocument(getter_AddRefs(doc)); + if (doc) { + nsCOMPtr root; + doc->GetDocumentElement(getter_AddRefs(root)); + if (root) { + SetActive(root); + } + } + } +} + +void +ActiveElementManager::SetActiveTask(nsIDOMElement* aTarget) +{ + // This gets called from mSetActiveTask's Run() method. The message loop + // deletes the task right after running it, so we need to null out + // mSetActiveTask to make sure we're not left with a dangling pointer. + mSetActiveTask = nullptr; + SetActive(aTarget); +} + +void +ActiveElementManager::CancelTask() +{ + if (mSetActiveTask) { + mSetActiveTask->Cancel(); + mSetActiveTask = nullptr; + } +} + +} +} \ No newline at end of file diff --git a/widget/xpwidgets/ActiveElementManager.h b/widget/xpwidgets/ActiveElementManager.h new file mode 100644 index 000000000000..974f4449c2fd --- /dev/null +++ b/widget/xpwidgets/ActiveElementManager.h @@ -0,0 +1,85 @@ +/* -*- 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 __mozilla_widget_ActiveElementManager_h__ +#define __mozilla_widget_ActiveElementManager_h__ + +#include "nsCOMPtr.h" +#include "nsISupportsImpl.h" + +class inIDOMUtils; +class nsIDOMEventTarget; +class nsIDOMElement; +class CancelableTask; + +namespace mozilla { +namespace widget { + +/** + * Manages setting and clearing the ':active' CSS pseudostate in the presence + * of touch input. + */ +class ActiveElementManager { +public: + NS_INLINE_DECL_REFCOUNTING(ActiveElementManager) + + ActiveElementManager(); + ~ActiveElementManager(); + + /** + * Specify the target of a touch. Typically this should be called right + * before HandleTouchStart(), but we give callers the flexibility to specify + * the target later if they don't know it at the time they call + * HandleTouchStart(). + * |aTarget| may be nullptr. + */ + void SetTargetElement(nsIDOMEventTarget* aTarget); + /** + * Handle a touch-start event. + * @param aCanBePan whether the touch can be a pan + */ + void HandleTouchStart(bool aCanBePan); + /** + * Handle the start of panning. + */ + void HandlePanStart(); + /** + * Handle a touch-end or touch-cancel event. + * @param aWasClick whether the touch was a click + */ + void HandleTouchEnd(bool aWasClick); +private: + nsCOMPtr mDomUtils; + /** + * The target of the first touch point in the current touch block. + */ + nsCOMPtr mTarget; + /** + * Whether the current touch block can be a pan. Set in HandleTouchStart(). + */ + bool mCanBePan; + /** + * Whether mCanBePan has been set for the current touch block. + * We need to keep track of this to allow HandleTouchStart() and + * SetTargetElement() to be called in either order. + */ + bool mCanBePanSet; + /** + * A task for calling SetActive() after a timeout. + */ + CancelableTask* mSetActiveTask; + + // Helpers + void TriggerElementActivation(); + void SetActive(nsIDOMElement* aTarget); + void ResetActive(); + void SetActiveTask(nsIDOMElement* aTarget); + void CancelTask(); +}; + +} +} + +#endif /*__mozilla_widget_ActiveElementManager_h__ */ diff --git a/widget/xpwidgets/moz.build b/widget/xpwidgets/moz.build index e85980c6c14f..02b07e3d63e5 100644 --- a/widget/xpwidgets/moz.build +++ b/widget/xpwidgets/moz.build @@ -5,6 +5,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. EXPORTS += [ + 'ActiveElementManager.h', 'APZCCallbackHelper.h', 'ContentHelper.h', 'GfxDriverInfo.h', @@ -13,6 +14,7 @@ EXPORTS += [ ] UNIFIED_SOURCES += [ + 'ActiveElementManager.cpp', 'APZCCallbackHelper.cpp', 'ContentHelper.cpp', 'GfxDriverInfo.cpp', diff --git a/xpcom/build/ServiceList.h b/xpcom/build/ServiceList.h index 78a9c5aa311d..0e59dd05cd28 100644 --- a/xpcom/build/ServiceList.h +++ b/xpcom/build/ServiceList.h @@ -14,6 +14,7 @@ MOZ_SERVICE(IOService, nsIIOService, "@mozilla.org/network/io-service;1") MOZ_SERVICE(ObserverService, nsIObserverService, "@mozilla.org/observer-service;1") MOZ_SERVICE(StringBundleService, nsIStringBundleService, "@mozilla.org/intl/stringbundle;1") MOZ_SERVICE(XPConnect, nsIXPConnect, "@mozilla.org/js/xpc/XPConnect;1") +MOZ_SERVICE(InDOMUtils, inIDOMUtils, "@mozilla.org/inspector/dom-utils;1") #ifdef MOZ_USE_NAMESPACE namespace mozilla diff --git a/xpcom/build/Services.cpp b/xpcom/build/Services.cpp index ac6bf7f87453..f9c14211b6f2 100644 --- a/xpcom/build/Services.cpp +++ b/xpcom/build/Services.cpp @@ -20,6 +20,7 @@ #include "nsIXULOverlayProvider.h" #include "IHistory.h" #include "nsIXPConnect.h" +#include "inIDOMUtils.h" using namespace mozilla; using namespace mozilla::services; diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index dff254103cf2..c49344bf6259 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -126,9 +126,6 @@ extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **) #include "mozilla/ClearOnShutdown.h" #include "mozilla/SystemMemoryReporter.h" -#include "mozilla/layers/ImageBridgeChild.h" -#include "mozilla/layers/CompositorParent.h" - #ifdef MOZ_VISUAL_EVENT_TRACER #include "mozilla/VisualEventTracer.h" #endif @@ -745,11 +742,6 @@ ShutdownXPCOM(nsIServiceManager* servMgr) } } - // This must happen after the shutdown of media and widgets, which - // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification. - mozilla::layers::ImageBridgeChild::ShutDown(); - mozilla::layers::CompositorParent::ShutDown(); - NS_ProcessPendingEvents(thread); mozilla::scache::StartupCache::DeleteSingleton(); if (observerService) diff --git a/xpcom/ds/moz.build b/xpcom/ds/moz.build index 855413a0c599..8e16a9ca2d5e 100644 --- a/xpcom/ds/moz.build +++ b/xpcom/ds/moz.build @@ -53,8 +53,6 @@ EXPORTS += [ 'nsHashPropertyBag.h', 'nsHashtable.h', 'nsMathUtils.h', - 'nsObserverList.h', - 'nsObserverService.h', 'nsStaticAtom.h', 'nsStaticNameTable.h', 'nsStringEnumerator.h', diff --git a/xpcom/ds/nsObserverService.cpp b/xpcom/ds/nsObserverService.cpp index 2388bfa045aa..fddf7d2b6ff1 100644 --- a/xpcom/ds/nsObserverService.cpp +++ b/xpcom/ds/nsObserverService.cpp @@ -222,7 +222,7 @@ nsObserverService::Create(nsISupports* outer, const nsIID& aIID, void* *aInstanc #define NS_ENSURE_VALIDCALL \ if (!NS_IsMainThread()) { \ - NS_ERROR("Using observer service off the main thread!"); \ + MOZ_CRASH("Using observer service off the main thread!"); \ return NS_ERROR_UNEXPECTED; \ } \ if (mShuttingDown) { \ diff --git a/xpcom/ds/nsObserverService.h b/xpcom/ds/nsObserverService.h index ebdfcc040d79..2bfddf465d2e 100644 --- a/xpcom/ds/nsObserverService.h +++ b/xpcom/ds/nsObserverService.h @@ -27,7 +27,7 @@ public: nsObserverService(); - NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVERSERVICE NS_DECL_NSIMEMORYREPORTER diff --git a/xpcom/threads/BackgroundHangMonitor.cpp b/xpcom/threads/BackgroundHangMonitor.cpp index 0f380ba7ccda..694974bf5414 100644 --- a/xpcom/threads/BackgroundHangMonitor.cpp +++ b/xpcom/threads/BackgroundHangMonitor.cpp @@ -28,7 +28,7 @@ namespace mozilla { * BackgroundHangManager is the global object that * manages all instances of BackgroundHangThread. */ -class BackgroundHangManager : public AtomicRefCounted +class BackgroundHangManager { private: // Background hang monitor thread function @@ -62,7 +62,7 @@ private: void RunMonitorThread(); public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(BackgroundHangManager) + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundHangManager) static StaticRefPtr sInstance; // Lock for access to members of this class