From e1c367c35639330714c63154e06c6949a1e537a2 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 2 Apr 2014 18:58:37 +0800 Subject: [PATCH 01/63] Bug 990876 - Moz2dify TestTextures.cpp. r=mattwoodrow --- gfx/tests/gtest/TestTextures.cpp | 94 +++++++++++++++----------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/gfx/tests/gtest/TestTextures.cpp b/gfx/tests/gtest/TestTextures.cpp index c67686d6bfb..4f854ade345 100644 --- a/gfx/tests/gtest/TestTextures.cpp +++ b/gfx/tests/gtest/TestTextures.cpp @@ -9,8 +9,7 @@ #include "mozilla/layers/TextureClient.h" #include "mozilla/layers/TextureHost.h" #include "gfx2DGlue.h" -#include "gfxImageSurface.h" -#include "gfxTypes.h" +#include "mozilla/gfx/Tools.h" #include "ImageContainer.h" #include "mozilla/layers/YCbCrImageDataSerializer.h" @@ -32,13 +31,14 @@ using namespace mozilla::layers; // fills the surface with values betwee 0 and 100. -void SetupSurface(gfxImageSurface* surface) { - int bpp = gfxASurface::BytePerPixelFromFormat(surface->Format()); - int stride = surface->Stride(); +void SetupSurface(gfx::DataSourceSurface* surface) { + uint8_t* data = surface->GetData(); + gfx::IntSize size = surface->GetSize(); + uint32_t stride = surface->Stride(); + int bpp = gfx::BytesPerPixel(surface->GetFormat()); uint8_t val = 0; - uint8_t* data = surface->Data(); - for (int y = 0; y < surface->Height(); ++y) { - for (int x = 0; x < surface->Height(); ++x) { + for (int y = 0; y < size.width; ++y) { + for (int x = 0; x < size.height; ++x) { for (int b = 0; b < bpp; ++b) { data[y*stride + x*bpp + b] = val; if (val == 100) { @@ -52,20 +52,20 @@ void SetupSurface(gfxImageSurface* surface) { } // return true if two surfaces contain the same data -void AssertSurfacesEqual(gfxImageSurface* surface1, - gfxImageSurface* surface2) +void AssertSurfacesEqual(gfx::DataSourceSurface* surface1, + gfx::DataSourceSurface* surface2) { ASSERT_EQ(surface1->GetSize(), surface2->GetSize()); - ASSERT_EQ(surface1->Format(), surface2->Format()); + ASSERT_EQ(surface1->GetFormat(), surface2->GetFormat()); - uint8_t* data1 = surface1->Data(); - uint8_t* data2 = surface2->Data(); + uint8_t* data1 = surface1->GetData(); + uint8_t* data2 = surface2->GetData(); int stride1 = surface1->Stride(); int stride2 = surface2->Stride(); - int bpp = gfxASurface::BytePerPixelFromFormat(surface1->Format()); + int bpp = gfx::BytesPerPixel(surface1->GetFormat()); - for (int y = 0; y < surface1->Height(); ++y) { - for (int x = 0; x < surface1->Width(); ++x) { + for (int y = 0; y < surface1->GetSize().height; ++y) { + for (int x = 0; x < surface1->GetSize().width; ++x) { for (int b = 0; b < bpp; ++b) { ASSERT_EQ(data1[y*stride1 + x*bpp + b], data2[y*stride2 + x*bpp + b]); @@ -100,22 +100,18 @@ void AssertYCbCrSurfacesEqual(PlanarYCbCrData* surface1, } // Run the test for a texture client and a surface -void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) { +void TestTextureClientSurface(TextureClient* texture, gfx::DataSourceSurface* surface) { // client allocation - ASSERT_TRUE(texture->AsTextureClientSurface() != nullptr); - TextureClientSurface* client = texture->AsTextureClientSurface(); - client->AllocateForSurface(ToIntSize(surface->GetSize())); + ASSERT_TRUE(texture->CanExposeDrawTarget()); + texture->AllocateForSurface(surface->GetSize()); ASSERT_TRUE(texture->IsAllocated()); ASSERT_TRUE(texture->Lock(OPEN_READ_WRITE)); // client painting - client->UpdateSurface(surface); - - nsRefPtr aSurface = client->GetAsSurface(); - nsRefPtr clientSurface = aSurface->GetAsImageSurface(); - - AssertSurfacesEqual(surface, clientSurface); + RefPtr dt = texture->GetAsDrawTarget(); + dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint()); + dt = nullptr; texture->Unlock(); // client serialization @@ -134,14 +130,9 @@ void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) // host read ASSERT_TRUE(host->Lock()); RefPtr hostDataSurface = host->GetAsSurface(); - host->Unlock(); + AssertSurfacesEqual(surface, hostDataSurface); - nsRefPtr hostSurface = - new gfxImageSurface(hostDataSurface->GetData(), - ThebesIntSize(hostDataSurface->GetSize()), - hostDataSurface->Stride(), - SurfaceFormatToImageFormat(hostDataSurface->GetFormat())); - AssertSurfacesEqual(surface, hostSurface.get()); + host->Unlock(); } // Same as above, for YCbCr surfaces @@ -205,20 +196,21 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) { TEST(Layers, TextureSerialization) { // the test is run on all the following image formats - gfxImageFormat formats[3] = { - gfxImageFormat::ARGB32, - gfxImageFormat::RGB24, - gfxImageFormat::A8, + gfx::SurfaceFormat formats[3] = { + gfx::SurfaceFormat::B8G8R8A8, + gfx::SurfaceFormat::R8G8B8X8, + gfx::SurfaceFormat::A8, }; for (int f = 0; f < 3; ++f) { - RefPtr surface = new gfxImageSurface(gfxIntSize(400,300), formats[f]); - SetupSurface(surface.get()); + RefPtr surface = + gfx::Factory::CreateDataSourceSurface(gfx::IntSize(400,300), formats[f]); + SetupSurface(surface); AssertSurfacesEqual(surface, surface); RefPtr client = new MemoryTextureClient(nullptr, - mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()), + surface->GetFormat(), gfx::BackendType::CAIRO, TEXTURE_DEALLOCATE_CLIENT); @@ -229,20 +221,24 @@ TEST(Layers, TextureSerialization) { } TEST(Layers, TextureYCbCrSerialization) { - RefPtr ySurface = new gfxImageSurface(gfxIntSize(400,300), gfxImageFormat::A8); - RefPtr cbSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormat::A8); - RefPtr crSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormat::A8); + RefPtr ySurface = gfx::Factory::CreateDataSourceSurface( + IntSize(400,300), gfx::SurfaceFormat::A8); + RefPtr cbSurface = gfx::Factory::CreateDataSourceSurface( + IntSize(200,150), gfx::SurfaceFormat::A8); + RefPtr crSurface = gfx::Factory::CreateDataSourceSurface( + IntSize(200,150), gfx::SurfaceFormat::A8); + SetupSurface(ySurface.get()); SetupSurface(cbSurface.get()); SetupSurface(crSurface.get()); PlanarYCbCrData clientData; - clientData.mYChannel = ySurface->Data(); - clientData.mCbChannel = cbSurface->Data(); - clientData.mCrChannel = crSurface->Data(); - clientData.mYSize = ySurface->GetSize().ToIntSize(); - clientData.mPicSize = ySurface->GetSize().ToIntSize(); - clientData.mCbCrSize = cbSurface->GetSize().ToIntSize(); + clientData.mYChannel = ySurface->GetData(); + clientData.mCbChannel = cbSurface->GetData(); + clientData.mCrChannel = crSurface->GetData(); + clientData.mYSize = ySurface->GetSize(); + clientData.mPicSize = ySurface->GetSize(); + clientData.mCbCrSize = cbSurface->GetSize(); clientData.mYStride = ySurface->Stride(); clientData.mCbCrStride = cbSurface->Stride(); clientData.mStereoMode = StereoMode::MONO; From 28124e2548f2f3473a0f9277942abe9599ea4a89 Mon Sep 17 00:00:00 2001 From: Jonathan Griffin Date: Tue, 1 Apr 2014 10:02:09 -0700 Subject: [PATCH 02/63] Bug 989048 - Use TimeoutException instead of Exception for emulator startup timeouts, r=mdas --- testing/marionette/client/marionette/emulator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/marionette/client/marionette/emulator.py b/testing/marionette/client/marionette/emulator.py index 86aab4bdc8f..b131262a258 100644 --- a/testing/marionette/client/marionette/emulator.py +++ b/testing/marionette/client/marionette/emulator.py @@ -348,7 +348,7 @@ waitFor( while online - original_online == set([]): time.sleep(1) if datetime.datetime.now() - now > datetime.timedelta(seconds=60): - raise Exception('timed out waiting for emulator to start') + raise TimeoutException('timed out waiting for emulator to start') online, offline = self._get_adb_devices() self.port = int(list(online - original_online)[0]) self._emulator_launched = True From db5e874e0839ab32b8caeb11ef4b00146231aa25 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 2 Apr 2014 19:12:48 +0800 Subject: [PATCH 03/63] Bug 990876 - Backed out changeset 0a245ee13ce6 for build bustage --- gfx/tests/gtest/TestTextures.cpp | 94 +++++++++++++++++--------------- 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/gfx/tests/gtest/TestTextures.cpp b/gfx/tests/gtest/TestTextures.cpp index 4f854ade345..c67686d6bfb 100644 --- a/gfx/tests/gtest/TestTextures.cpp +++ b/gfx/tests/gtest/TestTextures.cpp @@ -9,7 +9,8 @@ #include "mozilla/layers/TextureClient.h" #include "mozilla/layers/TextureHost.h" #include "gfx2DGlue.h" -#include "mozilla/gfx/Tools.h" +#include "gfxImageSurface.h" +#include "gfxTypes.h" #include "ImageContainer.h" #include "mozilla/layers/YCbCrImageDataSerializer.h" @@ -31,14 +32,13 @@ using namespace mozilla::layers; // fills the surface with values betwee 0 and 100. -void SetupSurface(gfx::DataSourceSurface* surface) { - uint8_t* data = surface->GetData(); - gfx::IntSize size = surface->GetSize(); - uint32_t stride = surface->Stride(); - int bpp = gfx::BytesPerPixel(surface->GetFormat()); +void SetupSurface(gfxImageSurface* surface) { + int bpp = gfxASurface::BytePerPixelFromFormat(surface->Format()); + int stride = surface->Stride(); uint8_t val = 0; - for (int y = 0; y < size.width; ++y) { - for (int x = 0; x < size.height; ++x) { + uint8_t* data = surface->Data(); + for (int y = 0; y < surface->Height(); ++y) { + for (int x = 0; x < surface->Height(); ++x) { for (int b = 0; b < bpp; ++b) { data[y*stride + x*bpp + b] = val; if (val == 100) { @@ -52,20 +52,20 @@ void SetupSurface(gfx::DataSourceSurface* surface) { } // return true if two surfaces contain the same data -void AssertSurfacesEqual(gfx::DataSourceSurface* surface1, - gfx::DataSourceSurface* surface2) +void AssertSurfacesEqual(gfxImageSurface* surface1, + gfxImageSurface* surface2) { ASSERT_EQ(surface1->GetSize(), surface2->GetSize()); - ASSERT_EQ(surface1->GetFormat(), surface2->GetFormat()); + ASSERT_EQ(surface1->Format(), surface2->Format()); - uint8_t* data1 = surface1->GetData(); - uint8_t* data2 = surface2->GetData(); + uint8_t* data1 = surface1->Data(); + uint8_t* data2 = surface2->Data(); int stride1 = surface1->Stride(); int stride2 = surface2->Stride(); - int bpp = gfx::BytesPerPixel(surface1->GetFormat()); + int bpp = gfxASurface::BytePerPixelFromFormat(surface1->Format()); - for (int y = 0; y < surface1->GetSize().height; ++y) { - for (int x = 0; x < surface1->GetSize().width; ++x) { + for (int y = 0; y < surface1->Height(); ++y) { + for (int x = 0; x < surface1->Width(); ++x) { for (int b = 0; b < bpp; ++b) { ASSERT_EQ(data1[y*stride1 + x*bpp + b], data2[y*stride2 + x*bpp + b]); @@ -100,18 +100,22 @@ void AssertYCbCrSurfacesEqual(PlanarYCbCrData* surface1, } // Run the test for a texture client and a surface -void TestTextureClientSurface(TextureClient* texture, gfx::DataSourceSurface* surface) { +void TestTextureClientSurface(TextureClient* texture, gfxImageSurface* surface) { // client allocation - ASSERT_TRUE(texture->CanExposeDrawTarget()); - texture->AllocateForSurface(surface->GetSize()); + ASSERT_TRUE(texture->AsTextureClientSurface() != nullptr); + TextureClientSurface* client = texture->AsTextureClientSurface(); + client->AllocateForSurface(ToIntSize(surface->GetSize())); ASSERT_TRUE(texture->IsAllocated()); ASSERT_TRUE(texture->Lock(OPEN_READ_WRITE)); // client painting - RefPtr dt = texture->GetAsDrawTarget(); - dt->CopySurface(surface, IntRect(IntPoint(), surface->GetSize()), IntPoint()); - dt = nullptr; + client->UpdateSurface(surface); + + nsRefPtr aSurface = client->GetAsSurface(); + nsRefPtr clientSurface = aSurface->GetAsImageSurface(); + + AssertSurfacesEqual(surface, clientSurface); texture->Unlock(); // client serialization @@ -130,9 +134,14 @@ void TestTextureClientSurface(TextureClient* texture, gfx::DataSourceSurface* su // host read ASSERT_TRUE(host->Lock()); RefPtr hostDataSurface = host->GetAsSurface(); - AssertSurfacesEqual(surface, hostDataSurface); - host->Unlock(); + + nsRefPtr hostSurface = + new gfxImageSurface(hostDataSurface->GetData(), + ThebesIntSize(hostDataSurface->GetSize()), + hostDataSurface->Stride(), + SurfaceFormatToImageFormat(hostDataSurface->GetFormat())); + AssertSurfacesEqual(surface, hostSurface.get()); } // Same as above, for YCbCr surfaces @@ -196,21 +205,20 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) { TEST(Layers, TextureSerialization) { // the test is run on all the following image formats - gfx::SurfaceFormat formats[3] = { - gfx::SurfaceFormat::B8G8R8A8, - gfx::SurfaceFormat::R8G8B8X8, - gfx::SurfaceFormat::A8, + gfxImageFormat formats[3] = { + gfxImageFormat::ARGB32, + gfxImageFormat::RGB24, + gfxImageFormat::A8, }; for (int f = 0; f < 3; ++f) { - RefPtr surface = - gfx::Factory::CreateDataSourceSurface(gfx::IntSize(400,300), formats[f]); - SetupSurface(surface); + RefPtr surface = new gfxImageSurface(gfxIntSize(400,300), formats[f]); + SetupSurface(surface.get()); AssertSurfacesEqual(surface, surface); RefPtr client = new MemoryTextureClient(nullptr, - surface->GetFormat(), + mozilla::gfx::ImageFormatToSurfaceFormat(surface->Format()), gfx::BackendType::CAIRO, TEXTURE_DEALLOCATE_CLIENT); @@ -221,24 +229,20 @@ TEST(Layers, TextureSerialization) { } TEST(Layers, TextureYCbCrSerialization) { - RefPtr ySurface = gfx::Factory::CreateDataSourceSurface( - IntSize(400,300), gfx::SurfaceFormat::A8); - RefPtr cbSurface = gfx::Factory::CreateDataSourceSurface( - IntSize(200,150), gfx::SurfaceFormat::A8); - RefPtr crSurface = gfx::Factory::CreateDataSourceSurface( - IntSize(200,150), gfx::SurfaceFormat::A8); - + RefPtr ySurface = new gfxImageSurface(gfxIntSize(400,300), gfxImageFormat::A8); + RefPtr cbSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormat::A8); + RefPtr crSurface = new gfxImageSurface(gfxIntSize(200,150), gfxImageFormat::A8); SetupSurface(ySurface.get()); SetupSurface(cbSurface.get()); SetupSurface(crSurface.get()); PlanarYCbCrData clientData; - clientData.mYChannel = ySurface->GetData(); - clientData.mCbChannel = cbSurface->GetData(); - clientData.mCrChannel = crSurface->GetData(); - clientData.mYSize = ySurface->GetSize(); - clientData.mPicSize = ySurface->GetSize(); - clientData.mCbCrSize = cbSurface->GetSize(); + clientData.mYChannel = ySurface->Data(); + clientData.mCbChannel = cbSurface->Data(); + clientData.mCrChannel = crSurface->Data(); + clientData.mYSize = ySurface->GetSize().ToIntSize(); + clientData.mPicSize = ySurface->GetSize().ToIntSize(); + clientData.mCbCrSize = cbSurface->GetSize().ToIntSize(); clientData.mYStride = ySurface->Stride(); clientData.mCbCrStride = cbSurface->Stride(); clientData.mStereoMode = StereoMode::MONO; From b918d98f73269812de99f2a2da241c6447ae41e2 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 2 Apr 2014 12:32:24 +0100 Subject: [PATCH 04/63] Bug 990683 - Stop calling DeprecatedGetCurrentAsSurface in nsLayoutUtils::SurfaceFromElement(HTMLVideoElement* aElement,...). (Moz2D migration.) r=mattwoodrow --- layout/base/nsLayoutUtils.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 30d375cd9d7..51fc7ac9c61 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -5346,11 +5346,10 @@ nsLayoutUtils::SurfaceFromElement(HTMLVideoElement* aElement, return result; mozilla::gfx::IntSize size; - nsRefPtr surf = container->DeprecatedGetCurrentAsSurface(&size); - if (!surf) + result.mSourceSurface = container->GetCurrentAsSourceSurface(&size); + if (!result.mSourceSurface) return result; - result.mSourceSurface = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, surf); result.mCORSUsed = aElement->GetCORSMode() != CORS_NONE; result.mSize = ThebesIntSize(size); result.mPrincipal = principal.forget(); From 3976b3243ca0291a8edd5a2658655c749bec1c54 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 2 Apr 2014 12:32:54 +0100 Subject: [PATCH 05/63] Bug 964732 - Remove calls to DeprecatedGetAsSurface in ImageLayerD3D9 (Moz2D migration). r=mattwoodrow --- gfx/layers/d3d9/ImageLayerD3D9.cpp | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/gfx/layers/d3d9/ImageLayerD3D9.cpp b/gfx/layers/d3d9/ImageLayerD3D9.cpp index 347232a6402..6e3ea031d1c 100644 --- a/gfx/layers/d3d9/ImageLayerD3D9.cpp +++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp @@ -4,7 +4,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ipc/AutoOpenSurface.h" +#include "mozilla/gfx/2D.h" #include "mozilla/gfx/Point.h" +#include "mozilla/RefPtr.h" #include "mozilla/layers/PLayerTransaction.h" #include "gfxSharedImageSurface.h" @@ -25,9 +27,9 @@ namespace layers { using namespace mozilla::gfx; static inline _D3DFORMAT -D3dFormatForGfxFormat(gfxImageFormat aFormat) +D3dFormatForSurfaceFormat(SurfaceFormat aFormat) { - if (aFormat == gfxImageFormat::A8) { + if (aFormat == SurfaceFormat::A8) { return D3DFMT_A8; } @@ -133,24 +135,22 @@ OpenSharedTexture(const D3DSURFACE_DESC& aDesc, static already_AddRefed SurfaceToTexture(IDirect3DDevice9 *aDevice, - gfxASurface *aSurface, + SourceSurface *aSurface, const IntSize &aSize) { - - nsRefPtr imageSurface = aSurface->GetAsImageSurface(); - - if (!imageSurface) { - imageSurface = new gfxImageSurface(ThebesIntSize(aSize), - gfxImageFormat::ARGB32); - - nsRefPtr context = new gfxContext(imageSurface); - context->SetSource(aSurface); - context->SetOperator(gfxContext::OPERATOR_SOURCE); - context->Paint(); + RefPtr dataSurface = aSurface->GetDataSurface(); + if (!dataSurface) { + return nullptr; } - - return DataToTexture(aDevice, imageSurface->Data(), imageSurface->Stride(), - aSize, D3dFormatForGfxFormat(imageSurface->Format())); + DataSourceSurface::MappedSurface map; + if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) { + return nullptr; + } + nsRefPtr texture = + DataToTexture(aDevice, map.mData, map.mStride, aSize, + D3dFormatForSurfaceFormat(dataSurface->GetFormat())); + dataSurface->Unmap(); + return texture.forget(); } static void AllocateTexturesYCbCr(PlanarYCbCrImage *aImage, @@ -344,7 +344,7 @@ ImageLayerD3D9::GetTexture(Image *aImage, bool& aHasAlpha) CairoImage *cairoImage = static_cast(aImage); - nsRefPtr surf = cairoImage->DeprecatedGetAsSurface(); + RefPtr surf = cairoImage->GetAsSourceSurface(); if (!surf) { return nullptr; } @@ -357,7 +357,7 @@ ImageLayerD3D9::GetTexture(Image *aImage, bool& aHasAlpha) } } - aHasAlpha = surf->GetContentType() == gfxContentType::COLOR_ALPHA; + aHasAlpha = surf->GetFormat() == SurfaceFormat::B8G8R8A8; } else if (aImage->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) { if (!aImage->GetBackendData(mozilla::layers::LayersBackend::LAYERS_D3D9)) { // The texture in which the frame is stored belongs to DXVA's D3D9 device. From 0f938e4df09d94a66c8d8365ee299602c2d46033 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Wed, 2 Apr 2014 12:33:15 +0100 Subject: [PATCH 06/63] Bug 990752 - Make ImageLayerD3D9/ImageLayerD3D10::Render() use mSourceSurface instead of mDeprecatedSurface (Moz2D migration). r=mattwoodrow --- gfx/layers/d3d10/ImageLayerD3D10.cpp | 4 ++-- gfx/layers/d3d9/ImageLayerD3D9.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gfx/layers/d3d10/ImageLayerD3D10.cpp b/gfx/layers/d3d10/ImageLayerD3D10.cpp index 6f0e2103650..130990904cf 100644 --- a/gfx/layers/d3d10/ImageLayerD3D10.cpp +++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp @@ -219,8 +219,8 @@ ImageLayerD3D10::RenderLayer() image->GetFormat() == ImageFormat::REMOTE_IMAGE_DXGI_TEXTURE || image->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) { NS_ASSERTION(image->GetFormat() != ImageFormat::CAIRO_SURFACE || - !static_cast(image)->mDeprecatedSurface || - static_cast(image)->mDeprecatedSurface->GetContentType() != gfxContentType::ALPHA, + !static_cast(image)->mSourceSurface || + static_cast(image)->mSourceSurface->GetFormat() != SurfaceFormat::A8, "Image layer has alpha image"); bool hasAlpha = false; diff --git a/gfx/layers/d3d9/ImageLayerD3D9.cpp b/gfx/layers/d3d9/ImageLayerD3D9.cpp index 6e3ea031d1c..a1b49b6cf9a 100644 --- a/gfx/layers/d3d9/ImageLayerD3D9.cpp +++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp @@ -415,8 +415,8 @@ ImageLayerD3D9::RenderLayer() image->GetFormat() == ImageFormat::D3D9_RGB32_TEXTURE) { NS_ASSERTION(image->GetFormat() != ImageFormat::CAIRO_SURFACE || - !static_cast(image)->mDeprecatedSurface || - static_cast(image)->mDeprecatedSurface->GetContentType() != gfxContentType::ALPHA, + !static_cast(image)->mSourceSurface || + static_cast(image)->mSourceSurface->GetFormat() != SurfaceFormat::A8, "Image layer has alpha image"); bool hasAlpha = false; From 3758666427e83e86380c5139def2e1204cd6d26f Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Wed, 2 Apr 2014 13:53:08 +0200 Subject: [PATCH 07/63] Bug 989011 - Factor this-computation for arrow functions out of JSOP_LAMBDA. r=jorendorff --- js/src/frontend/BytecodeEmitter.cpp | 7 +++- js/src/frontend/ParseNode.h | 13 +++---- js/src/frontend/Parser.cpp | 2 +- js/src/jit/BaselineCompiler.cpp | 27 ++++++++++++++ js/src/jit/BaselineCompiler.h | 1 + js/src/vm/Interpreter.cpp | 55 +++++++++++++++++------------ js/src/vm/Interpreter.h | 3 ++ js/src/vm/Opcodes.h | 5 ++- js/src/vm/Xdr.h | 2 +- 9 files changed, 81 insertions(+), 34 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 9381bb676d7..e78d8227217 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -4937,8 +4937,13 @@ EmitFunc(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn) unsigned index = bce->objectList.add(pn->pn_funbox); /* Non-hoisted functions simply emit their respective op. */ - if (!pn->functionIsHoisted()) + if (!pn->functionIsHoisted()) { + /* JSOP_LAMBDA_ARROW is always preceded by JSOP_THIS. */ + MOZ_ASSERT(fun->isArrow() == (pn->getOp() == JSOP_LAMBDA_ARROW)); + if (fun->isArrow() && Emit1(cx, bce, JSOP_THIS) < 0) + return false; return EmitIndex32(cx, pn->getOp(), index, bce); + } /* * For a script we emit the code as we parse. Thus the bytecode for diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index e9b8c626d2d..ae5f53f90ca 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -700,12 +700,13 @@ class ParseNode bool functionIsHoisted() const { JS_ASSERT(pn_arity == PN_CODE && getKind() == PNK_FUNCTION); - JS_ASSERT(isOp(JSOP_LAMBDA) || // lambda, genexpr - isOp(JSOP_DEFFUN) || // non-body-level function statement - isOp(JSOP_NOP) || // body-level function stmt in global code - isOp(JSOP_GETLOCAL) || // body-level function stmt in function code - isOp(JSOP_GETARG)); // body-level function redeclaring formal - return !(isOp(JSOP_LAMBDA) || isOp(JSOP_DEFFUN)); + JS_ASSERT(isOp(JSOP_LAMBDA) || // lambda, genexpr + isOp(JSOP_LAMBDA_ARROW) || // arrow function + isOp(JSOP_DEFFUN) || // non-body-level function statement + isOp(JSOP_NOP) || // body-level function stmt in global code + isOp(JSOP_GETLOCAL) || // body-level function stmt in function code + isOp(JSOP_GETARG)); // body-level function redeclaring formal + return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN); } /* diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 793355da569..01199889ea9 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -1821,7 +1821,7 @@ Parser::checkFunctionDefinition(HandlePropertyName funName, pn->pn_dflags |= PND_BOUND; } else { /* A function expression does not introduce any binding. */ - pn->setOp(JSOP_LAMBDA); + pn->setOp(kind == Arrow ? JSOP_LAMBDA_ARROW : JSOP_LAMBDA); } // When a lazily-parsed function is called, we only fully parse (and emit) diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 96cbb446f2e..1a9470e1f2b 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -1274,6 +1274,33 @@ BaselineCompiler::emit_JSOP_LAMBDA() return true; } +typedef JSObject *(*LambdaArrowFn)(JSContext *, HandleFunction, HandleObject, HandleValue); +static const VMFunction LambdaArrowInfo = FunctionInfo(js::LambdaArrow); + +bool +BaselineCompiler::emit_JSOP_LAMBDA_ARROW() +{ + // Keep pushed |this| in R0. + frame.popRegsAndSync(1); + + RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc))); + + prepareVMCall(); + masm.loadPtr(frame.addressOfScopeChain(), R1.scratchReg()); + + pushArg(R0); + pushArg(R1.scratchReg()); + pushArg(ImmGCPtr(fun)); + + if (!callVM(LambdaArrowInfo)) + return false; + + // Box and push return value. + masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0); + frame.push(R0); + return true; +} + void BaselineCompiler::storeValue(const StackValue *source, const Address &dest, const ValueOperand &scratch) diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 8db9a0ea0d3..ef8afaa3400 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -60,6 +60,7 @@ namespace jit { _(JSOP_OBJECT) \ _(JSOP_REGEXP) \ _(JSOP_LAMBDA) \ + _(JSOP_LAMBDA_ARROW) \ _(JSOP_BITOR) \ _(JSOP_BITXOR) \ _(JSOP_BITAND) \ diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index e2ae62028df..dfb6529edc3 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -1633,7 +1633,6 @@ CASE(JSOP_UNUSED107) CASE(JSOP_UNUSED124) CASE(JSOP_UNUSED125) CASE(JSOP_UNUSED126) -CASE(JSOP_UNUSED132) CASE(JSOP_UNUSED139) CASE(JSOP_UNUSED140) CASE(JSOP_UNUSED141) @@ -3018,6 +3017,21 @@ CASE(JSOP_LAMBDA) } END_CASE(JSOP_LAMBDA) +CASE(JSOP_LAMBDA_ARROW) +{ + /* Load the specified function object literal. */ + RootedFunction &fun = rootFunction0; + fun = script->getFunction(GET_UINT32_INDEX(REGS.pc)); + RootedValue &thisv = rootValue0; + thisv = REGS.sp[-1]; + JSObject *obj = LambdaArrow(cx, fun, REGS.fp()->scopeChain(), thisv); + if (!obj) + goto error; + JS_ASSERT(obj->getProto()); + REGS.sp[-1].setObject(*obj); +} +END_CASE(JSOP_LAMBDA_ARROW) + CASE(JSOP_CALLEE) JS_ASSERT(REGS.fp()->isNonEvalFunctionFrame()); PUSH_COPY(REGS.fp()->calleev()); @@ -3594,34 +3608,31 @@ js::GetScopeNameForTypeOf(JSContext *cx, HandleObject scopeChain, HandleProperty JSObject * js::Lambda(JSContext *cx, HandleFunction fun, HandleObject parent) { + MOZ_ASSERT(!fun->isArrow()); + RootedObject clone(cx, CloneFunctionObjectIfNotSingleton(cx, fun, parent, TenuredObject)); if (!clone) return nullptr; - if (fun->isArrow()) { - // Note that this will assert if called from Ion code. Ion can't yet - // emit code for a bound arrow function (bug 851913). - AbstractFramePtr frame; - if (cx->currentlyRunningInInterpreter()) { - frame = cx->interpreterFrame(); - } else { -#ifdef JS_ION - JS_ASSERT(cx->currentlyRunningInJit()); - frame = jit::GetTopBaselineFrame(cx); -#endif - } + MOZ_ASSERT(clone->global() == clone->global()); + return clone; +} - if (!ComputeThis(cx, frame)) - return nullptr; +JSObject * +js::LambdaArrow(JSContext *cx, HandleFunction fun, HandleObject parent, HandleValue thisv) +{ + MOZ_ASSERT(fun->isArrow()); - RootedValue thisval(cx, frame.thisValue()); - clone = js_fun_bind(cx, clone, thisval, nullptr, 0); - if (!clone) - return nullptr; - clone->as().setArrow(); - } + RootedObject clone(cx, CloneFunctionObjectIfNotSingleton(cx, fun, parent, TenuredObject)); + if (!clone) + return nullptr; - JS_ASSERT(clone->global() == clone->global()); + clone = js_fun_bind(cx, clone, thisv, nullptr, 0); + if (!clone) + return nullptr; + clone->as().setArrow(); + + MOZ_ASSERT(clone->global() == clone->global()); return clone; } diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h index 8cf9e310882..5a0d5da41f1 100644 --- a/js/src/vm/Interpreter.h +++ b/js/src/vm/Interpreter.h @@ -370,6 +370,9 @@ GetScopeNameForTypeOf(JSContext *cx, HandleObject obj, HandlePropertyName name, JSObject * Lambda(JSContext *cx, HandleFunction fun, HandleObject parent); +JSObject * +LambdaArrow(JSContext *cx, HandleFunction fun, HandleObject parent, HandleValue thisv); + bool GetElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res); diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h index 0a897526444..9fc480566ec 100644 --- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -287,11 +287,10 @@ \ /* Push a closure for a named or anonymous function expression. */ \ macro(JSOP_LAMBDA, 130, "lambda", NULL, 5, 0, 1, JOF_OBJECT) \ + macro(JSOP_LAMBDA_ARROW, 131, "lambda_arrow", NULL, 5, 1, 1, JOF_OBJECT) \ \ /* Used for named function expression self-naming, if lightweight. */ \ - macro(JSOP_CALLEE, 131, "callee", NULL, 1, 0, 1, JOF_BYTE) \ - \ - macro(JSOP_UNUSED132, 132, "unused132", NULL, 1, 0, 0, JOF_BYTE) \ + macro(JSOP_CALLEE, 132, "callee", NULL, 1, 0, 1, JOF_BYTE) \ \ /* Pick an element from the stack. */ \ macro(JSOP_PICK, 133, "pick", NULL, 2, 0, 0, JOF_UINT8|JOF_TMPSLOT2) \ diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index fbe4fa37c27..7cd30c3715d 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -23,7 +23,7 @@ namespace js { * and saved versions. If deserialization fails, the data should be * invalidated if possible. */ -static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 169); +static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 170); class XDRBuffer { public: From b925abbb4766954491a24b2e8b04bbdee514701d Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 2 Apr 2014 14:25:15 +0200 Subject: [PATCH 08/63] Bug 986313: Use LifoAllocPolicy for VarTypeVector and prevent a memory leak when moving it in ModuleCompiler; r=luke --- js/src/ds/LifoAlloc.h | 30 ++++++++++++++++++++++++++++++ js/src/jit/AsmJS.cpp | 19 +++++++++++-------- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/js/src/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h index d1c37b27680..4fbc42f3a57 100644 --- a/js/src/ds/LifoAlloc.h +++ b/js/src/ds/LifoAlloc.h @@ -521,6 +521,36 @@ class LifoAllocScope } }; +class LifoAllocPolicy +{ + LifoAlloc &alloc_; + + public: + LifoAllocPolicy(LifoAlloc &alloc) + : alloc_(alloc) + {} + void *malloc_(size_t bytes) { + return alloc_.alloc(bytes); + } + void *calloc_(size_t bytes) { + void *p = malloc_(bytes); + if (p) + memset(p, 0, bytes); + return p; + } + void *realloc_(void *p, size_t oldBytes, size_t bytes) { + void *n = malloc_(bytes); + if (!n) + return n; + memcpy(n, p, Min(oldBytes, bytes)); + return n; + } + void free_(void *p) { + } + void reportAllocOverflow() const { + } +}; + } // namespace js #endif /* ds_LifoAlloc_h */ diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index a6965839482..5e61bbb2af9 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -672,7 +672,7 @@ class ABIArgIter typedef js::Vector MIRTypeVector; typedef ABIArgIter ABIArgMIRTypeIter; -typedef js::Vector VarTypeVector; +typedef js::Vector VarTypeVector; typedef ABIArgIter ABIArgTypeIter; class Signature @@ -681,10 +681,10 @@ class Signature RetType retType_; public: - Signature(ExclusiveContext *cx) - : argTypes_(cx) {} - Signature(ExclusiveContext *cx, RetType retType) - : argTypes_(cx), retType_(retType) {} + Signature(LifoAlloc &alloc) + : argTypes_(alloc) {} + Signature(LifoAlloc &alloc, RetType retType) + : argTypes_(alloc), retType_(retType) {} Signature(VarTypeVector &&argTypes, RetType retType) : argTypes_(Move(argTypes)), retType_(Move(retType)) {} Signature(Signature &&rhs) @@ -1416,6 +1416,9 @@ class MOZ_STACK_CLASS ModuleCompiler uint32_t minHeapLength() const { return module_->minHeapLength(); } + LifoAlloc &lifo() { + return moduleLifo_; + } bool collectAccesses(MIRGenerator &gen) { if (!module_->addHeapAccesses(gen.heapAccesses())) @@ -2281,7 +2284,7 @@ class FunctionCompiler : prevMaxStackBytes_(0), maxChildStackBytes_(0), spIncrement_(0), - sig_(f.cx(), retType), + sig_(f.m().lifo(), retType), regArgs_(f.cx()), stackArgs_(f.cx()), childClobbers_(false) @@ -5384,7 +5387,7 @@ CheckFunction(ModuleCompiler &m, LifoAlloc &lifo, MIRGenerator **mir, ModuleComp ParseNode *stmtIter = ListHead(FunctionStatementList(fn)); - VarTypeVector argTypes(m.cx()); + VarTypeVector argTypes(m.lifo()); if (!CheckArguments(f, &stmtIter, &argTypes)) return false; @@ -5841,7 +5844,7 @@ CheckFuncPtrTable(ModuleCompiler &m, ParseNode *var) return false; } - Signature sig(m.cx()); + Signature sig(m.lifo()); if (!sig.copy(*firstSig)) return false; From fd16aeaa78752207ee526f6286460dd9fd4c007d Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Thu, 27 Feb 2014 16:26:24 +0100 Subject: [PATCH 09/63] Bug 946618 - Update cubeb to pick up new tests. r=kinetik --HG-- extra : rebase_source : 335880c5ecc3ace9cf5260e9e95b668ae00d183a --- media/libcubeb/README_MOZILLA | 2 +- media/libcubeb/tests/common.h | 30 ++ media/libcubeb/tests/test_audio.cpp | 174 ++++++++++ media/libcubeb/tests/test_latency.cpp | 39 +++ media/libcubeb/tests/test_sanity.cpp | 466 ++++++++++++++++++++++++++ media/libcubeb/tests/test_tone.cpp | 117 +++++++ 6 files changed, 827 insertions(+), 1 deletion(-) create mode 100644 media/libcubeb/tests/common.h create mode 100644 media/libcubeb/tests/test_audio.cpp create mode 100644 media/libcubeb/tests/test_latency.cpp create mode 100644 media/libcubeb/tests/test_sanity.cpp create mode 100644 media/libcubeb/tests/test_tone.cpp diff --git a/media/libcubeb/README_MOZILLA b/media/libcubeb/README_MOZILLA index 1caf0347907..3c8330da59a 100644 --- a/media/libcubeb/README_MOZILLA +++ b/media/libcubeb/README_MOZILLA @@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system. The cubeb git repository is: git://github.com/kinetiknz/cubeb.git -The git commit ID used was e8df12d770c6299640540e91cec13dc81efc9bbe. +The git commit ID used was bb0437c060a85a4f1f11b962a53ca0af02801967. diff --git a/media/libcubeb/tests/common.h b/media/libcubeb/tests/common.h new file mode 100644 index 00000000000..47cc28cc7f4 --- /dev/null +++ b/media/libcubeb/tests/common.h @@ -0,0 +1,30 @@ +/* + * Copyright © 2013 Sebastien Alaiwan + * + * This program is made available under an ISC-style license. See the + * accompanying file LICENSE for details. + */ + +#if defined( _WIN32) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#else +#include +#endif + +void delay(unsigned int ms) +{ +#if defined(_WIN32) + Sleep(ms); +#else + sleep(ms / 1000); + usleep(ms % 1000 * 1000); +#endif +} + +#if !defined(M_PI) +#define M_PI 3.14159265358979323846 +#endif + diff --git a/media/libcubeb/tests/test_audio.cpp b/media/libcubeb/tests/test_audio.cpp new file mode 100644 index 00000000000..5dfa468d18d --- /dev/null +++ b/media/libcubeb/tests/test_audio.cpp @@ -0,0 +1,174 @@ +/* + * Copyright © 2013 Sebastien Alaiwan + * + * This program is made available under an ISC-style license. See the + * accompanying file LICENSE for details. + */ + +/* libcubeb api/function exhaustive test. Plays a series of tones in different + * conditions. */ +#ifdef NDEBUG +#undef NDEBUG +#endif +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +#include "cubeb/cubeb.h" +#include "common.h" + +#define MAX_NUM_CHANNELS 32 + +#if !defined(M_PI) +#define M_PI 3.14159265358979323846 +#endif + +#define NELEMS(x) ((int) (sizeof(x) / sizeof(x[0]))) +#define VOLUME 0.2 + +float get_frequency(int channel_index) +{ + return 220.0f * (channel_index+1); +} + +/* store the phase of the generated waveform */ +typedef struct { + int num_channels; + float phase[MAX_NUM_CHANNELS]; + float sample_rate; +} synth_state; + +synth_state* synth_create(int num_channels, float sample_rate) +{ + synth_state* synth = (synth_state *) malloc(sizeof(synth_state)); + for(int i=0;i < MAX_NUM_CHANNELS;++i) + synth->phase[i] = 0.0f; + synth->num_channels = num_channels; + synth->sample_rate = sample_rate; + return synth; +} + +void synth_destroy(synth_state* synth) +{ + free(synth); +} + +void synth_run_float(synth_state* synth, float* audiobuffer, long nframes) +{ + for(int c=0;c < synth->num_channels;++c) { + float freq = get_frequency(c); + float phase_inc = 2.0 * M_PI * freq / synth->sample_rate; + for(long n=0;n < nframes;++n) { + audiobuffer[n*synth->num_channels+c] = sin(synth->phase[c]) * VOLUME; + synth->phase[c] += phase_inc; + } + } +} + +long data_cb_float(cubeb_stream *stream, void *user, void *buffer, long nframes) +{ + synth_state *synth = (synth_state *)user; + synth_run_float(synth, (float*)buffer, nframes); + return nframes; +} + +void synth_run_16bit(synth_state* synth, short* audiobuffer, long nframes) +{ + for(int c=0;c < synth->num_channels;++c) { + float freq = get_frequency(c); + float phase_inc = 2.0 * M_PI * freq / synth->sample_rate; + for(long n=0;n < nframes;++n) { + audiobuffer[n*synth->num_channels+c] = sin(synth->phase[c]) * VOLUME * 32767.0f; + synth->phase[c] += phase_inc; + } + } +} + +long data_cb_short(cubeb_stream *stream, void *user, void *buffer, long nframes) +{ + synth_state *synth = (synth_state *)user; + synth_run_16bit(synth, (short*)buffer, nframes); + return nframes; +} + +void state_cb(cubeb_stream *stream, void *user, cubeb_state state) +{ +} + +int run_test(int num_channels, int sampling_rate, int is_float) +{ + int ret = CUBEB_OK; + + cubeb *ctx = NULL; + synth_state* synth = NULL; + cubeb_stream *stream = NULL; + + ret = cubeb_init(&ctx, "Cubeb audio test"); + if (ret != CUBEB_OK) { + fprintf(stderr, "Error initializing cubeb library\n"); + goto cleanup; + } + + fprintf(stderr, "Testing %d channel(s), %d Hz, %s (%s)\n", num_channels, sampling_rate, is_float ? "float" : "short", cubeb_get_backend_id(ctx)); + + cubeb_stream_params params; + params.format = is_float ? CUBEB_SAMPLE_FLOAT32NE : CUBEB_SAMPLE_S16NE; + params.rate = sampling_rate; + params.channels = num_channels; + + synth = synth_create(params.channels, params.rate); + if (synth == NULL) { + fprintf(stderr, "Out of memory\n"); + goto cleanup; + } + + ret = cubeb_stream_init(ctx, &stream, "test tone", params, + 250, is_float ? data_cb_float : data_cb_short, state_cb, synth); + if (ret != CUBEB_OK) { + fprintf(stderr, "Error initializing cubeb stream: %d\n", ret); + goto cleanup; + } + + cubeb_stream_start(stream); + delay(200); + cubeb_stream_stop(stream); + +cleanup: + cubeb_stream_destroy(stream); + cubeb_destroy(ctx); + synth_destroy(synth); + + return ret; +} + +int main(int argc, char *argv[]) +{ + int channel_values[] = { + 1, + 2, + 4, + 5, + 6, + }; + + int freq_values[] = { + 24000, + 44100, + 48000, + }; + + for(int j=0;j < NELEMS(channel_values);++j) { + for(int i=0;i < NELEMS(freq_values);++i) { + assert(channel_values[j] < MAX_NUM_CHANNELS); + fprintf(stderr, "--------------------------\n"); + run_test(channel_values[j], freq_values[i], 0); + run_test(channel_values[j], freq_values[i], 1); + } + } + + return CUBEB_OK; +} + + diff --git a/media/libcubeb/tests/test_latency.cpp b/media/libcubeb/tests/test_latency.cpp new file mode 100644 index 00000000000..eb145f64640 --- /dev/null +++ b/media/libcubeb/tests/test_latency.cpp @@ -0,0 +1,39 @@ +#ifdef NDEBUG +#undef NDEBUG +#endif +#include +#include +#include + +int main(int argc, char * argv[]) +{ + cubeb * ctx = NULL; + int rv; + uint32_t max_channels; + uint32_t preferred_rate; + uint32_t latency_ms; + + rv = cubeb_init(&ctx, "Cubeb audio test"); + assert(rv == CUBEB_OK && "Cubeb init failed."); + + rv = cubeb_get_max_channel_count(ctx, &max_channels); + assert(rv == CUBEB_OK && "Could not query the max channe count."); + assert(max_channels > 0 && "Invalid max channel count."); + + rv = cubeb_get_preferred_sample_rate(ctx, &preferred_rate); + assert(rv == CUBEB_OK && "Could not query the preferred sample rate."); + assert(preferred_rate && "Invalid preferred sample rate."); + + cubeb_stream_params params = { + CUBEB_SAMPLE_FLOAT32NE, + preferred_rate, + max_channels + }; + rv = cubeb_get_min_latency(ctx, params, &latency_ms); + assert(rv == CUBEB_OK && "Could not query the minimal latency."); + assert(latency_ms && "Invalid minimal latency."); + + cubeb_destroy(ctx); + + return EXIT_SUCCESS; +} diff --git a/media/libcubeb/tests/test_sanity.cpp b/media/libcubeb/tests/test_sanity.cpp new file mode 100644 index 00000000000..ed83d37be0e --- /dev/null +++ b/media/libcubeb/tests/test_sanity.cpp @@ -0,0 +1,466 @@ +/* + * Copyright © 2011 Mozilla Foundation + * + * This program is made available under an ISC-style license. See the + * accompanying file LICENSE for details. + */ +#ifdef NDEBUG +#undef NDEBUG +#endif +#define _XOPEN_SOURCE 500 +#include "cubeb/cubeb.h" +#include +#include +#include +#include +#include "common.h" + +#define STREAM_LATENCY 100 +#define STREAM_RATE 44100 +#define STREAM_CHANNELS 1 +#define STREAM_FORMAT CUBEB_SAMPLE_S16LE + +static int dummy; +static uint64_t total_frames_written; +static int delay_callback; + +static long +test_data_callback(cubeb_stream * stm, void * user_ptr, void * p, long nframes) +{ + assert(stm && user_ptr == &dummy && p && nframes > 0); + memset(p, 0, nframes * sizeof(short)); + total_frames_written += nframes; + if (delay_callback) { + delay(10); + } + return nframes; +} + +void +test_state_callback(cubeb_stream * stm, void * user_ptr, cubeb_state state) +{ +} + +static void +test_init_destroy_context(void) +{ + int r; + cubeb * ctx; + + r = cubeb_init(&ctx, "test_sanity"); + assert(r == 0 && ctx); + + cubeb_destroy(ctx); +} + +static void +test_init_destroy_multiple_contexts(void) +{ + int i; + int r; + cubeb * ctx[4]; + + for (i = 0; i < 4; ++i) { + r = cubeb_init(&ctx[i], NULL); + assert(r == 0 && ctx[i]); + } + + /* destroy in a different order */ + cubeb_destroy(ctx[2]); + cubeb_destroy(ctx[0]); + cubeb_destroy(ctx[3]); + cubeb_destroy(ctx[1]); +} + +static void +test_init_destroy_stream(void) +{ + int r; + cubeb * ctx; + cubeb_stream * stream; + cubeb_stream_params params; + + r = cubeb_init(&ctx, "test_sanity"); + assert(r == 0 && ctx); + + params.format = STREAM_FORMAT; + params.rate = STREAM_RATE; + params.channels = STREAM_CHANNELS; + + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, + test_data_callback, test_state_callback, &dummy); + assert(r == 0 && stream); + + cubeb_stream_destroy(stream); + cubeb_destroy(ctx); +} + +static void +test_init_destroy_multiple_streams(void) +{ + int i; + int r; + cubeb * ctx; + cubeb_stream * stream[16]; + cubeb_stream_params params; + + r = cubeb_init(&ctx, "test_sanity"); + assert(r == 0 && ctx); + + params.format = STREAM_FORMAT; + params.rate = STREAM_RATE; + params.channels = STREAM_CHANNELS; + + for (i = 0; i < 16; ++i) { + r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY, + test_data_callback, test_state_callback, &dummy); + assert(r == 0 && stream[i]); + } + + for (i = 0; i < 16; ++i) { + cubeb_stream_destroy(stream[i]); + } + + cubeb_destroy(ctx); +} + +static void +test_init_start_stop_destroy_multiple_streams(int early, int delay_ms) +{ + int i; + int r; + cubeb * ctx; + cubeb_stream * stream[16]; + cubeb_stream_params params; + + r = cubeb_init(&ctx, "test_sanity"); + assert(r == 0 && ctx); + + params.format = STREAM_FORMAT; + params.rate = STREAM_RATE; + params.channels = STREAM_CHANNELS; + + for (i = 0; i < 16; ++i) { + r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY, + test_data_callback, test_state_callback, &dummy); + assert(r == 0 && stream[i]); + if (early) { + r = cubeb_stream_start(stream[i]); + assert(r == 0); + } + } + + + if (!early) { + for (i = 0; i < 16; ++i) { + r = cubeb_stream_start(stream[i]); + assert(r == 0); + } + } + + if (delay_ms) { + delay(delay_ms); + } + + if (!early) { + for (i = 0; i < 16; ++i) { + r = cubeb_stream_stop(stream[i]); + assert(r == 0); + } + } + + for (i = 0; i < 16; ++i) { + if (early) { + r = cubeb_stream_stop(stream[i]); + assert(r == 0); + } + cubeb_stream_destroy(stream[i]); + } + + cubeb_destroy(ctx); +} + +static void +test_init_destroy_multiple_contexts_and_streams(void) +{ + int i, j; + int r; + cubeb * ctx[4]; + cubeb_stream * stream[16]; + cubeb_stream_params params; + + params.format = STREAM_FORMAT; + params.rate = STREAM_RATE; + params.channels = STREAM_CHANNELS; + + for (i = 0; i < 4; ++i) { + r = cubeb_init(&ctx[i], "test_sanity"); + assert(r == 0 && ctx[i]); + + for (j = 0; j < 4; ++j) { + r = cubeb_stream_init(ctx[i], &stream[i * 4 + j], "test", params, STREAM_LATENCY, + test_data_callback, test_state_callback, &dummy); + assert(r == 0 && stream[i * 4 + j]); + } + } + + for (i = 0; i < 4; ++i) { + for (j = 0; j < 4; ++j) { + cubeb_stream_destroy(stream[i * 4 + j]); + } + cubeb_destroy(ctx[i]); + } +} + +static void +test_basic_stream_operations(void) +{ + int r; + cubeb * ctx; + cubeb_stream * stream; + cubeb_stream_params params; + uint64_t position; + + r = cubeb_init(&ctx, "test_sanity"); + assert(r == 0 && ctx); + + params.format = STREAM_FORMAT; + params.rate = STREAM_RATE; + params.channels = STREAM_CHANNELS; + + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, + test_data_callback, test_state_callback, &dummy); + assert(r == 0 && stream); + + /* position and volume before stream has started */ + r = cubeb_stream_get_position(stream, &position); + assert(r == 0 && position == 0); + + r = cubeb_stream_start(stream); + assert(r == 0); + + /* position and volume after while stream running */ + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + + r = cubeb_stream_stop(stream); + assert(r == 0); + + /* position and volume after stream has stopped */ + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + + cubeb_stream_destroy(stream); + cubeb_destroy(ctx); +} + +static void +test_stream_position(void) +{ + int i; + int r; + cubeb * ctx; + cubeb_stream * stream; + cubeb_stream_params params; + uint64_t position, last_position; + + total_frames_written = 0; + + r = cubeb_init(&ctx, "test_sanity"); + assert(r == 0 && ctx); + + params.format = STREAM_FORMAT; + params.rate = STREAM_RATE; + params.channels = STREAM_CHANNELS; + + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, + test_data_callback, test_state_callback, &dummy); + assert(r == 0 && stream); + + /* stream position should not advance before starting playback */ + r = cubeb_stream_get_position(stream, &position); + assert(r == 0 && position == 0); + + delay(500); + + r = cubeb_stream_get_position(stream, &position); + assert(r == 0 && position == 0); + + /* stream position should advance during playback */ + r = cubeb_stream_start(stream); + assert(r == 0); + + /* XXX let start happen */ + delay(500); + + /* stream should have prefilled */ + assert(total_frames_written > 0); + + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + last_position = position; + + delay(500); + + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + assert(position >= last_position); + last_position = position; + + /* stream position should not exceed total frames written */ + for (i = 0; i < 5; ++i) { + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + assert(position >= last_position); + assert(position <= total_frames_written); + last_position = position; + delay(500); + } + + assert(last_position != 0); + + /* stream position should not advance after stopping playback */ + r = cubeb_stream_stop(stream); + assert(r == 0); + + /* XXX allow stream to settle */ + delay(500); + + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + last_position = position; + + delay(500); + + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + assert(position == last_position); + + cubeb_stream_destroy(stream); + cubeb_destroy(ctx); +} + +static int do_drain; +static int got_drain; + +static long +test_drain_data_callback(cubeb_stream * stm, void * user_ptr, void * p, long nframes) +{ + assert(stm && user_ptr == &dummy && p && nframes > 0); + if (do_drain == 1) { + do_drain = 2; + return 0; + } + /* once drain has started, callback must never be called again */ + assert(do_drain != 2); + memset(p, 0, nframes * sizeof(short)); + total_frames_written += nframes; + return nframes; +} + +void +test_drain_state_callback(cubeb_stream * stm, void * user_ptr, cubeb_state state) +{ + if (state == CUBEB_STATE_DRAINED) { + assert(!got_drain); + got_drain = 1; + } +} + +static void +test_drain(void) +{ + int r; + cubeb * ctx; + cubeb_stream * stream; + cubeb_stream_params params; + uint64_t position; + + total_frames_written = 0; + + r = cubeb_init(&ctx, "test_sanity"); + assert(r == 0 && ctx); + + params.format = STREAM_FORMAT; + params.rate = STREAM_RATE; + params.channels = STREAM_CHANNELS; + + r = cubeb_stream_init(ctx, &stream, "test", params, STREAM_LATENCY, + test_drain_data_callback, test_drain_state_callback, &dummy); + assert(r == 0 && stream); + + r = cubeb_stream_start(stream); + assert(r == 0); + + delay(500); + + do_drain = 1; + + for (;;) { + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + if (got_drain) { + break; + } else { + // Latency passed to cubeb_stream_init is not really honored on OSX and + // winmm, skip this test. + const char * backend_id = cubeb_get_backend_id(ctx); + if (strcmp(backend_id, "audiounit") != 0 && + strcmp(backend_id, "winmm") != 0) { + /* Position should roughly be equal to the number of written frames. We + * need to take the latency into account. */ + int latency = (STREAM_LATENCY * STREAM_RATE) / 1000; + assert(position + latency <= total_frames_written); + } + } + delay(500); + } + + r = cubeb_stream_get_position(stream, &position); + assert(r == 0); + assert(got_drain); + + // Disabled due to failures in the ALSA backend. + //assert(position == total_frames_written); + + cubeb_stream_destroy(stream); + cubeb_destroy(ctx); +} + +static void +progress(void) +{ + printf("."); + fflush(stdout); +} + +int +main(int argc, char * argv[]) +{ + test_init_destroy_context(); progress(); + test_init_destroy_multiple_contexts(); progress(); + test_init_destroy_stream(); progress(); + test_init_destroy_multiple_streams(); progress(); + test_init_destroy_multiple_contexts_and_streams(); progress(); + test_basic_stream_operations(); progress(); + test_stream_position(); progress(); + delay_callback = 0; + test_init_start_stop_destroy_multiple_streams(0, 0); progress(); + test_init_start_stop_destroy_multiple_streams(1, 0); progress(); + test_init_start_stop_destroy_multiple_streams(0, 150); progress(); + test_init_start_stop_destroy_multiple_streams(1, 150); progress(); + delay_callback = 1; + test_init_start_stop_destroy_multiple_streams(0, 0); progress(); + test_init_start_stop_destroy_multiple_streams(1, 0); progress(); + test_init_start_stop_destroy_multiple_streams(0, 150); progress(); + test_init_start_stop_destroy_multiple_streams(1, 150); progress(); + delay_callback = 0; + test_drain(); +/* + to implement: + test_eos_during_prefill(); + test_stream_destroy_pending_drain(); +*/ + printf("\n"); + return 0; +} diff --git a/media/libcubeb/tests/test_tone.cpp b/media/libcubeb/tests/test_tone.cpp new file mode 100644 index 00000000000..c3e6cc75fac --- /dev/null +++ b/media/libcubeb/tests/test_tone.cpp @@ -0,0 +1,117 @@ +/* + * Copyright © 2011 Mozilla Foundation + * + * This program is made available under an ISC-style license. See the + * accompanying file LICENSE for details. + */ + +/* libcubeb api/function test. Plays a simple tone. */ +#ifdef NDEBUG +#undef NDEBUG +#endif +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include + +#include "cubeb/cubeb.h" +#include "common.h" + +#define SAMPLE_FREQUENCY 48000 + +/* store the phase of the generated waveform */ +struct cb_user_data { + long position; +}; + +long data_cb(cubeb_stream *stream, void *user, void *buffer, long nframes) +{ + struct cb_user_data *u = (struct cb_user_data *)user; + short *b = (short *)buffer; + int i; + + if (stream == NULL || u == NULL) + return CUBEB_ERROR; + + /* generate our test tone on the fly */ + for (i = 0; i < nframes; i++) { + /* North American dial tone */ + b[i] = 16000*sin(2*M_PI*(i + u->position)*350/SAMPLE_FREQUENCY); + b[i] += 16000*sin(2*M_PI*(i + u->position)*440/SAMPLE_FREQUENCY); + /* European dial tone */ + /*b[i] = 30000*sin(2*M_PI*(i + u->position)*425/SAMPLE_FREQUENCY);*/ + } + /* remember our phase to avoid clicking on buffer transitions */ + /* we'll still click if position overflows */ + u->position += nframes; + + return nframes; +} + +void state_cb(cubeb_stream *stream, void *user, cubeb_state state) +{ + struct cb_user_data *u = (struct cb_user_data *)user; + + if (stream == NULL || u == NULL) + return; + + switch (state) { + case CUBEB_STATE_STARTED: + printf("stream started\n"); break; + case CUBEB_STATE_STOPPED: + printf("stream stopped\n"); break; + case CUBEB_STATE_DRAINED: + printf("stream drained\n"); break; + default: + printf("unknown stream state %d\n", state); + } + + return; +} + +int main(int argc, char *argv[]) +{ + cubeb *ctx; + cubeb_stream *stream; + cubeb_stream_params params; + struct cb_user_data *user_data; + int ret; + + ret = cubeb_init(&ctx, "Cubeb tone example"); + if (ret != CUBEB_OK) { + fprintf(stderr, "Error initializing cubeb library\n"); + return ret; + } + + params.format = CUBEB_SAMPLE_S16NE; + params.rate = SAMPLE_FREQUENCY; + params.channels = 1; + + user_data = (struct cb_user_data *) malloc(sizeof(*user_data)); + if (user_data == NULL) { + fprintf(stderr, "Error allocating user data\n"); + return CUBEB_ERROR; + } + user_data->position = 0; + + ret = cubeb_stream_init(ctx, &stream, "Cubeb tone (mono)", params, + 250, data_cb, state_cb, user_data); + if (ret != CUBEB_OK) { + fprintf(stderr, "Error initializing cubeb stream\n"); + return ret; + } + + cubeb_stream_start(stream); + delay(500); + cubeb_stream_stop(stream); + + cubeb_stream_destroy(stream); + cubeb_destroy(ctx); + + assert(user_data->position); + + free(user_data); + + return CUBEB_OK; +} From 1140f95c5d05abccc16fa99604885ad53efc1532 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Mon, 24 Mar 2014 11:06:05 +0100 Subject: [PATCH 10/63] Bug 946618 - Skip some cubeb tests on some platforms. r=kinetik For example, skip float tests on platform that don't support floating point audio, and skip timing test on platform where we don't honor latency request. --HG-- extra : rebase_source : 6d48b637f18747674d519b586a24a8f4680f293b --- media/libcubeb/tests/test_audio.cpp | 37 +++++++-- media/libcubeb/tests/test_sanity.cpp | 108 ++++++++++++++++++++------- 2 files changed, 111 insertions(+), 34 deletions(-) diff --git a/media/libcubeb/tests/test_audio.cpp b/media/libcubeb/tests/test_audio.cpp index 5dfa468d18d..a7b2fb42d70 100644 --- a/media/libcubeb/tests/test_audio.cpp +++ b/media/libcubeb/tests/test_audio.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "cubeb/cubeb.h" #include "common.h" @@ -97,6 +98,20 @@ void state_cb(cubeb_stream *stream, void *user, cubeb_state state) { } +/* Our android backends don't support float, only int16. */ +int supports_float32(const char* backend_id) +{ + return (strcmp(backend_id, "opensl") != 0 && + strcmp(backend_id, "audiotrack") != 0); +} + +/* Some backends don't have code to deal with more than mono or stereo. */ +int supports_channel_count(const char* backend_id, int nchannels) +{ + return nchannels <= 2 || + (strcmp(backend_id, "opensl") != 0 && strcmp(backend_id, "audiotrack") != 0); +} + int run_test(int num_channels, int sampling_rate, int is_float) { int ret = CUBEB_OK; @@ -104,6 +119,7 @@ int run_test(int num_channels, int sampling_rate, int is_float) cubeb *ctx = NULL; synth_state* synth = NULL; cubeb_stream *stream = NULL; + const char * backend_id = NULL; ret = cubeb_init(&ctx, "Cubeb audio test"); if (ret != CUBEB_OK) { @@ -111,6 +127,14 @@ int run_test(int num_channels, int sampling_rate, int is_float) goto cleanup; } + backend_id = cubeb_get_backend_id(ctx); + + if ((is_float && !supports_float32(backend_id)) || + !supports_channel_count(backend_id, num_channels)) { + /* don't treat this as a test failure. */ + goto cleanup; + } + fprintf(stderr, "Testing %d channel(s), %d Hz, %s (%s)\n", num_channels, sampling_rate, is_float ? "float" : "short", cubeb_get_backend_id(ctx)); cubeb_stream_params params; @@ -125,7 +149,7 @@ int run_test(int num_channels, int sampling_rate, int is_float) } ret = cubeb_stream_init(ctx, &stream, "test tone", params, - 250, is_float ? data_cb_float : data_cb_short, state_cb, synth); + 100, is_float ? data_cb_float : data_cb_short, state_cb, synth); if (ret != CUBEB_OK) { fprintf(stderr, "Error initializing cubeb stream: %d\n", ret); goto cleanup; @@ -148,23 +172,24 @@ int main(int argc, char *argv[]) int channel_values[] = { 1, 2, + 3, 4, - 5, 6, }; int freq_values[] = { + 16000, 24000, 44100, 48000, }; - for(int j=0;j < NELEMS(channel_values);++j) { - for(int i=0;i < NELEMS(freq_values);++i) { + for(int j = 0; j < NELEMS(channel_values); ++j) { + for(int i = 0; i < NELEMS(freq_values); ++i) { assert(channel_values[j] < MAX_NUM_CHANNELS); fprintf(stderr, "--------------------------\n"); - run_test(channel_values[j], freq_values[i], 0); - run_test(channel_values[j], freq_values[i], 1); + assert(run_test(channel_values[j], freq_values[i], 0) == CUBEB_OK); + assert(run_test(channel_values[j], freq_values[i], 1) == CUBEB_OK); } } diff --git a/media/libcubeb/tests/test_sanity.cpp b/media/libcubeb/tests/test_sanity.cpp index ed83d37be0e..60f31c5ec90 100644 --- a/media/libcubeb/tests/test_sanity.cpp +++ b/media/libcubeb/tests/test_sanity.cpp @@ -15,6 +15,14 @@ #include #include "common.h" +#if defined ( WIN32 ) +#define __func__ __FUNCTION__ +#endif + +#define ARRAY_LENGTH(_x) (sizeof(_x) / sizeof(_x[0])) +#define BEGIN_TEST fprintf(stderr, "START %s\n", __func__); +#define END_TEST fprintf(stderr, "END %s\n", __func__); + #define STREAM_LATENCY 100 #define STREAM_RATE 44100 #define STREAM_CHANNELS 1 @@ -47,10 +55,14 @@ test_init_destroy_context(void) int r; cubeb * ctx; + BEGIN_TEST + r = cubeb_init(&ctx, "test_sanity"); assert(r == 0 && ctx); cubeb_destroy(ctx); + + END_TEST } static void @@ -60,6 +72,8 @@ test_init_destroy_multiple_contexts(void) int r; cubeb * ctx[4]; + BEGIN_TEST + for (i = 0; i < 4; ++i) { r = cubeb_init(&ctx[i], NULL); assert(r == 0 && ctx[i]); @@ -70,6 +84,8 @@ test_init_destroy_multiple_contexts(void) cubeb_destroy(ctx[0]); cubeb_destroy(ctx[3]); cubeb_destroy(ctx[1]); + + END_TEST } static void @@ -80,6 +96,8 @@ test_init_destroy_stream(void) cubeb_stream * stream; cubeb_stream_params params; + BEGIN_TEST + r = cubeb_init(&ctx, "test_sanity"); assert(r == 0 && ctx); @@ -93,6 +111,8 @@ test_init_destroy_stream(void) cubeb_stream_destroy(stream); cubeb_destroy(ctx); + + END_TEST } static void @@ -104,6 +124,8 @@ test_init_destroy_multiple_streams(void) cubeb_stream * stream[16]; cubeb_stream_params params; + BEGIN_TEST + r = cubeb_init(&ctx, "test_sanity"); assert(r == 0 && ctx); @@ -114,7 +136,8 @@ test_init_destroy_multiple_streams(void) for (i = 0; i < 16; ++i) { r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); - assert(r == 0 && stream[i]); + assert(r == 0); + assert(stream[i]); } for (i = 0; i < 16; ++i) { @@ -122,6 +145,8 @@ test_init_destroy_multiple_streams(void) } cubeb_destroy(ctx); + + END_TEST } static void @@ -133,6 +158,8 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms) cubeb_stream * stream[16]; cubeb_stream_params params; + BEGIN_TEST + r = cubeb_init(&ctx, "test_sanity"); assert(r == 0 && ctx); @@ -143,7 +170,8 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms) for (i = 0; i < 16; ++i) { r = cubeb_stream_init(ctx, &stream[i], "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); - assert(r == 0 && stream[i]); + assert(r == 0); + assert(stream[i]); if (early) { r = cubeb_stream_start(stream[i]); assert(r == 0); @@ -178,6 +206,8 @@ test_init_start_stop_destroy_multiple_streams(int early, int delay_ms) } cubeb_destroy(ctx); + + END_TEST } static void @@ -189,6 +219,8 @@ test_init_destroy_multiple_contexts_and_streams(void) cubeb_stream * stream[16]; cubeb_stream_params params; + BEGIN_TEST + params.format = STREAM_FORMAT; params.rate = STREAM_RATE; params.channels = STREAM_CHANNELS; @@ -200,7 +232,8 @@ test_init_destroy_multiple_contexts_and_streams(void) for (j = 0; j < 4; ++j) { r = cubeb_stream_init(ctx[i], &stream[i * 4 + j], "test", params, STREAM_LATENCY, test_data_callback, test_state_callback, &dummy); - assert(r == 0 && stream[i * 4 + j]); + assert(r == 0); + assert(stream[i * 4 + j]); } } @@ -210,6 +243,8 @@ test_init_destroy_multiple_contexts_and_streams(void) } cubeb_destroy(ctx[i]); } + + END_TEST } static void @@ -221,6 +256,8 @@ test_basic_stream_operations(void) cubeb_stream_params params; uint64_t position; + BEGIN_TEST + r = cubeb_init(&ctx, "test_sanity"); assert(r == 0 && ctx); @@ -252,6 +289,8 @@ test_basic_stream_operations(void) cubeb_stream_destroy(stream); cubeb_destroy(ctx); + + END_TEST } static void @@ -264,6 +303,8 @@ test_stream_position(void) cubeb_stream_params params; uint64_t position, last_position; + BEGIN_TEST + total_frames_written = 0; r = cubeb_init(&ctx, "test_sanity"); @@ -338,6 +379,8 @@ test_stream_position(void) cubeb_stream_destroy(stream); cubeb_destroy(ctx); + + END_TEST } static int do_drain; @@ -376,6 +419,8 @@ test_drain(void) cubeb_stream_params params; uint64_t position; + BEGIN_TEST + total_frames_written = 0; r = cubeb_init(&ctx, "test_sanity"); @@ -402,11 +447,23 @@ test_drain(void) if (got_drain) { break; } else { - // Latency passed to cubeb_stream_init is not really honored on OSX and - // winmm, skip this test. + uint32_t i, skip = 0; + /* Latency passed to cubeb_stream_init is not really honored on OSX, + win32/winmm and android, skip this test. */ const char * backend_id = cubeb_get_backend_id(ctx); - if (strcmp(backend_id, "audiounit") != 0 && - strcmp(backend_id, "winmm") != 0) { + const char * latency_not_honored_bakends[] = { + "audiounit", + "winmm", + "audiotrack", + "opensl" + }; + + for (i = 0; i < ARRAY_LENGTH(latency_not_honored_bakends); i++) { + if (!strcmp(backend_id, latency_not_honored_bakends[i])) { + skip = 1; + } + } + if (!skip) { /* Position should roughly be equal to the number of written frames. We * need to take the latency into account. */ int latency = (STREAM_LATENCY * STREAM_RATE) / 1000; @@ -425,35 +482,30 @@ test_drain(void) cubeb_stream_destroy(stream); cubeb_destroy(ctx); -} -static void -progress(void) -{ - printf("."); - fflush(stdout); + END_TEST } int main(int argc, char * argv[]) { - test_init_destroy_context(); progress(); - test_init_destroy_multiple_contexts(); progress(); - test_init_destroy_stream(); progress(); - test_init_destroy_multiple_streams(); progress(); - test_init_destroy_multiple_contexts_and_streams(); progress(); - test_basic_stream_operations(); progress(); - test_stream_position(); progress(); + test_init_destroy_context(); + test_init_destroy_multiple_contexts(); + test_init_destroy_stream(); + test_init_destroy_multiple_streams(); + test_init_destroy_multiple_contexts_and_streams(); + test_basic_stream_operations(); + test_stream_position(); delay_callback = 0; - test_init_start_stop_destroy_multiple_streams(0, 0); progress(); - test_init_start_stop_destroy_multiple_streams(1, 0); progress(); - test_init_start_stop_destroy_multiple_streams(0, 150); progress(); - test_init_start_stop_destroy_multiple_streams(1, 150); progress(); + test_init_start_stop_destroy_multiple_streams(0, 0); + test_init_start_stop_destroy_multiple_streams(1, 0); + test_init_start_stop_destroy_multiple_streams(0, 150); + test_init_start_stop_destroy_multiple_streams(1, 150); delay_callback = 1; - test_init_start_stop_destroy_multiple_streams(0, 0); progress(); - test_init_start_stop_destroy_multiple_streams(1, 0); progress(); - test_init_start_stop_destroy_multiple_streams(0, 150); progress(); - test_init_start_stop_destroy_multiple_streams(1, 150); progress(); + test_init_start_stop_destroy_multiple_streams(0, 0); + test_init_start_stop_destroy_multiple_streams(1, 0); + test_init_start_stop_destroy_multiple_streams(0, 150); + test_init_start_stop_destroy_multiple_streams(1, 150); delay_callback = 0; test_drain(); /* From ba92d7c5b829fd8b3085f34d3d94f9a298f6f9cd Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Tue, 25 Feb 2014 14:21:59 +0100 Subject: [PATCH 11/63] Bug 946618 - Add native tests for cubeb. r=kinetik --HG-- extra : rebase_source : 9b2e8e702ce5f8ea4d5416f3b45c91bc4cd94432 --- layout/media/symbols.def.in | 1 + media/libcubeb/moz.build | 1 + media/libcubeb/src/moz.build | 2 ++ media/libcubeb/tests/Makefile.in | 26 ++++++++++++++++++++++++++ media/libcubeb/tests/moz.build | 19 +++++++++++++++++++ media/libcubeb/update.sh | 6 ++++++ 6 files changed, 55 insertions(+) create mode 100644 media/libcubeb/tests/Makefile.in create mode 100644 media/libcubeb/tests/moz.build diff --git a/layout/media/symbols.def.in b/layout/media/symbols.def.in index c43406716d6..85a5d95722c 100644 --- a/layout/media/symbols.def.in +++ b/layout/media/symbols.def.in @@ -134,6 +134,7 @@ speex_resampler_reset_mem speex_resampler_strerror cubeb_destroy cubeb_init +cubeb_get_backend_id cubeb_get_max_channel_count cubeb_get_min_latency cubeb_get_preferred_sample_rate diff --git a/media/libcubeb/moz.build b/media/libcubeb/moz.build index e9b8e10b831..7fd2825404a 100644 --- a/media/libcubeb/moz.build +++ b/media/libcubeb/moz.build @@ -5,4 +5,5 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DIRS += ['include', 'src'] +TEST_TOOL_DIRS += ['tests'] diff --git a/media/libcubeb/src/moz.build b/media/libcubeb/src/moz.build index d4d540bb005..64a6146f50e 100644 --- a/media/libcubeb/src/moz.build +++ b/media/libcubeb/src/moz.build @@ -4,6 +4,8 @@ # 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/. +LIBRARY_NAME = 'cubeb' + SOURCES += [ 'cubeb.c', ] diff --git a/media/libcubeb/tests/Makefile.in b/media/libcubeb/tests/Makefile.in new file mode 100644 index 00000000000..b16ee8aa1b5 --- /dev/null +++ b/media/libcubeb/tests/Makefile.in @@ -0,0 +1,26 @@ +# -*- Mode: makefile; tab-width: 8; 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/. + +ifeq ($(OS_ARCH),WINNT) + # On windows, the WASAPI backend needs the resampler we have in + # /media/libspeex_resampler, so we can't get away with just linking cubeb's .o + LIBS = $(call EXPAND_LIBNAME_PATH,gkmedias,$(DEPTH)/layout/media) \ + $(NULL) +else + # Otherwise, we can just grab all the compiled .o and compile against that, + # linking the appriopriate libraries. + LIBS = $(call EXPAND_LIBNAME_PATH,cubeb,$(DEPTH)/media/libcubeb/src) + ifeq ($(OS_TARGET),Darwin) + LIBS += -framework AudioUnit -framework CoreAudio + else + ifeq ($(OS_TARGET), OpenBSD) + LIBS += -lsndio + else + LIBS += $(MOZ_ALSA_LIBS) \ + $(MOZ_PULSEAUDIO_LIBS) + endif + endif + LIBS += $(NULL) +endif diff --git a/media/libcubeb/tests/moz.build b/media/libcubeb/tests/moz.build new file mode 100644 index 00000000000..4f531e0f03b --- /dev/null +++ b/media/libcubeb/tests/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +CPP_UNIT_TESTS += [ + 'test_audio.cpp', + 'test_latency.cpp', + 'test_sanity.cpp', + 'test_tone.cpp' +] + +LOCAL_INCLUDES += [ + '../include' +] + +FAIL_ON_WARNINGS = True + diff --git a/media/libcubeb/update.sh b/media/libcubeb/update.sh index 5d012b7301a..1d055dece22 100644 --- a/media/libcubeb/update.sh +++ b/media/libcubeb/update.sh @@ -18,6 +18,12 @@ cp $1/src/android/sles_definitions.h src/android cp $1/LICENSE . cp $1/README . cp $1/AUTHORS . +cp $1/test/common.h tests/common.h +cp $1/test/test_audio.c tests/test_audio.cpp +cp $1/test/test_tone.c tests/test_tone.cpp +cp $1/test/test_sanity.c tests/test_sanity.cpp +cp $1/test/test_latency.c tests/test_latency.cpp + if [ -d $1/.git ]; then rev=$(cd $1 && git rev-parse --verify HEAD) dirty=$(cd $1 && git diff-index --name-only HEAD) From bdf73646add60b33fe5c4bf34987a8de95d30534 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Mon, 24 Mar 2014 11:06:05 +0100 Subject: [PATCH 12/63] Bug 946618 - Disable some cubeb tests on Android. r=kinetik We still have some kind of smoke test in test_audio.c, so that's kind of okay. --HG-- extra : rebase_source : a5b760c58e8365a96b310b4bd480c3c2262c0713 --- media/libcubeb/tests/moz.build | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/media/libcubeb/tests/moz.build b/media/libcubeb/tests/moz.build index 4f531e0f03b..9c029cdff8c 100644 --- a/media/libcubeb/tests/moz.build +++ b/media/libcubeb/tests/moz.build @@ -5,12 +5,16 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. CPP_UNIT_TESTS += [ - 'test_audio.cpp', - 'test_latency.cpp', - 'test_sanity.cpp', 'test_tone.cpp' ] +if CONFIG['OS_TARGET'] != 'Android': + CPP_UNIT_TESTS += [ + 'test_audio.cpp', + 'test_latency.cpp', + 'test_sanity.cpp' + ] + LOCAL_INCLUDES += [ '../include' ] From 2d520f1828be3d01d8f5f0ab5b77eff339a98067 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Mon, 24 Mar 2014 11:06:05 +0100 Subject: [PATCH 13/63] Bug 946618 - Disable part of a cubeb test on Windows 7. r=kinetik --HG-- extra : rebase_source : 1bf38b7cbb7e023b74ec1226e79f7bf01d739bd0 --- media/libcubeb/src/cubeb_wasapi.cpp | 25 +++++++++-------- media/libcubeb/tests/test_sanity.cpp | 42 +++++++++++++++++++++------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp index a2b5633d46f..135aa86bef6 100644 --- a/media/libcubeb/src/cubeb_wasapi.cpp +++ b/media/libcubeb/src/cubeb_wasapi.cpp @@ -328,8 +328,7 @@ wasapi_stream_render_loop(LPVOID stream) stm->context->set_mm_thread_characteristics("Audio", &mmcss_task_index); if (!mmcss_handle) { /* This is not fatal, but we might glitch under heavy load. */ - LOG("Unable to use mmcss to bump the render thread priority: %d", - GetLastError()); + LOG("Unable to use mmcss to bump the render thread priority: %x", GetLastError()); } hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -486,7 +485,7 @@ int wasapi_init(cubeb ** context, char const * context_name) (revert_mm_thread_characteristics_function) GetProcAddress( ctx->mmcss_module, "AvRevertMmThreadCharacteristics"); if (!(ctx->set_mm_thread_characteristics && ctx->revert_mm_thread_characteristics)) { - LOG("Could not load AvSetMmThreadCharacteristics or AvRevertMmThreadCharacteristics: %d", GetLastError()); + LOG("Could not load AvSetMmThreadCharacteristics or AvRevertMmThreadCharacteristics: %x", GetLastError()); FreeLibrary(ctx->mmcss_module); } } else { @@ -729,14 +728,14 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, stm->refill_event = CreateEvent(NULL, 0, 0, NULL); if (!stm->shutdown_event) { - LOG("Can't create the shutdown event, error: %d.", GetLastError()); + LOG("Can't create the shutdown event, error: %x.", GetLastError()); wasapi_stream_destroy(stm); return CUBEB_ERROR; } if (!stm->refill_event) { SafeRelease(stm->shutdown_event); - LOG("Can't create the refill event, error: %d.", GetLastError()); + LOG("Can't create the refill event, error: %x.", GetLastError()); wasapi_stream_destroy(stm); return CUBEB_ERROR; } @@ -744,6 +743,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, IMMDevice * device; hr = get_default_endpoint(&device); if (FAILED(hr)) { + LOG("Could not get default endpoint, error: %x", hr); wasapi_stream_destroy(stm); return CUBEB_ERROR; } @@ -755,7 +755,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, NULL, (void **)&stm->client); SafeRelease(device); if (FAILED(hr)) { - LOG("Could not activate the device to get an audio client."); + LOG("Could not activate the device to get an audio client: error: %x", hr); wasapi_stream_destroy(stm); return CUBEB_ERROR; } @@ -764,7 +764,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, * and the format the stream we want to play uses. */ hr = stm->client->GetMixFormat(&mix_format); if (FAILED(hr)) { - LOG("Could not fetch current mix format from the audio client."); + LOG("Could not fetch current mix format from the audio client: error: %x", hr); wasapi_stream_destroy(stm); return CUBEB_ERROR; } @@ -792,6 +792,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, SPEEX_RESAMPLER_QUALITY_DESKTOP, NULL); if (!stm->resampler) { + LOG("Could not get a resampler"); CoTaskMemFree(mix_format); wasapi_stream_destroy(stm); return CUBEB_ERROR; @@ -826,7 +827,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, hr = stm->client->GetBufferSize(&stm->buffer_frame_count); if (FAILED(hr)) { - LOG("Could not get the buffer size from the client."); + LOG("Could not get the buffer size from the client %x.", hr); wasapi_stream_destroy(stm); return CUBEB_ERROR; } @@ -846,7 +847,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, hr = stm->client->SetEventHandle(stm->refill_event); if (FAILED(hr)) { - LOG("Could set the event handle for the client."); + LOG("Could set the event handle for the client %x.", hr); wasapi_stream_destroy(stm); return CUBEB_ERROR; } @@ -854,7 +855,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, hr = stm->client->GetService(__uuidof(IAudioRenderClient), (void **)&stm->render_client); if (FAILED(hr)) { - LOG("Could not get the render client."); + LOG("Could not get the render client %x.", hr); wasapi_stream_destroy(stm); return CUBEB_ERROR; } @@ -862,14 +863,14 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream, hr = stm->client->GetService(__uuidof(IAudioClock), (void **)&stm->audio_clock); if (FAILED(hr)) { - LOG("Could not get the IAudioClock."); + LOG("Could not get the IAudioClock, %x", hr); wasapi_stream_destroy(stm); return CUBEB_ERROR; } hr = stm->audio_clock->GetFrequency(&stm->clock_freq); if (FAILED(hr)) { - LOG("failed to get audio clock frequency."); + LOG("failed to get audio clock frequency, %x", hr); return CUBEB_ERROR; } diff --git a/media/libcubeb/tests/test_sanity.cpp b/media/libcubeb/tests/test_sanity.cpp index 60f31c5ec90..6e36f3afe28 100644 --- a/media/libcubeb/tests/test_sanity.cpp +++ b/media/libcubeb/tests/test_sanity.cpp @@ -486,6 +486,20 @@ test_drain(void) END_TEST } +int is_windows_7() +{ +#ifdef __WIN32__ +#include + DWORD version = GetVersion(); + DWORD major = (DWORD) (LOBYTE(LOWORD(version))); + DWORD minor = (DWORD) (HIBYTE(LOWORD(version))); + + return (major == 6) && (minor == 1); +#else + return-0; +#endif +} + int main(int argc, char * argv[]) { @@ -496,16 +510,24 @@ main(int argc, char * argv[]) test_init_destroy_multiple_contexts_and_streams(); test_basic_stream_operations(); test_stream_position(); - delay_callback = 0; - test_init_start_stop_destroy_multiple_streams(0, 0); - test_init_start_stop_destroy_multiple_streams(1, 0); - test_init_start_stop_destroy_multiple_streams(0, 150); - test_init_start_stop_destroy_multiple_streams(1, 150); - delay_callback = 1; - test_init_start_stop_destroy_multiple_streams(0, 0); - test_init_start_stop_destroy_multiple_streams(1, 0); - test_init_start_stop_destroy_multiple_streams(0, 150); - test_init_start_stop_destroy_multiple_streams(1, 150); + + /* Sometimes, when using WASAPI on windows 7 (vista and 8 are okay), and + * calling Activate a lot on an AudioClient, 0x800700b7 is returned. This is + * the HRESULT value for "Cannot create a file when that file already exists", + * and is not documented as a possible return value for this call. Hence, we + * try to limit the number of streams we create in this test. */ + if (!is_windows_7()) { + delay_callback = 0; + test_init_start_stop_destroy_multiple_streams(0, 0); + test_init_start_stop_destroy_multiple_streams(1, 0); + test_init_start_stop_destroy_multiple_streams(0, 150); + test_init_start_stop_destroy_multiple_streams(1, 150); + delay_callback = 1; + test_init_start_stop_destroy_multiple_streams(0, 0); + test_init_start_stop_destroy_multiple_streams(1, 0); + test_init_start_stop_destroy_multiple_streams(0, 150); + test_init_start_stop_destroy_multiple_streams(1, 150); + } delay_callback = 0; test_drain(); /* From 868bd3671a62755107ebcabc950dd20326dfdc63 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Wed, 2 Apr 2014 14:42:11 +0200 Subject: [PATCH 14/63] Bug 986985 - Reconnect to the PulseAudio context if it is disconnected on stream creation. r=padenot,kinetik --HG-- extra : rebase_source : efb8239b2a3ac73c78185084276d4b9ec53e1a3f --- media/libcubeb/src/cubeb_pulse.c | 78 +++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/media/libcubeb/src/cubeb_pulse.c b/media/libcubeb/src/cubeb_pulse.c index 217e13be2e0..5e7010ebf8f 100644 --- a/media/libcubeb/src/cubeb_pulse.c +++ b/media/libcubeb/src/cubeb_pulse.c @@ -69,6 +69,7 @@ struct cubeb { pa_threaded_mainloop * mainloop; pa_context * context; pa_sink_info * default_sink_info; + char * context_name; int error; }; @@ -270,8 +271,38 @@ stream_cork(cubeb_stream * stm, enum cork_state state) } } +static void pulse_context_destroy(cubeb * ctx); static void pulse_destroy(cubeb * ctx); +static int +pulse_context_init(cubeb * ctx) +{ + if (ctx->context) { + assert(ctx->error == 1); + pulse_context_destroy(ctx); + } + + ctx->context = WRAP(pa_context_new)(WRAP(pa_threaded_mainloop_get_api)(ctx->mainloop), + ctx->context_name); + WRAP(pa_context_set_state_callback)(ctx->context, context_state_callback, ctx); + + WRAP(pa_threaded_mainloop_lock)(ctx->mainloop); + WRAP(pa_context_connect)(ctx->context, NULL, 0, NULL); + + if (wait_until_context_ready(ctx) != 0) { + WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); + pulse_context_destroy(ctx); + ctx->context = NULL; + return -1; + } + + WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); + + ctx->error = 0; + + return 0; +} + /*static*/ int pulse_init(cubeb ** context, char const * context_name) { @@ -343,20 +374,17 @@ pulse_init(cubeb ** context, char const * context_name) ctx->libpulse = libpulse; ctx->mainloop = WRAP(pa_threaded_mainloop_new)(); - ctx->context = WRAP(pa_context_new)(WRAP(pa_threaded_mainloop_get_api)(ctx->mainloop), context_name); ctx->default_sink_info = NULL; - WRAP(pa_context_set_state_callback)(ctx->context, context_state_callback, ctx); WRAP(pa_threaded_mainloop_start)(ctx->mainloop); - WRAP(pa_threaded_mainloop_lock)(ctx->mainloop); - WRAP(pa_context_connect)(ctx->context, NULL, 0, NULL); - - if (wait_until_context_ready(ctx) != 0) { - WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); + ctx->context_name = context_name ? strdup(context_name) : NULL; + if (pulse_context_init(ctx) != 0) { pulse_destroy(ctx); return CUBEB_ERROR; } + + WRAP(pa_threaded_mainloop_lock)(ctx->mainloop); WRAP(pa_context_get_server_info)(ctx->context, server_info_callback, ctx); WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); @@ -408,22 +436,33 @@ pulse_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latenc return CUBEB_OK; } +static void +pulse_context_destroy(cubeb * ctx) +{ + pa_operation * o; + + WRAP(pa_threaded_mainloop_lock)(ctx->mainloop); + o = WRAP(pa_context_drain)(ctx->context, context_notify_callback, ctx); + if (o) { + operation_wait(ctx, NULL, o); + WRAP(pa_operation_unref)(o); + } + WRAP(pa_context_set_state_callback)(ctx->context, NULL, NULL); + WRAP(pa_context_disconnect)(ctx->context); + WRAP(pa_context_unref)(ctx->context); + WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); +} + static void pulse_destroy(cubeb * ctx) { pa_operation * o; + if (ctx->context_name) { + free(ctx->context_name); + } if (ctx->context) { - WRAP(pa_threaded_mainloop_lock)(ctx->mainloop); - o = WRAP(pa_context_drain)(ctx->context, context_notify_callback, ctx); - if (o) { - operation_wait(ctx, NULL, o); - WRAP(pa_operation_unref)(o); - } - WRAP(pa_context_set_state_callback)(ctx->context, NULL, NULL); - WRAP(pa_context_disconnect)(ctx->context); - WRAP(pa_context_unref)(ctx->context); - WRAP(pa_threaded_mainloop_unlock)(ctx->mainloop); + pulse_context_destroy(ctx); } if (ctx->mainloop) { @@ -475,6 +514,11 @@ pulse_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n return CUBEB_ERROR_INVALID_FORMAT; } + // If the connection failed for some reason, try to reconnect + if (context->error == 1 && pulse_context_init(context) != 0) { + return CUBEB_ERROR; + } + ss.rate = stream_params.rate; ss.channels = stream_params.channels; From d5ddc93df5f9f3a52a9660e7efd4c0056246a446 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Wed, 2 Apr 2014 08:53:04 -0400 Subject: [PATCH 15/63] Bug 990202 - Move the test page to a new window to prevent it from navigating the test runner frame back; r=bzbarsky --- docshell/test/file_framedhistoryframes.html | 16 ++++++++++++++++ docshell/test/mochitest.ini | 1 + docshell/test/test_framedhistoryframes.html | 3 ++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 docshell/test/file_framedhistoryframes.html diff --git a/docshell/test/file_framedhistoryframes.html b/docshell/test/file_framedhistoryframes.html new file mode 100644 index 00000000000..314f9c72d89 --- /dev/null +++ b/docshell/test/file_framedhistoryframes.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/docshell/test/mochitest.ini b/docshell/test/mochitest.ini index b20b8b3a682..41e16b9ae59 100644 --- a/docshell/test/mochitest.ini +++ b/docshell/test/mochitest.ini @@ -97,6 +97,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec [test_bug797909.html] [test_framedhistoryframes.html] skip-if = toolkit == 'android' #bug 784321 +support-files = file_framedhistoryframes.html [test_pushState_after_document_open.html] [test_windowedhistoryframes.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage diff --git a/docshell/test/test_framedhistoryframes.html b/docshell/test/test_framedhistoryframes.html index b6981780845..916a6229d39 100644 --- a/docshell/test/test_framedhistoryframes.html +++ b/docshell/test/test_framedhistoryframes.html @@ -12,7 +12,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=602256 Mozilla Bug 602256

-
 
+  
+  
+
+
+

+ +
+
+
+ + + From d9e2f3f810fa582db73de7c6aacd6ddeb0a1ac3f Mon Sep 17 00:00:00 2001 From: "J.R. Oldroyd" Date: Wed, 2 Apr 2014 09:02:06 -0400 Subject: [PATCH 22/63] Bug 893397 - Add FreeBSD support for NeckoWifi. r=ted, r=jdm --- configure.in | 2 +- netwerk/wifi/moz.build | 4 + netwerk/wifi/nsWifiScannerFreeBSD.cpp | 167 ++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 netwerk/wifi/nsWifiScannerFreeBSD.cpp diff --git a/configure.in b/configure.in index 8f9d85cd653..fd907e8d0f4 100644 --- a/configure.in +++ b/configure.in @@ -8281,7 +8281,7 @@ case "$OS_TARGET" in NECKO_WIFI=1 fi ;; - Darwin|SunOS|WINNT) + Darwin|FreeBSD|SunOS|WINNT) NECKO_WIFI=1 ;; Linux) diff --git a/netwerk/wifi/moz.build b/netwerk/wifi/moz.build index 26498f931ca..017defc4d22 100644 --- a/netwerk/wifi/moz.build +++ b/netwerk/wifi/moz.build @@ -35,6 +35,10 @@ if CONFIG['OS_ARCH'] == 'Darwin': UNIFIED_SOURCES += [ 'osx_corewlan.mm', ] +elif CONFIG['OS_ARCH'] == 'FreeBSD': + UNIFIED_SOURCES += [ + 'nsWifiScannerFreeBSD.cpp', + ] elif CONFIG['OS_ARCH'] == 'WINNT': UNIFIED_SOURCES += [ 'nsWifiScannerWin.cpp', diff --git a/netwerk/wifi/nsWifiScannerFreeBSD.cpp b/netwerk/wifi/nsWifiScannerFreeBSD.cpp new file mode 100644 index 00000000000..74bc82eaf52 --- /dev/null +++ b/netwerk/wifi/nsWifiScannerFreeBSD.cpp @@ -0,0 +1,167 @@ +/* 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/. */ + +// Developed by J.R. Oldroyd , December 2012. + +// For FreeBSD we use the getifaddrs(3) to obtain the list of interfaces +// and then check for those with an 802.11 media type and able to return +// a list of stations. This is similar to ifconfig(8). + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "nsWifiAccessPoint.h" + +using namespace mozilla; + +static nsresult +FreeBSDGetAccessPointData(nsCOMArray &accessPoints) +{ + // get list of interfaces + struct ifaddrs *ifal; + if (getifaddrs(&ifal) < 0) { + return NS_ERROR_FAILURE; + } + + accessPoints.Clear(); + + // loop through the interfaces + nsresult rv = NS_ERROR_FAILURE; + struct ifaddrs *ifa; + for (ifa = ifal; ifa; ifa = ifa->ifa_next) { + // limit to one interface per address + if (ifa->ifa_addr->sa_family != AF_LINK) { + continue; + } + + // store interface name in socket structure + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); + ifr.ifr_addr.sa_family = AF_LOCAL; + + // open socket to interface + int s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); + if (s < 0) { + continue; + } + + // clear interface media structure + struct ifmediareq ifmr; + memset(&ifmr, 0, sizeof(ifmr)); + strncpy(ifmr.ifm_name, ifa->ifa_name, sizeof(ifmr.ifm_name)); + + // get interface media information + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { + close(s); + continue; + } + + // check interface is a WiFi interface + if (IFM_TYPE(ifmr.ifm_active) != IFM_IEEE80211) { + close(s); + continue; + } + + // perform WiFi scan + struct ieee80211req i802r; + char iscanbuf[32*1024]; + memset(&i802r, 0, sizeof(i802r)); + strncpy(i802r.i_name, ifa->ifa_name, sizeof(i802r.i_name)); + i802r.i_type = IEEE80211_IOC_SCAN_RESULTS; + i802r.i_data = iscanbuf; + i802r.i_len = sizeof(iscanbuf); + if (ioctl(s, SIOCG80211, &i802r) < 0) { + close(s); + continue; + } + + // close socket + close(s); + + // loop through WiFi networks and build geoloc-lookup structure + char *vsr = (char *) i802r.i_data; + unsigned len = i802r.i_len; + while (len >= sizeof(struct ieee80211req_scan_result)) { + struct ieee80211req_scan_result *isr = + (struct ieee80211req_scan_result *) vsr; + + // determine size of this entry + char *id; + int idlen; + if (isr->isr_meshid_len) { + id = vsr + isr->isr_ie_off + isr->isr_ssid_len; + idlen = isr->isr_meshid_len; + } else { + id = vsr + isr->isr_ie_off; + idlen = isr->isr_ssid_len; + } + + // copy network data + char ssid[IEEE80211_NWID_LEN+1]; + strncpy(ssid, id, idlen); + ssid[idlen] = '\0'; + nsWifiAccessPoint *ap = new nsWifiAccessPoint(); + ap->setSSID(ssid, strlen(ssid)); + ap->setMac(isr->isr_bssid); + ap->setSignal(isr->isr_rssi); + accessPoints.AppendObject(ap); + rv = NS_OK; + + // log the data + LOG(( "FreeBSD access point: " + "SSID: %s, MAC: %02x-%02x-%02x-%02x-%02x-%02x, " + "Strength: %d, Channel: %dMHz\n", + ssid, isr->isr_bssid[0], isr->isr_bssid[1], isr->isr_bssid[2], + isr->isr_bssid[3], isr->isr_bssid[4], isr->isr_bssid[5], + isr->isr_rssi, isr->isr_freq)); + + // increment pointers + len -= isr->isr_len; + vsr += isr->isr_len; + } + } + + freeifaddrs(ifal); + + return rv; +} + +nsresult +nsWifiMonitor::DoScan() +{ + // Regularly get the access point data. + + nsCOMArray lastAccessPoints; + nsCOMArray accessPoints; + + do { + nsresult rv = FreeBSDGetAccessPointData(accessPoints); + if (NS_FAILED(rv)) + return rv; + + bool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints); + ReplaceArray(lastAccessPoints, accessPoints); + + rv = CallWifiListeners(lastAccessPoints, accessPointsChanged); + NS_ENSURE_SUCCESS(rv, rv); + + // wait for some reasonable amount of time. pref? + LOG(("waiting on monitor\n")); + + ReentrantMonitorAutoEnter mon(mReentrantMonitor); + mon.Wait(PR_SecondsToInterval(60)); + } + while (mKeepGoing); + + return NS_OK; +} From 3f0be9b595268163b2ebfa0947cb4c6d9318fb4a Mon Sep 17 00:00:00 2001 From: Randy Lin Date: Wed, 2 Apr 2014 09:59:31 +0800 Subject: [PATCH 23/63] Bug 912627 - Remove spurious assertion. r=cpearce --- content/media/MediaDecoder.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/content/media/MediaDecoder.cpp b/content/media/MediaDecoder.cpp index 9440a6beaff..81cca612f05 100644 --- a/content/media/MediaDecoder.cpp +++ b/content/media/MediaDecoder.cpp @@ -698,7 +698,6 @@ void MediaDecoder::QueueMetadata(int64_t aPublishTime, bool MediaDecoder::IsDataCachedToEndOfResource() { - NS_ASSERTION(!mShuttingDown, "Don't call during shutdown!"); ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); return (mResource && mResource->IsDataCachedToEndOfResource(mDecoderPosition)); From 55b87a048bcff7b54e0bb39b54610e43741eeb65 Mon Sep 17 00:00:00 2001 From: Qiang Lu Date: Thu, 20 Mar 2014 21:37:16 +0800 Subject: [PATCH 24/63] Bug 973761 - [WebRTC] Check device capabilities (HW codec and Android ver) before enabling vp8 hardware acceleration on Fennec. r=bjacob, r=gcp --- modules/libpref/src/init/all.js | 3 +++ widget/android/GfxInfo.cpp | 22 ++++++++++++++++++++-- widget/nsIGfxInfo.idl | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index b6898fd6a99..79e3cf4b587 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -277,6 +277,9 @@ pref("media.peerconnection.capture_delay", 50); pref("media.peerconnection.capture_delay", 50); #elif defined(ANDROID) pref("media.peerconnection.capture_delay", 100); +// Whether to enable Webrtc Hardware acceleration support +pref("media.navigator.hardware.vp8_encode.acceleration_enabled", false); +pref("media.navigator.hardware.vp8_decode.acceleration_enabled", false); #elif defined(XP_LINUX) pref("media.peerconnection.capture_delay", 70); #else diff --git a/widget/android/GfxInfo.cpp b/widget/android/GfxInfo.cpp index 2afc9f9aea8..f649905570a 100644 --- a/widget/android/GfxInfo.cpp +++ b/widget/android/GfxInfo.cpp @@ -480,7 +480,7 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature, { // Honeycomb Samsung devices are whitelisted. // All other Honeycomb devices are blacklisted. - bool isWhitelisted = + bool isWhitelisted = cManufacturer.Equals("samsung", nsCaseInsensitiveCStringComparator()); if (!isWhitelisted) { @@ -549,6 +549,24 @@ GfxInfo::GetFeatureStatusImpl(int32_t aFeature, } } } + + if (aFeature == FEATURE_WEBRTC_HW_ACCELERATION) { + NS_LossyConvertUTF16toASCII cManufacturer(mManufacturer); + NS_LossyConvertUTF16toASCII cModel(mModel); + NS_LossyConvertUTF16toASCII cHardware(mHardware); + + if (cHardware.Equals("hammerhead") && + CompareVersions(mOSVersion.get(), "4.4.2") >= 0 && + cManufacturer.Equals("lge", nsCaseInsensitiveCStringComparator()) && + cModel.Equals("nexus 5", nsCaseInsensitiveCStringComparator())) { + *aStatus = nsIGfxInfo::FEATURE_NO_INFO; + return NS_OK; + } else { + // Blocklist all other devices except Nexus 5 which VP8 hardware acceleration is supported + *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; + return NS_OK; + } + } } return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os); @@ -623,4 +641,4 @@ uint32_t GfxInfo::OperatingSystemVersion() } } -} \ No newline at end of file +} diff --git a/widget/nsIGfxInfo.idl b/widget/nsIGfxInfo.idl index 36daf6b2759..5c26e67f227 100644 --- a/widget/nsIGfxInfo.idl +++ b/widget/nsIGfxInfo.idl @@ -79,6 +79,8 @@ interface nsIGfxInfo : nsISupports const long FEATURE_WEBGL_MSAA = 8; /* Whether Stagefright is supported */ const long FEATURE_STAGEFRIGHT = 9; + /* Whether Webrtc Hardware acceleration is supported */ + const long FEATURE_WEBRTC_HW_ACCELERATION = 10; /* * A set of return values from GetFeatureStatus From 98a1b26a3bf367209f3b41f7f9a08ec72c1034cc Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Wed, 2 Apr 2014 09:02:07 -0400 Subject: [PATCH 25/63] Bug 978479 - Remove flipped quad texture from mQuadVBO. r=bjacob --- gfx/layers/opengl/CompositorOGL.cpp | 32 ++++++++++------------------- gfx/layers/opengl/CompositorOGL.h | 11 ++++------ 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index d52718a09b4..e37a2e749d2 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -372,8 +372,6 @@ CompositorOGL::Initialize() 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, /* Then quad texcoords */ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - /* Then flipped quad texcoords */ - 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER, sizeof(vertices), vertices, LOCAL_GL_STATIC_DRAW); mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); @@ -479,7 +477,7 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg, Matrix4x4 transform; ToMatrix4x4(aTextureTransform * textureTransform, transform); aProg->SetTextureTransform(transform); - BindAndDrawQuad(aProg, false); + BindAndDrawQuad(aProg); } else { Matrix4x4 transform; ToMatrix4x4(aTextureTransform, transform); @@ -988,7 +986,7 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect, BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE0, maskQuadTransform); } - BindAndDrawQuad(program, false, aDrawMode); + BindAndDrawQuad(program, aDrawMode); } break; @@ -1072,7 +1070,12 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect, surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget); - program->SetTextureTransform(Matrix4x4()); + // Drawing is always flipped, but when copying between surfaces we want to avoid + // this, so apply a flip here to cancel the other one out. + Matrix transform; + transform.Translate(0.0, 1.0); + transform.Scale(1.0f, -1.0f); + program->SetTextureTransform(Matrix4x4::From2D(transform)); program->SetTextureUnit(0); if (maskType != MaskNone) { @@ -1089,7 +1092,7 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect, // Drawing is always flipped, but when copying between surfaces we want to avoid // this. Pass true for the flip parameter to introduce a second flip // that cancels the other one out. - BindAndDrawQuad(program, true); + BindAndDrawQuad(program); } break; case EFFECT_COMPONENT_ALPHA: { @@ -1429,28 +1432,16 @@ CompositorOGL::QuadVBOTexCoordsAttrib(GLuint aAttribIndex) { (GLvoid*) QuadVBOTexCoordOffset()); } -void -CompositorOGL::QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex) { - mGLContext->fVertexAttribPointer(aAttribIndex, 2, - LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, - (GLvoid*) QuadVBOFlippedTexCoordOffset()); -} - void CompositorOGL::BindAndDrawQuad(GLuint aVertAttribIndex, GLuint aTexCoordAttribIndex, - bool aFlipped, GLuint aDrawMode) { BindQuadVBO(); QuadVBOVerticesAttrib(aVertAttribIndex); if (aTexCoordAttribIndex != GLuint(-1)) { - if (aFlipped) - QuadVBOFlippedTexCoordsAttrib(aTexCoordAttribIndex); - else - QuadVBOTexCoordsAttrib(aTexCoordAttribIndex); - + QuadVBOTexCoordsAttrib(aTexCoordAttribIndex); mGLContext->fEnableVertexAttribArray(aTexCoordAttribIndex); } @@ -1464,13 +1455,12 @@ CompositorOGL::BindAndDrawQuad(GLuint aVertAttribIndex, void CompositorOGL::BindAndDrawQuad(ShaderProgramOGL *aProg, - bool aFlipped, GLuint aDrawMode) { NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized"); BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib), aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib), - aFlipped, aDrawMode); + aDrawMode); } GLuint diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 2b166a08f17..33d036cccb0 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -311,9 +311,10 @@ private: CompositingRenderTargetOGL* mWindowRenderTarget; #endif - /** VBO that has some basics in it for a textured quad, - * including vertex coords and texcoords for both - * flipped and unflipped textures */ + /** + * VBO that has some basics in it for a textured quad, including vertex + * coords and texcoords. + */ GLuint mQuadVBO; /** @@ -366,18 +367,14 @@ private: GLintptr QuadVBOVertexOffset() { return 0; } GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; } - GLintptr QuadVBOFlippedTexCoordOffset() { return sizeof(float)*8*2; } void BindQuadVBO(); void QuadVBOVerticesAttrib(GLuint aAttribIndex); void QuadVBOTexCoordsAttrib(GLuint aAttribIndex); - void QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex); void BindAndDrawQuad(GLuint aVertAttribIndex, GLuint aTexCoordAttribIndex, - bool aFlipped = false, GLuint aDrawMode = LOCAL_GL_TRIANGLE_STRIP); void BindAndDrawQuad(ShaderProgramOGL *aProg, - bool aFlipped = false, GLuint aDrawMode = LOCAL_GL_TRIANGLE_STRIP); void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg, const gfx3DMatrix& aTextureTransform, From d5714a2ac30acb85d37f3c32cc0bb7981e58dffc Mon Sep 17 00:00:00 2001 From: James Graham Date: Wed, 2 Apr 2014 14:32:41 +0100 Subject: [PATCH 26/63] Bug 985606 - Improve API for reading structured logs, r=ahal --- testing/mozbase/docs/mozlog_structured.rst | 20 +++-- .../mozlog/structured/formatters/base.py | 23 +----- .../mozlog/mozlog/structured/reader.py | 49 +++++++++++- .../mozbase/mozlog/tests/test_structured.py | 80 ++++++++++++++++++- 4 files changed, 135 insertions(+), 37 deletions(-) diff --git a/testing/mozbase/docs/mozlog_structured.rst b/testing/mozbase/docs/mozlog_structured.rst index d1a1367e080..9b338995088 100644 --- a/testing/mozbase/docs/mozlog_structured.rst +++ b/testing/mozbase/docs/mozlog_structured.rst @@ -261,16 +261,14 @@ Count the number of tests that timed out in a testsuite:: from mozlog.structured import reader - class TestCounter(object): - def count(filename): - self.count = 0 - with open(filename) as f: - reader.map_action(reader.read(f), - {"test_end":self.process_test_end}) - return self.count + count = 0; - def process_test_end(self, data): - if data["status"] == "TIMEOUT": - self.count += 1 + def handle_test_end(data): + global count + if data["status"] == "TIMEOUT": + count += 1 - print TestCounter().count("my_test_run.log") + reader.each_log(reader.read("my_test_run.log"), + {"test_end": handle_test_end}) + + print count diff --git a/testing/mozbase/mozlog/mozlog/structured/formatters/base.py b/testing/mozbase/mozlog/mozlog/structured/formatters/base.py index b0f210f5680..18cc35be02f 100644 --- a/testing/mozbase/mozlog/mozlog/structured/formatters/base.py +++ b/testing/mozbase/mozlog/mozlog/structured/formatters/base.py @@ -3,9 +3,9 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import json +from ..reader import LogHandler - -class BaseFormatter(object): +class BaseFormatter(LogHandler): """Base class for implementing non-trivial formatters. Subclasses are expected to provide a method for each action type they @@ -18,22 +18,3 @@ class BaseFormatter(object): #For simplicity in the example pretend the id is always a string return data["test"] """ - def __init__(self): - pass - - def __call__(self, data): - if hasattr(self, data["action"]): - handler = getattr(self, data["action"]) - return handler(data) - - -def format_file(input_file, handler): - while True: - line = input_file.readline() - if not line: - break - try: - data = json.loads(line.strip()) - formatter(data) - except: - pass diff --git a/testing/mozbase/mozlog/mozlog/structured/reader.py b/testing/mozbase/mozlog/mozlog/structured/reader.py index 9d8001d344f..9daac42a774 100644 --- a/testing/mozbase/mozlog/mozlog/structured/reader.py +++ b/testing/mozbase/mozlog/mozlog/structured/reader.py @@ -11,7 +11,11 @@ def read(log_f, raise_on_error=False): :param log_f: file-like object containing the raw log entries, one per line :param raise_on_error: boolean indicating whether ValueError should be raised for lines that cannot be decoded.""" - for line in log_f: + while True: + line = log_f.readline() + if not line: + # This allows log_f to be a stream like stdout + break try: yield json.loads(line) except ValueError: @@ -19,9 +23,9 @@ def read(log_f, raise_on_error=False): raise -def map_action(log_iter, action_map): - """Call a callback per action for each item in a iterable containing structured - log entries +def imap_log(log_iter, action_map): + """Create an iterator that will invoke a callback per action for each item in a + iterable containing structured log entries :param log_iter: Iterator returning structured log entries :param action_map: Dictionary mapping action name to callback function. Log items @@ -30,3 +34,40 @@ def map_action(log_iter, action_map): for item in log_iter: if item["action"] in action_map: yield action_map[item["action"]](item) + +def each_log(log_iter, action_map): + """Call a callback for each item in an iterable containing structured + log entries + + :param log_iter: Iterator returning structured log entries + :param action_map: Dictionary mapping action name to callback function. Log items + with actions not in this dictionary will be skipped. + """ + for item in log_iter: + if item["action"] in action_map: + action_map[item["action"]](item) + +class LogHandler(object): + """Base class for objects that act as log handlers. A handler is a callable + that takes a log entry as the only argument. + + Subclasses are expected to provide a method for each action type they + wish to handle, each taking a single argument for the test data. + For example a trivial subclass that just produces the id of each test as + it starts might be:: + + class StartIdHandler(LogHandler): + def test_start(data): + #For simplicity in the example pretend the id is always a string + return data["test"] + """ + + def __call__(self, data): + if hasattr(self, data["action"]): + handler = getattr(self, data["action"]) + return handler(data) + +def handle_log(log_iter, handler): + """Call a handler for each item in a log, discarding the return value""" + for item in log_iter: + handler(item) diff --git a/testing/mozbase/mozlog/tests/test_structured.py b/testing/mozbase/mozlog/tests/test_structured.py index 02a5e7395a4..6e1a087b73c 100644 --- a/testing/mozbase/mozlog/tests/test_structured.py +++ b/testing/mozbase/mozlog/tests/test_structured.py @@ -2,8 +2,9 @@ import os import time import unittest import StringIO +import json -from mozlog.structured import structuredlog +from mozlog.structured import structuredlog, reader class TestHandler(object): @@ -181,5 +182,82 @@ class TestStructuredLog(BaseStructuredTest): "level": "INFO", "message": "line 4"}) +class TestReader(unittest.TestCase): + def to_file_like(self, obj): + data_str = "\n".join(json.dumps(item) for item in obj) + return StringIO.StringIO(data_str) + + def test_read(self): + data = [{"action": "action_0", "data": "data_0"}, + {"action": "action_1", "data": "data_1"}] + + f = self.to_file_like(data) + self.assertEquals(data, list(reader.read(f))) + + def test_imap_log(self): + data = [{"action": "action_0", "data": "data_0"}, + {"action": "action_1", "data": "data_1"}] + + f = self.to_file_like(data) + + def f_action_0(item): + return ("action_0", item["data"]) + + def f_action_1(item): + return ("action_1", item["data"]) + + res_iter = reader.imap_log(reader.read(f), + {"action_0": f_action_0, + "action_1": f_action_1}) + self.assertEquals([("action_0", "data_0"), ("action_1", "data_1")], + list(res_iter)) + + def test_each_log(self): + data = [{"action": "action_0", "data": "data_0"}, + {"action": "action_1", "data": "data_1"}] + + f = self.to_file_like(data) + + count = {"action_0":0, + "action_1":0} + + def f_action_0(item): + count[item["action"]] += 1 + + def f_action_1(item): + count[item["action"]] += 2 + + reader.each_log(reader.read(f), + {"action_0": f_action_0, + "action_1": f_action_1}) + + self.assertEquals({"action_0":1, "action_1":2}, count) + + def test_handler(self): + data = [{"action": "action_0", "data": "data_0"}, + {"action": "action_1", "data": "data_1"}] + + f = self.to_file_like(data) + + test = self + class ReaderTestHandler(reader.LogHandler): + def __init__(self): + self.action_0_count = 0 + self.action_1_count = 0 + + def action_0(self, item): + test.assertEquals(item["action"], "action_0") + self.action_0_count += 1 + + def action_1(self, item): + test.assertEquals(item["action"], "action_1") + self.action_1_count += 1 + + handler = ReaderTestHandler() + reader.handle_log(reader.read(f), handler) + + self.assertEquals(handler.action_0_count, 1) + self.assertEquals(handler.action_1_count, 1) + if __name__ == "__main__": unittest.main() From a250e383425831c46aee928b6568395ef3a1b1e3 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 2 Apr 2014 03:27:42 -0400 Subject: [PATCH 27/63] Bug 984490 - Make Compositor::GetCurrentRenderTarget() const. r=nical --- gfx/layers/Compositor.h | 2 +- gfx/layers/basic/BasicCompositor.h | 2 +- gfx/layers/d3d11/CompositorD3D11.h | 2 +- gfx/layers/d3d9/CompositorD3D9.h | 2 +- gfx/layers/opengl/CompositorOGL.cpp | 2 +- gfx/layers/opengl/CompositorOGL.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index 5cd8d9302c1..bb4cc5c7421 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -291,7 +291,7 @@ public: * Returns the current target for rendering. Will return null if we are * rendering to the screen. */ - virtual CompositingRenderTarget* GetCurrentRenderTarget() = 0; + virtual CompositingRenderTarget* GetCurrentRenderTarget() const = 0; /** * Mostly the compositor will pull the size from a widget and this method will diff --git a/gfx/layers/basic/BasicCompositor.h b/gfx/layers/basic/BasicCompositor.h index 26eee5c9883..c3b7e0e83a1 100644 --- a/gfx/layers/basic/BasicCompositor.h +++ b/gfx/layers/basic/BasicCompositor.h @@ -73,7 +73,7 @@ public: { mRenderTarget = static_cast(aSource); } - virtual CompositingRenderTarget* GetCurrentRenderTarget() MOZ_OVERRIDE + virtual CompositingRenderTarget* GetCurrentRenderTarget() const MOZ_OVERRIDE { return mRenderTarget; } diff --git a/gfx/layers/d3d11/CompositorD3D11.h b/gfx/layers/d3d11/CompositorD3D11.h index e110f04f123..98af8dce4cd 100644 --- a/gfx/layers/d3d11/CompositorD3D11.h +++ b/gfx/layers/d3d11/CompositorD3D11.h @@ -71,7 +71,7 @@ public: const gfx::IntPoint& aSourcePoint) MOZ_OVERRIDE; virtual void SetRenderTarget(CompositingRenderTarget* aSurface) MOZ_OVERRIDE; - virtual CompositingRenderTarget* GetCurrentRenderTarget() MOZ_OVERRIDE + virtual CompositingRenderTarget* GetCurrentRenderTarget() const MOZ_OVERRIDE { return mCurrentRT; } diff --git a/gfx/layers/d3d9/CompositorD3D9.h b/gfx/layers/d3d9/CompositorD3D9.h index c8b06bad052..f695cb11cfa 100644 --- a/gfx/layers/d3d9/CompositorD3D9.h +++ b/gfx/layers/d3d9/CompositorD3D9.h @@ -48,7 +48,7 @@ public: const gfx::IntPoint &aSourcePoint) MOZ_OVERRIDE; virtual void SetRenderTarget(CompositingRenderTarget *aSurface); - virtual CompositingRenderTarget* GetCurrentRenderTarget() MOZ_OVERRIDE + virtual CompositingRenderTarget* GetCurrentRenderTarget() const MOZ_OVERRIDE { return mCurrentRT; } diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index e37a2e749d2..2558ac10186 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -572,7 +572,7 @@ CompositorOGL::SetRenderTarget(CompositingRenderTarget *aSurface) } CompositingRenderTarget* -CompositorOGL::GetCurrentRenderTarget() +CompositorOGL::GetCurrentRenderTarget() const { return mCurrentRenderTarget; } diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 33d036cccb0..1f3863a3f42 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -190,7 +190,7 @@ public: const gfx::IntPoint &aSourcePoint) MOZ_OVERRIDE; virtual void SetRenderTarget(CompositingRenderTarget *aSurface) MOZ_OVERRIDE; - virtual CompositingRenderTarget* GetCurrentRenderTarget() MOZ_OVERRIDE; + virtual CompositingRenderTarget* GetCurrentRenderTarget() const MOZ_OVERRIDE; virtual void DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, From 4187310007201fa6bb72ec210739a6cca905b4ee Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 2 Apr 2014 03:23:04 -0400 Subject: [PATCH 28/63] Bug 984490 - Use the correct clip rect when determining whether to skip rendering a tile. r=nical --- gfx/layers/Compositor.cpp | 17 +++++++++++++++++ gfx/layers/Compositor.h | 14 +++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/gfx/layers/Compositor.cpp b/gfx/layers/Compositor.cpp index 331ed0bab63..41e22fb03e6 100644 --- a/gfx/layers/Compositor.cpp +++ b/gfx/layers/Compositor.cpp @@ -104,6 +104,23 @@ Compositor::DrawDiagnostics(DiagnosticFlags aFlags, aFlashCounter); } +gfx::Rect +Compositor::ClipRectInLayersCoordinates(gfx::Rect aClip) const { + gfx::Rect result; + switch (mScreenRotation) { + case ROTATION_90: + case ROTATION_270: + result = gfx::Rect(aClip.y, aClip.x, aClip.height, aClip.width); + break; + case ROTATION_0: + case ROTATION_180: + default: + result = aClip; + break; + } + return result + GetCurrentRenderTarget()->GetOrigin(); +} + void Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags, const gfx::Rect& aVisibleRect, diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index bb4cc5c7421..f255ea07651 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -504,17 +504,9 @@ public: // on the other hand, depends on the screen orientation. // This only applies to b2g as with other platforms, orientation is handled // at the OS level rather than in Gecko. - gfx::Rect ClipRectInLayersCoordinates(gfx::Rect aClip) const { - switch (mScreenRotation) { - case ROTATION_90: - case ROTATION_270: - return gfx::Rect(aClip.y, aClip.x, aClip.height, aClip.width); - case ROTATION_0: - case ROTATION_180: - default: - return aClip; - } - } + // In addition, the clip rect needs to be offset by the rendering origin. + // This becomes important if intermediate surfaces are used. + gfx::Rect ClipRectInLayersCoordinates(gfx::Rect aClip) const; protected: void DrawDiagnosticsInternal(DiagnosticFlags aFlags, const gfx::Rect& aVisibleRect, From 3e811f8ee0e25892ea500b6fb82caa8a7869916c Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 2 Apr 2014 15:28:03 +0100 Subject: [PATCH 29/63] Bug 959787 - Handlify remaining JS APIs r=sfink r=bholley r=smaug --- dom/base/nsDOMClassInfo.cpp | 5 +-- dom/base/nsGlobalWindow.cpp | 8 ++-- dom/base/nsJSEnvironment.cpp | 3 +- dom/plugins/base/nsJSNPRuntime.cpp | 5 ++- dom/workers/WorkerPrivate.cpp | 3 +- ipc/nfc/Nfc.cpp | 2 +- ipc/ril/Ril.cpp | 2 +- js/ipc/JavaScriptShared.cpp | 2 +- js/jsd/jsd_scpt.cpp | 5 ++- js/public/OldDebugAPI.h | 4 +- js/public/StructuredClone.h | 2 +- js/src/jsapi-tests/testDebugger.cpp | 3 +- js/src/jsapi.cpp | 32 ++++++++-------- js/src/jsapi.h | 21 ++++++----- js/src/jsfriendapi.cpp | 6 +-- js/src/jsfriendapi.h | 5 ++- js/src/shell/js.cpp | 2 +- js/src/vm/ArrayBufferObject.cpp | 4 +- js/src/vm/OldDebugAPI.cpp | 8 ++-- js/src/vm/StructuredClone.cpp | 5 +-- js/xpconnect/src/Sandbox.cpp | 9 ++--- js/xpconnect/src/XPCComponents.cpp | 45 +++++++++++------------ js/xpconnect/src/XPCMaps.h | 5 ++- js/xpconnect/src/XPCQuickStubs.h | 2 +- js/xpconnect/src/XPCWrappedNative.cpp | 5 +-- storage/src/mozStorageStatementParams.cpp | 6 +-- xpcom/io/nsBinaryStream.cpp | 2 +- 27 files changed, 101 insertions(+), 100 deletions(-) diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 3725a2e97b9..aa060208c49 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -3912,12 +3912,11 @@ nsStorage2SH::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) { nsString& key = keys->ElementAt(0); - JSString *str = - JS_NewUCStringCopyN(cx, key.get(), key.Length()); + JS::Rooted str(cx, JS_NewUCStringCopyN(cx, key.get(), key.Length())); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); JS::Rooted id(cx); - JS_ValueToId(cx, JS::StringValue(str), &id); + JS_StringToId(cx, str, &id); *idp = id; keys->RemoveElementAt(0); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index bb093e9b880..ecf6fe2fdd8 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -2487,18 +2487,18 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, { JSAutoCompartment ac(cx, mJSObject); - JS_SetParent(cx, mJSObject, newInnerWindow->mJSObject); - JS::Rooted obj(cx, mJSObject); + JS::Rooted newParent(cx, newInnerWindow->mJSObject); + JS_SetParent(cx, obj, newParent); // Inform the nsJSContext, which is the canonical holder of the outer. mContext->SetWindowProxy(obj); NS_ASSERTION(!JS_IsExceptionPending(cx), "We might overwrite a pending exception!"); - XPCWrappedNativeScope* scope = xpc::GetObjectScope(mJSObject); + XPCWrappedNativeScope* scope = xpc::GetObjectScope(obj); if (scope->mWaiverWrapperMap) { - scope->mWaiverWrapperMap->Reparent(cx, newInnerWindow->mJSObject); + scope->mWaiverWrapperMap->Reparent(cx, newParent); } } } diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 446f1bf6f79..1a3d4eca4be 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -2793,9 +2793,10 @@ NS_DOMWriteStructuredClone(JSContext* cx, // Write the internals to the stream. JSAutoCompartment ac(cx, dataArray); + JS::Rooted arrayValue(cx, JS::ObjectValue(*dataArray)); return JS_WriteUint32Pair(writer, SCTAG_DOM_IMAGEDATA, 0) && JS_WriteUint32Pair(writer, width, height) && - JS_WriteTypedArray(writer, JS::ObjectValue(*dataArray)); + JS_WriteTypedArray(writer, arrayValue); } void diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 48e76a92d03..9443e27506b 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -871,9 +871,10 @@ nsJSObjWrapper::NP_Enumerate(NPObject *npobj, NPIdentifier **idarray, nsCxPusher pusher; pusher.Push(cx); AutoJSExceptionReporter reporter(cx); - JSAutoCompartment ac(cx, npjsobj->mJSObj); + JS::Rooted jsobj(cx, npjsobj->mJSObj); + JSAutoCompartment ac(cx, jsobj); - JS::AutoIdArray ida(cx, JS_Enumerate(cx, npjsobj->mJSObj)); + JS::AutoIdArray ida(cx, JS_Enumerate(cx, jsobj)); if (!ida) { return false; } diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index dc00b2be91b..165b2142cc5 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -426,9 +426,10 @@ struct WorkerStructuredCloneCallbacks // Write the internals to the stream. JSAutoCompartment ac(aCx, dataArray); + JS::Rooted arrayValue(aCx, JS::ObjectValue(*dataArray)); return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) && JS_WriteUint32Pair(aWriter, width, height) && - JS_WriteTypedArray(aWriter, JS::ObjectValue(*dataArray)); + JS_WriteTypedArray(aWriter, arrayValue); } } diff --git a/ipc/nfc/Nfc.cpp b/ipc/nfc/Nfc.cpp index cc6189f6d45..285cd66edc0 100644 --- a/ipc/nfc/Nfc.cpp +++ b/ipc/nfc/Nfc.cpp @@ -91,7 +91,7 @@ PostToNFC(JSContext* aCx, void* data; size_t size; if (JSVAL_IS_STRING(v)) { - JSString* str = JSVAL_TO_STRING(v); + JS::Rooted str(aCx, v.toString()); if (!abs.encodeUtf8(aCx, str)) { return false; } diff --git a/ipc/ril/Ril.cpp b/ipc/ril/Ril.cpp index 84f9b16ad7a..6ccce829c5c 100644 --- a/ipc/ril/Ril.cpp +++ b/ipc/ril/Ril.cpp @@ -96,7 +96,7 @@ PostToRIL(JSContext *aCx, void *data; size_t size; if (JSVAL_IS_STRING(v)) { - JSString *str = JSVAL_TO_STRING(v); + JS::Rooted str(aCx, v.toString()); if (!abs.encodeUtf8(aCx, str)) { return false; } diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp index 9f68f046601..295e1902447 100644 --- a/js/ipc/JavaScriptShared.cpp +++ b/js/ipc/JavaScriptShared.cpp @@ -158,7 +158,7 @@ JavaScriptShared::convertGeckoStringToId(JSContext *cx, const nsString &from, JS if (!str) return false; - return JS_ValueToId(cx, StringValue(str), to); + return JS_StringToId(cx, str, to); } bool diff --git a/js/jsd/jsd_scpt.cpp b/js/jsd/jsd_scpt.cpp index 0223bd960bb..ff542f6cf94 100644 --- a/js/jsd/jsd_scpt.cpp +++ b/js/jsd/jsd_scpt.cpp @@ -542,9 +542,10 @@ jsd_EnableSingleStepInterrupts(JSDContext* jsdc, JSDScript* jsdscript, bool enab { bool rv; AutoSafeJSContext cx; - JSAutoCompartment ac(cx, jsdscript->script); + JS::RootedScript script(cx, jsdscript->script); + JSAutoCompartment ac(cx, script); JSD_LOCK(); - rv = JS_SetSingleStepMode(cx, jsdscript->script, enable); + rv = JS_SetSingleStepMode(cx, script, enable); JSD_UNLOCK(); return rv; } diff --git a/js/public/OldDebugAPI.h b/js/public/OldDebugAPI.h index ba4658b3c86..fe5e3368636 100644 --- a/js/public/OldDebugAPI.h +++ b/js/public/OldDebugAPI.h @@ -199,7 +199,7 @@ JS_SetDebugMode(JSContext *cx, bool debug); /* Turn on single step mode. */ extern JS_PUBLIC_API(bool) -JS_SetSingleStepMode(JSContext *cx, JSScript *script, bool singleStep); +JS_SetSingleStepMode(JSContext *cx, JS::HandleScript script, bool singleStep); /* The closure argument will be marked. */ extern JS_PUBLIC_API(bool) @@ -532,7 +532,7 @@ extern JS_PUBLIC_API(bool) JS_DefineDebuggerObject(JSContext *cx, JS::HandleObject obj); extern JS_PUBLIC_API(void) -JS_DumpPCCounts(JSContext *cx, JSScript *script); +JS_DumpPCCounts(JSContext *cx, JS::HandleScript script); extern JS_PUBLIC_API(void) JS_DumpCompartmentPCCounts(JSContext *cx); diff --git a/js/public/StructuredClone.h b/js/public/StructuredClone.h index 8e13a898383..f83fd4e83b5 100644 --- a/js/public/StructuredClone.h +++ b/js/public/StructuredClone.h @@ -158,6 +158,6 @@ JS_PUBLIC_API(bool) JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len); JS_PUBLIC_API(bool) -JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v); +JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::HandleValue v); #endif /* js_StructuredClone_h */ diff --git a/js/src/jsapi-tests/testDebugger.cpp b/js/src/jsapi-tests/testDebugger.cpp index c433fd11c99..bf910d23c65 100644 --- a/js/src/jsapi-tests/testDebugger.cpp +++ b/js/src/jsapi-tests/testDebugger.cpp @@ -258,7 +258,8 @@ BEGIN_TEST(testDebugger_singleStepThrow) CallArgs args = CallArgsFromVp(argc, vp); NonBuiltinScriptFrameIter iter(cx); - if (!JS_SetSingleStepMode(cx, iter.script(), true)) + JS::RootedScript script(cx, iter.script()); + if (!JS_SetSingleStepMode(cx, script, true)) return false; args.rval().set(UndefinedValue()); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index a468714e2b7..5d6ad8247c2 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -2175,15 +2175,24 @@ JS_DestroyIdArray(JSContext *cx, JSIdArray *ida) } JS_PUBLIC_API(bool) -JS_ValueToId(JSContext *cx, jsval valueArg, MutableHandleId idp) +JS_ValueToId(JSContext *cx, HandleValue value, MutableHandleId idp) { - RootedValue value(cx, valueArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, value); return ValueToId(cx, value, idp); } +JS_PUBLIC_API(bool) +JS_StringToId(JSContext *cx, HandleString string, MutableHandleId idp) +{ + AssertHeapIsIdle(cx); + CHECK_REQUEST(cx); + assertSameCompartment(cx, string); + RootedValue value(cx, StringValue(string)); + return ValueToId(cx, value, idp); +} + JS_PUBLIC_API(bool) JS_IdToValue(JSContext *cx, jsid id, MutableHandleValue vp) { @@ -2351,10 +2360,8 @@ JS_GetParent(JSObject *obj) } JS_PUBLIC_API(bool) -JS_SetParent(JSContext *cx, JSObject *objArg, JSObject *parentArg) +JS_SetParent(JSContext *cx, HandleObject obj, HandleObject parent) { - RootedObject obj(cx, objArg); - RootedObject parent(cx, parentArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); JS_ASSERT(!obj->is()); @@ -3310,11 +3317,9 @@ JS_GetElement(JSContext *cx, HandleObject objArg, uint32_t index, MutableHandleV } JS_PUBLIC_API(bool) -JS_ForwardGetElementTo(JSContext *cx, JSObject *objArg, uint32_t index, JSObject *onBehalfOfArg, +JS_ForwardGetElementTo(JSContext *cx, HandleObject obj, uint32_t index, HandleObject onBehalfOf, MutableHandleValue vp) { - RootedObject obj(cx, objArg); - RootedObject onBehalfOf(cx, onBehalfOfArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj); @@ -3512,9 +3517,8 @@ LastConfigurableShape(JSObject *obj) } JS_PUBLIC_API(void) -JS_ClearNonGlobalObject(JSContext *cx, JSObject *objArg) +JS_ClearNonGlobalObject(JSContext *cx, HandleObject obj) { - RootedObject obj(cx, objArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj); @@ -3563,9 +3567,8 @@ JS_SetAllNonReservedSlotsToUndefined(JSContext *cx, JSObject *objArg) } JS_PUBLIC_API(JSIdArray *) -JS_Enumerate(JSContext *cx, JSObject *objArg) +JS_Enumerate(JSContext *cx, HandleObject obj) { - RootedObject obj(cx, objArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj); @@ -4978,9 +4981,8 @@ JS::Call(JSContext *cx, HandleValue thisv, HandleValue fval, const JS::HandleVal } JS_PUBLIC_API(JSObject *) -JS_New(JSContext *cx, JSObject *ctorArg, const JS::HandleValueArray& inputArgs) +JS_New(JSContext *cx, HandleObject ctor, const JS::HandleValueArray& inputArgs) { - RootedObject ctor(cx, ctorArg); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, ctor, inputArgs); @@ -5387,7 +5389,7 @@ JS_EncodeString(JSContext *cx, JSString *str) } JS_PUBLIC_API(char *) -JS_EncodeStringToUTF8(JSContext *cx, JSString *str) +JS_EncodeStringToUTF8(JSContext *cx, HandleString str) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); diff --git a/js/src/jsapi.h b/js/src/jsapi.h index e2d37c15191..dcc0fbcb81b 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2273,7 +2273,10 @@ class AutoIdArray : private AutoGCRooter } /* namespace JS */ extern JS_PUBLIC_API(bool) -JS_ValueToId(JSContext *cx, jsval v, JS::MutableHandle idp); +JS_ValueToId(JSContext *cx, JS::HandleValue v, JS::MutableHandleId idp); + +extern JS_PUBLIC_API(bool) +JS_StringToId(JSContext *cx, JS::HandleString s, JS::MutableHandleId idp); extern JS_PUBLIC_API(bool) JS_IdToValue(JSContext *cx, jsid id, JS::MutableHandle vp); @@ -2520,7 +2523,7 @@ extern JS_PUBLIC_API(JSObject *) JS_GetParent(JSObject *obj); extern JS_PUBLIC_API(bool) -JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent); +JS_SetParent(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent); extern JS_PUBLIC_API(JSObject *) JS_GetConstructor(JSContext *cx, JS::Handle proto); @@ -2722,7 +2725,7 @@ extern JS_PUBLIC_API(bool) JS_PreventExtensions(JSContext *cx, JS::HandleObject obj); extern JS_PUBLIC_API(JSObject *) -JS_New(JSContext *cx, JSObject *ctor, const JS::HandleValueArray& args); +JS_New(JSContext *cx, JS::HandleObject ctor, const JS::HandleValueArray& args); extern JS_PUBLIC_API(JSObject *) JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, const JSClass *clasp, @@ -3037,8 +3040,8 @@ extern JS_PUBLIC_API(bool) JS_GetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp); extern JS_PUBLIC_API(bool) -JS_ForwardGetElementTo(JSContext *cx, JSObject *obj, uint32_t index, JSObject *onBehalfOf, - JS::MutableHandleValue vp); +JS_ForwardGetElementTo(JSContext *cx, JS::HandleObject obj, uint32_t index, + JS::HandleObject onBehalfOf, JS::MutableHandleValue vp); extern JS_PUBLIC_API(bool) JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v); @@ -3069,7 +3072,7 @@ JS_DeleteElement2(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *suc * assign undefined to all writable data properties. */ JS_PUBLIC_API(void) -JS_ClearNonGlobalObject(JSContext *cx, JSObject *objArg); +JS_ClearNonGlobalObject(JSContext *cx, JS::HandleObject obj); /* * Assign 'undefined' to all of the object's non-reserved slots. Note: this is @@ -3113,7 +3116,7 @@ extern JS_PUBLIC_API(void *) JS_ReallocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void *oldContents, uint32_t oldNbytes); extern JS_PUBLIC_API(JSIdArray *) -JS_Enumerate(JSContext *cx, JSObject *obj); +JS_Enumerate(JSContext *cx, JS::HandleObject obj); /* * Create an object to iterate over enumerable properties of obj, in arbitrary @@ -4055,7 +4058,7 @@ JS_EncodeString(JSContext *cx, JSString *str); * Same behavior as JS_EncodeString(), but encode into UTF-8 string */ JS_PUBLIC_API(char *) -JS_EncodeStringToUTF8(JSContext *cx, JSString *str); +JS_EncodeStringToUTF8(JSContext *cx, JS::HandleString str); /* * Get number of bytes in the string encoding (without accounting for a @@ -4112,7 +4115,7 @@ class JSAutoByteString char *encodeLatin1(js::ExclusiveContext *cx, JSString *str); - char *encodeUtf8(JSContext *cx, JSString *str) { + char *encodeUtf8(JSContext *cx, JS::HandleString str) { JS_ASSERT(!mBytes); JS_ASSERT(cx); mBytes = JS_EncodeStringToUTF8(cx, str); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 4618377899e..66c1d732161 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -683,11 +683,9 @@ JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallba } JS_FRIEND_API(JSObject *) -JS_CloneObject(JSContext *cx, JSObject *obj_, JSObject *proto_, JSObject *parent_) +JS_CloneObject(JSContext *cx, HandleObject obj, HandleObject protoArg, HandleObject parent) { - RootedObject obj(cx, obj_); - Rooted proto(cx, proto_); - RootedObject parent(cx, parent_); + Rooted proto(cx, protoArg.get()); return CloneObject(cx, obj, proto, parent); } diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index e5bf5e98ee6..07f5ceb6e6d 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -133,7 +133,8 @@ extern JS_FRIEND_API(JSObject *) JS_ObjectToOuterObject(JSContext *cx, JS::HandleObject obj); extern JS_FRIEND_API(JSObject *) -JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent); +JS_CloneObject(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto, + JS::HandleObject parent); extern JS_FRIEND_API(JSString *) JS_BasicObjectToString(JSContext *cx, JS::HandleObject obj); @@ -1416,7 +1417,7 @@ JS_GetFloat64ArrayData(JSObject *obj); * as the object is live. */ extern JS_FRIEND_API(uint8_t *) -JS_GetStableArrayBufferData(JSContext *cx, JSObject *obj); +JS_GetStableArrayBufferData(JSContext *cx, JS::HandleObject obj); /* * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index cca773ed4d8..83c87589e5f 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -872,7 +872,7 @@ ParseCompileOptions(JSContext *cx, CompileOptions &options, HandleObject opts, if (!JS_GetProperty(cx, opts, "sourcePolicy", &v)) return false; if (!v.isUndefined()) { - JSString *s = ToString(cx, v); + RootedString s(cx, ToString(cx, v)); if (!s) return false; diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index ef87c77d12d..209bd54dddf 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -955,9 +955,9 @@ JS_GetArrayBufferData(JSObject *obj) } JS_FRIEND_API(uint8_t *) -JS_GetStableArrayBufferData(JSContext *cx, JSObject *obj) +JS_GetStableArrayBufferData(JSContext *cx, HandleObject objArg) { - obj = CheckedUnwrap(obj); + JSObject *obj = CheckedUnwrap(objArg); if (!obj) return nullptr; diff --git a/js/src/vm/OldDebugAPI.cpp b/js/src/vm/OldDebugAPI.cpp index cd26624d116..47e97046295 100644 --- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -211,9 +211,8 @@ CheckDebugMode(JSContext *cx) } JS_PUBLIC_API(bool) -JS_SetSingleStepMode(JSContext *cx, JSScript *scriptArg, bool singleStep) +JS_SetSingleStepMode(JSContext *cx, HandleScript script, bool singleStep) { - RootedScript script(cx, scriptArg); assertSameCompartment(cx, script); if (!CheckDebugMode(cx)) @@ -819,9 +818,8 @@ JS_GetGlobalDebugHooks(JSRuntime *rt) /************************************************************************/ extern JS_PUBLIC_API(void) -JS_DumpPCCounts(JSContext *cx, JSScript *scriptArg) +JS_DumpPCCounts(JSContext *cx, HandleScript script) { - Rooted script(cx, scriptArg); JS_ASSERT(script->hasScriptCounts()); Sprinter sprinter(cx); @@ -838,7 +836,7 @@ JS_PUBLIC_API(void) JS_DumpCompartmentPCCounts(JSContext *cx) { for (CellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) { - JSScript *script = i.get(); + RootedScript script(cx, i.get()); if (script->compartment() != cx->compartment()) continue; diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index c38a0ceafd9..040a5b756af 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -300,7 +300,7 @@ struct JSStructuredCloneWriter { JS::RootedValue transferable; JS::AutoObjectVector transferableObjects; - friend bool JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v); + friend bool JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::HandleValue v); }; JS_FRIEND_API(uint64_t) @@ -1840,7 +1840,7 @@ JS_WriteBytes(JSStructuredCloneWriter *w, const void *p, size_t len) } JS_PUBLIC_API(bool) -JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v) +JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::HandleValue v) { JS_ASSERT(v.isObject()); assertSameCompartment(w->context(), v); @@ -1856,4 +1856,3 @@ JS_WriteTypedArray(JSStructuredCloneWriter *w, JS::Value v) } return w->writeTypedArray(obj); } - diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index f595e5bbed2..2536a37c54d 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -177,7 +177,7 @@ SandboxImport(JSContext *cx, unsigned argc, Value *vp) } RootedId id(cx); - if (!JS_ValueToId(cx, StringValue(funname), &id)) + if (!JS_StringToId(cx, funname, &id)) return false; // We need to resolve the this object, because this function is used @@ -299,9 +299,7 @@ ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleV if (!funName) funName = JS_InternString(cx, ""); - RootedValue vname(cx); - vname.setString(funName); - if (!JS_ValueToId(cx, vname, &id)) + if (!JS_StringToId(cx, funName, &id)) return false; } MOZ_ASSERT(JSID_IS_STRING(id)); @@ -1841,7 +1839,8 @@ xpc::NewFunctionForwarder(JSContext *cx, HandleObject callable, bool doclone, MutableHandleValue vp) { RootedId emptyId(cx); - if (!JS_ValueToId(cx, JS_GetEmptyStringValue(cx), &emptyId)) + RootedValue emptyStringValue(cx, JS_GetEmptyStringValue(cx)); + if (!JS_ValueToId(cx, emptyStringValue, &emptyId)) return false; return NewFunctionForwarder(cx, emptyId, callable, doclone, vp); diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index 375c6103b8d..c58803df4df 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -265,15 +265,15 @@ nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative *wrapper, *statep = UINT_TO_JSVAL(idx + 1); if (interface) { - JSString* idstr; const char* name; - JS::Rooted id(cx); - if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name && - nullptr != (idstr = JS_NewStringCopyZ(cx, name)) && - JS_ValueToId(cx, StringValue(idstr), &id)) { - *idp = id; - return NS_OK; + RootedId id(cx); + if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) { + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); + if (idstr && JS_StringToId(cx, idstr, &id)) { + *idp = id; + return NS_OK; + } } } // fall through @@ -514,13 +514,12 @@ nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper, if (interface) { nsIID const *iid; char idstr[NSID_LENGTH]; - JSString* jsstr; if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) { iid->ToProvidedString(idstr); - jsstr = JS_NewStringCopyZ(cx, idstr); - JS::Rooted id(cx); - if (jsstr && JS_ValueToId(cx, StringValue(jsstr), &id)) { + RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr)); + RootedId id(cx); + if (jsstr && JS_StringToId(cx, jsstr, &id)) { *idp = id; return NS_OK; } @@ -774,10 +773,9 @@ nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative *wrapper, if (holder) { nsAutoCString name; if (NS_SUCCEEDED(holder->GetData(name))) { - JSString* idstr = JS_NewStringCopyN(cx, name.get(), name.Length()); - JS::Rooted id(cx); - if (idstr && - JS_ValueToId(cx, StringValue(idstr), &id)) { + RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length())); + RootedId id(cx); + if (idstr && JS_StringToId(cx, idstr, &id)) { *idp = id; return NS_OK; } @@ -1015,11 +1013,10 @@ nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper, if (holder) { char* name; if (NS_SUCCEEDED(holder->ToString(&name)) && name) { - JSString* idstr = JS_NewStringCopyZ(cx, name); + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); nsMemory::Free(name); - JS::Rooted id(cx); - if (idstr && - JS_ValueToId(cx, StringValue(idstr), &id)) { + RootedId id(cx); + if (idstr && JS_StringToId(cx, idstr, &id)) { *idp = id; return NS_OK; } @@ -1270,9 +1267,9 @@ nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative *wrapper, const char* name; iter = (const void**) JSVAL_TO_PRIVATE(*statep); if (nsXPCException::IterateNSResults(nullptr, &name, nullptr, iter)) { - JSString* idstr = JS_NewStringCopyZ(cx, name); - JS::Rooted id(cx); - if (idstr && JS_ValueToId(cx, StringValue(idstr), &id)) { + RootedString idstr(cx, JS_NewStringCopyZ(cx, name)); + JS::RootedId id(cx); + if (idstr && JS_StringToId(cx, idstr, &id)) { *idp = id; return NS_OK; } @@ -2417,7 +2414,7 @@ nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper, RootedString str(cx, ToString(cx, args[1])); RootedId id(cx); - if (!str || !JS_ValueToId(cx, StringValue(str), &id)) + if (!str || !JS_StringToId(cx, str, &id)) return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); RootedValue val(cx); @@ -2465,7 +2462,7 @@ nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper, RootedString str(cx, ToString(cx, args[0])); RootedId id(cx); - if (!str || !JS_ValueToId(cx, StringValue(str), &id)) + if (!str || !JS_StringToId(cx, str, &id)) return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval); RootedValue val(cx); diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 583911e5f53..6a4ce127c68 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -672,12 +672,13 @@ public: * We reparent wrappers that have as their parent an inner window * whose outer has the new inner window as its current inner. */ - JS::RootedObject parent(aCx, JS_GetParent(e.front().value())); + JS::RootedObject wrapper(aCx, e.front().value()); + JS::RootedObject parent(aCx, JS_GetParent(wrapper)); JS::RootedObject outer(aCx, JS_ObjectToOuterObject(aCx, parent)); if (outer) { JSObject *inner = JS_ObjectToInnerObject(aCx, outer); if (inner == aNewInner && inner != parent) - JS_SetParent(aCx, e.front().value(), aNewInner); + JS_SetParent(aCx, wrapper, aNewInner); } else { JS_ClearPendingException(aCx); } diff --git a/js/xpconnect/src/XPCQuickStubs.h b/js/xpconnect/src/XPCQuickStubs.h index 5f5e20eae20..c88511fa222 100644 --- a/js/xpconnect/src/XPCQuickStubs.h +++ b/js/xpconnect/src/XPCQuickStubs.h @@ -601,7 +601,7 @@ PropertyOpForwarder(JSContext *cx, unsigned argc, jsval *vp) if (!obj) return false; - jsval v = js::GetFunctionNativeReserved(callee, 0); + JS::RootedValue v(cx, js::GetFunctionNativeReserved(callee, 0)); JSObject *ptrobj = JSVAL_TO_OBJECT(v); Op *popp = static_cast(JS_GetPrivate(ptrobj)); diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index 7501832b226..420f721b093 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -1160,9 +1160,8 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCWrappedNativeScope* aOldScope, // ending up with two reflectors pointing to the same WN. Other than // that, the objects we create will just go away if we return early. - RootedObject newobj(cx, JS_CloneObject(cx, flat, - newProto->GetJSProtoObject(), - aNewParent)); + RootedObject proto(cx, newProto->GetJSProtoObject()); + RootedObject newobj(cx, JS_CloneObject(cx, flat, proto, aNewParent)); if (!newobj) return NS_ERROR_FAILURE; diff --git a/storage/src/mozStorageStatementParams.cpp b/storage/src/mozStorageStatementParams.cpp index 9f9cc20d371..c187032e563 100644 --- a/storage/src/mozStorageStatementParams.cpp +++ b/storage/src/mozStorageStatementParams.cpp @@ -123,13 +123,13 @@ StatementParams::NewEnumerate(nsIXPConnectWrappedNative *aWrapper, NS_ENSURE_SUCCESS(rv, rv); // But drop the first character, which is going to be a ':'. - JSString *jsname = ::JS_NewStringCopyN(aCtx, &(name.get()[1]), - name.Length() - 1); + JS::RootedString jsname(aCtx, ::JS_NewStringCopyN(aCtx, &(name.get()[1]), + name.Length() - 1)); NS_ENSURE_TRUE(jsname, NS_ERROR_OUT_OF_MEMORY); // Set our name. JS::Rooted id(aCtx); - if (!::JS_ValueToId(aCtx, JS::StringValue(jsname), &id)) { + if (!::JS_StringToId(aCtx, jsname, &id)) { *_retval = false; return NS_OK; } diff --git a/xpcom/io/nsBinaryStream.cpp b/xpcom/io/nsBinaryStream.cpp index ea68aa9ba09..7ae96a9464b 100644 --- a/xpcom/io/nsBinaryStream.cpp +++ b/xpcom/io/nsBinaryStream.cpp @@ -752,7 +752,7 @@ nsBinaryInputStream::ReadArrayBuffer(uint32_t aLength, JS::Handle aBu JS_GetArrayBufferByteLength(buffer) < aLength) { return NS_ERROR_FAILURE; } - uint8_t* data = JS_GetStableArrayBufferData(cx, &aBuffer.toObject()); + uint8_t* data = JS_GetStableArrayBufferData(cx, buffer); if (!data) { return NS_ERROR_FAILURE; } From 527b2025db7e581045a5c452a14c2fafd5a9edcd Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 2 Apr 2014 15:28:03 +0100 Subject: [PATCH 30/63] Bug 990071 r=terrence --- js/src/vm/ArgumentsObject.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/js/src/vm/ArgumentsObject.cpp b/js/src/vm/ArgumentsObject.cpp index 531747215e9..a7a8ddfb615 100644 --- a/js/src/vm/ArgumentsObject.cpp +++ b/js/src/vm/ArgumentsObject.cpp @@ -198,6 +198,13 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle if (!data) return nullptr; + JSObject *obj = JSObject::create(cx, FINALIZE_KIND, GetInitialHeap(GenericObject, clasp), + shape, type); + if (!obj) { + js_free(data); + return nullptr; + } + data->numArgs = numArgs; data->callee.init(ObjectValue(*callee.get())); data->script = script; @@ -209,13 +216,6 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle data->deletedBits = reinterpret_cast(dstEnd); ClearAllBitArrayElements(data->deletedBits, numDeletedWords); - JSObject *obj = JSObject::create(cx, FINALIZE_KIND, GetInitialHeap(GenericObject, clasp), - shape, type); - if (!obj) { - js_free(data); - return nullptr; - } - obj->initFixedSlot(INITIAL_LENGTH_SLOT, Int32Value(numActuals << PACKED_BITS_COUNT)); obj->initFixedSlot(DATA_SLOT, PrivateValue(data)); From de160c2fee0db7a76eec539710be5e9012fe2bcf Mon Sep 17 00:00:00 2001 From: Mike Shal Date: Tue, 1 Apr 2014 11:22:03 -0400 Subject: [PATCH 31/63] Bug 990739: Add releng.manifest for b2g win32; r=rail --- b2g/config/tooltool-manifests/win32/releng.manifest | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 b2g/config/tooltool-manifests/win32/releng.manifest diff --git a/b2g/config/tooltool-manifests/win32/releng.manifest b/b2g/config/tooltool-manifests/win32/releng.manifest new file mode 100644 index 00000000000..2e802b78d1f --- /dev/null +++ b/b2g/config/tooltool-manifests/win32/releng.manifest @@ -0,0 +1,8 @@ +[ +{ +"size": 266240, +"digest": "bb345b0e700ffab4d09436981f14b5de84da55a3f18a7f09ebc4364a4488acdeab8d46f447b12ac70f2da1444a68b8ce8b8675f0dae2ccf845e966d1df0f0869", +"algorithm": "sha512", +"filename": "mozmake.exe" +} +] From 854aed8da82aa23a4195fe94412b6ebc18b09fe4 Mon Sep 17 00:00:00 2001 From: Mike Kaply Date: Wed, 2 Apr 2014 10:03:08 -0500 Subject: [PATCH 32/63] Backing out bug 889085 (dddfd63f1414, f8c14bd80676) due to regression bug 987783. r=roc --- layout/base/nsCSSRendering.cpp | 6 ------ widget/cocoa/nsNativeThemeCocoa.h | 1 - widget/cocoa/nsNativeThemeCocoa.mm | 24 +----------------------- 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index f7211d3827c..d91309be173 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -1695,12 +1695,6 @@ nsCSSRendering::DetermineBackgroundColor(nsPresContext* aPresContext, bool& aDrawBackgroundImage, bool& aDrawBackgroundColor) { - if (aFrame->IsThemed()) { - aDrawBackgroundColor = false; - aDrawBackgroundImage = false; - return NS_RGBA(0,0,0,0); - } - aDrawBackgroundImage = true; aDrawBackgroundColor = true; diff --git a/widget/cocoa/nsNativeThemeCocoa.h b/widget/cocoa/nsNativeThemeCocoa.h index 580c23181a3..9c56ed000b5 100644 --- a/widget/cocoa/nsNativeThemeCocoa.h +++ b/widget/cocoa/nsNativeThemeCocoa.h @@ -71,7 +71,6 @@ protected: nsIFrame* SeparatorResponsibility(nsIFrame* aBefore, nsIFrame* aAfter); CGRect SeparatorAdjustedRect(CGRect aRect, nsIFrame* aLeft, nsIFrame* aCurrent, nsIFrame* aRight); - bool IsWindowSheet(nsIFrame* aFrame); // HITheme drawing routines void DrawFrame(CGContextRef context, HIThemeFrameKind inKind, diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index fdfde3fa56b..86b85c6a6f8 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2152,14 +2152,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, switch (aWidgetType) { case NS_THEME_DIALOG: { - CGContextClearRect(cgContext, macRect); - if (IsWindowSheet(aFrame)) { - HIThemeSetFill(kThemeBrushSheetBackgroundTransparent, NULL, cgContext, HITHEME_ORIENTATION); - } - else { - HIThemeSetFill(kThemeBrushDialogBackgroundActive, NULL, cgContext, HITHEME_ORIENTATION); - } - + HIThemeSetFill(kThemeBrushDialogBackgroundActive, NULL, cgContext, HITHEME_ORIENTATION); CGContextFillRect(cgContext, macRect); } break; @@ -3429,18 +3422,6 @@ nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) } } -bool -nsNativeThemeCocoa::IsWindowSheet(nsIFrame* aFrame) -{ - NSWindow* win = NativeWindowForFrame(aFrame); - id winDelegate = [win delegate]; - nsIWidget* widget = [(WindowDelegate *)winDelegate geckoWidget]; - if (!widget) { - return false; - } - return (widget->WindowType() == eWindowType_sheet); -} - nsITheme::Transparency nsNativeThemeCocoa::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) { @@ -3449,9 +3430,6 @@ nsNativeThemeCocoa::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) case NS_THEME_TOOLTIP: return eTransparent; - case NS_THEME_DIALOG: - return IsWindowSheet(aFrame) ? eTransparent : eOpaque; - case NS_THEME_SCROLLBAR_SMALL: case NS_THEME_SCROLLBAR: return nsLookAndFeel::UseOverlayScrollbars() ? eTransparent : eOpaque; From 0905fe759085d1e11e0f27104c094290277b16d5 Mon Sep 17 00:00:00 2001 From: Camilo Viecco Date: Fri, 28 Mar 2014 10:21:30 -0700 Subject: [PATCH 33/63] Bug 987816 - Part 1/3. Allow verifying with certificateUsageVerifyCA. r=dkeeler --HG-- extra : rebase_source : 7530839c9c02d56936e322f897de96d80a60a18f --- security/certverifier/CertVerifier.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp index 06a0d845af6..53de1779f1f 100644 --- a/security/certverifier/CertVerifier.cpp +++ b/security/certverifier/CertVerifier.cpp @@ -145,6 +145,9 @@ ClassicVerifyCert(CERTCertificate* cert, case certificateUsageObjectSigner: enumUsage = certUsageObjectSigner; break; + case certificateUsageVerifyCA: + enumUsage = certUsageVerifyCA; + break; case certificateUsageStatusResponder: enumUsage = certUsageStatusResponder; break; @@ -475,6 +478,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, case certificateUsageEmailSigner: case certificateUsageEmailRecipient: case certificateUsageObjectSigner: + case certificateUsageVerifyCA: case certificateUsageStatusResponder: break; default: From 2011f0e31acddde11a67ca1ccc654bd916992495 Mon Sep 17 00:00:00 2001 From: Camilo Viecco Date: Mon, 31 Mar 2014 09:10:11 -0700 Subject: [PATCH 34/63] Bug 987816 - Part 2/3. Test verifying certificateUsageVerifyCA can return OK. r= dkeeler --HG-- extra : rebase_source : 8e3f50d58c3c61e0fc843a053370f74d9adac8c0 --- security/manager/ssl/tests/unit/head_psm.js | 13 +++++++++++++ .../ssl/tests/unit/test_certificate_usages.js | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/security/manager/ssl/tests/unit/head_psm.js b/security/manager/ssl/tests/unit/head_psm.js index f09c948ffee..4caf5a5d2ce 100644 --- a/security/manager/ssl/tests/unit/head_psm.js +++ b/security/manager/ssl/tests/unit/head_psm.js @@ -101,6 +101,19 @@ function getXPCOMStatusFromNSS(statusNSS) { return nssErrorsService.getXPCOMFromNSSError(statusNSS); } +function checkCertErrorGeneric(certdb, cert, expectedError, usage) { + let hasEVPolicy = {}; + let verifiedChain = {}; + let error = certdb.verifyCertNow(cert, usage, NO_FLAGS, verifiedChain, + hasEVPolicy); + // expected error == -1 is a special marker for any error is OK + if (expectedError != -1 ) { + do_check_eq(error, expectedError); + } else { + do_check_neq (error, 0); + } +} + function _getLibraryFunctionWithNoArguments(functionName, libraryName) { // Open the NSS library. copied from services/crypto/modules/WeaveCrypto.js let path = ctypes.libraryName(libraryName); diff --git a/security/manager/ssl/tests/unit/test_certificate_usages.js b/security/manager/ssl/tests/unit/test_certificate_usages.js index aee7d81898e..3d7cf409991 100644 --- a/security/manager/ssl/tests/unit/test_certificate_usages.js +++ b/security/manager/ssl/tests/unit/test_certificate_usages.js @@ -124,7 +124,9 @@ function run_test_in_mode(useMozillaPKIX) { cert.getUsagesString(true, verified, usages); do_print("usages.value=" + usages.value); do_check_eq(ca_usages[i], usages.value); - + if (ca_usages[i].indexOf('SSL CA') != -1) { + checkCertErrorGeneric(certdb, cert, 0, certificateUsageVerifyCA); + } //now the ee, names also one based for (var j = 0; j < ee_usages[i].length; j++) { var ee_name = "ee-" + (j + 1) + "-" + ca_name; From 02c29dd5806906e09e80060745d42b55ee132c07 Mon Sep 17 00:00:00 2001 From: Camilo Viecco Date: Mon, 31 Mar 2014 09:10:13 -0700 Subject: [PATCH 35/63] Bug 987816 - Part 2/3. Update tests to match un-regressed behaviour. r=dkeeler --HG-- extra : rebase_source : 7bccc66831f56cede353ec33275449b7bf2560b1 --- .../manager/ssl/tests/unit/test_cert_trust.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/security/manager/ssl/tests/unit/test_cert_trust.js b/security/manager/ssl/tests/unit/test_cert_trust.js index c688abe28f0..7d829cf135a 100644 --- a/security/manager/ssl/tests/unit/test_cert_trust.js +++ b/security/manager/ssl/tests/unit/test_cert_trust.js @@ -52,8 +52,10 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); // expected check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, - certificateUsageVerifyCA); // expected no bc + : 0, + certificateUsageVerifyCA); + // mozilla::pkix enforces that certificase must have a basic constraints + // extension with cA:true to be a CA certificate, whereas classic does not check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); //expected @@ -75,7 +77,7 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + : 0, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -111,7 +113,7 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + : 0, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -133,7 +135,7 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + : 0, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -157,7 +159,7 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + : 0, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -180,7 +182,7 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + : 0, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -208,7 +210,7 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + : 0, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); From 7ee45c73875ae35ee0e18b317580c2c4b698c503 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Wed, 2 Apr 2014 11:39:38 -0400 Subject: [PATCH 36/63] Backed out changeset 1d4ec2065398 (bug 990202) for b2g-desktop failures on a CLOSED TREE --- docshell/test/file_framedhistoryframes.html | 16 ---------------- docshell/test/mochitest.ini | 1 - docshell/test/test_framedhistoryframes.html | 3 +-- 3 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 docshell/test/file_framedhistoryframes.html diff --git a/docshell/test/file_framedhistoryframes.html b/docshell/test/file_framedhistoryframes.html deleted file mode 100644 index 314f9c72d89..00000000000 --- a/docshell/test/file_framedhistoryframes.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/docshell/test/mochitest.ini b/docshell/test/mochitest.ini index 41e16b9ae59..b20b8b3a682 100644 --- a/docshell/test/mochitest.ini +++ b/docshell/test/mochitest.ini @@ -97,7 +97,6 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec [test_bug797909.html] [test_framedhistoryframes.html] skip-if = toolkit == 'android' #bug 784321 -support-files = file_framedhistoryframes.html [test_pushState_after_document_open.html] [test_windowedhistoryframes.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage diff --git a/docshell/test/test_framedhistoryframes.html b/docshell/test/test_framedhistoryframes.html index 916a6229d39..b6981780845 100644 --- a/docshell/test/test_framedhistoryframes.html +++ b/docshell/test/test_framedhistoryframes.html @@ -12,6 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=602256 Mozilla Bug 602256

+