Merge inbound to m-c.

This commit is contained in:
Ryan VanderMeulen 2014-04-17 22:31:17 -04:00
commit 9e685c22d5
162 changed files with 2879 additions and 1140 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 916012 moves definition from one WEBIDL_FILE to another (Bug 979886)
Bug 995411 moves some files around in gfx/layers and widget/xpwidget

View File

@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
no_tooltool=1
no_sccache=1
# This file is included at the top of all b2g mozconfigs

View File

@ -21,7 +21,8 @@ export MOZ_TELEMETRY_REPORTING=1
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
# DISABLED WHILE NOT ON TRY ac_add_options --enable-warnings-as-errors
# Use ccache
# Use sccache
no_sccache=
. "$topsrcdir/build/mozconfig.cache"
#B2G options

View File

@ -22,7 +22,8 @@ export MOZ_TELEMETRY_REPORTING=1
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
# DISABLED WHILE NOT ON TRY ac_add_options --enable-warnings-as-errors
# Use ccache
# Use sccache
no_sccache=
. "$topsrcdir/build/mozconfig.cache"
#B2G options

View File

@ -21,7 +21,8 @@ export MOZ_TELEMETRY_REPORTING=1
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
# DISABLED WHILE NOT ON TRY ac_add_options --enable-warnings-as-errors
# Use ccache
# Use sccache
no_sccache=
. "$topsrcdir/build/mozconfig.cache"
#B2G options

View File

@ -1,14 +0,0 @@
[
{
"size": 195,
"digest": "236362c71c433971c36b46d34e8560342435718364bc390df8de6a33249fb1fbf4fc3d0143f1e22bca262a7af7dc1b277a920bfde3ee8197eb07db2e7cef3e1f",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
"size": 63159127,
"digest": "fcf629c815b5cbed7858d7697815f355275dcc6b060ae5455b4b31fde0d78ebc176927564a5353ceacdb9f9c9bfc1357f1341bf6ba844c25153a89664e661510",
"algorithm": "sha512",
"filename": "gonk-toolchain-7.tar.bz2"
}
]

View File

@ -0,0 +1,14 @@
[
{
"size": 50,
"digest": "48f405d8c2712838b9dd3be118951c8b41c63c891576f5287d2e05afa8fd051a08807511259581aa3170a3c4f7d4e77e6c0539b00b8f6845f01562127f6a27fa",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
"size": 160232,
"digest": "8656c3fc2daa66839ec81a0edbd9759040a83c7a41c3e472d7f90508b80eefd008b87305dc8549b4ff6098dc33fe17fedc9b4eb76cf5307d5f22dae925c033db",
"algorithm": "sha512",
"filename": "sccache.tar.xz"
}
]

View File

@ -0,0 +1,14 @@
[
{
"size": 50,
"digest": "48f405d8c2712838b9dd3be118951c8b41c63c891576f5287d2e05afa8fd051a08807511259581aa3170a3c4f7d4e77e6c0539b00b8f6845f01562127f6a27fa",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
"size": 160232,
"digest": "8656c3fc2daa66839ec81a0edbd9759040a83c7a41c3e472d7f90508b80eefd008b87305dc8549b4ff6098dc33fe17fedc9b4eb76cf5307d5f22dae925c033db",
"algorithm": "sha512",
"filename": "sccache.tar.xz"
}
]

View File

@ -1,14 +0,0 @@
[
{
"size": 195,
"digest": "da2edcb1ec9b169f6c685d02ebd0bd4ad53ace2df58598f15e1bde43dd74bcb816620601587c97e636bda3327045b43c8f5e973672ebd904e06036f70466908f",
"algorithm": "sha512",
"filename": "setup.sh"
},
{
"size": 121166734,
"digest": "10da1d28d49ff1aa9ad3d84e52235dc8ed7df6721530b896a53424480ec23a2e9f28cadd631f562342325611ecb72152be51f9b62616356f33005f6cc0fb82fe",
"algorithm": "sha512",
"filename": "gonk-toolchain-3.tar.bz2"
}
]

View File

@ -51,6 +51,11 @@ function checkPage() {
// Now press the "Try Again" button
ok(gBrowser.contentDocument.getElementById("errorTryAgain"),
"The error page has got a #errorTryAgain element");
// Re-enable the proxy so example.com is resolved to localhost, rather than
// the actual example.com.
Services.prefs.setIntPref("network.proxy.type", proxyPrefValue);
gBrowser.contentDocument.getElementById("errorTryAgain").click();
ok(!Services.io.offline, "After clicking the Try Again button, we're back " +
@ -60,7 +65,6 @@ function checkPage() {
}
registerCleanupFunction(function() {
Services.prefs.setIntPref("network.proxy.type", proxyPrefValue);
Services.prefs.setBoolPref("browser.cache.disk.enable", true);
Services.prefs.setBoolPref("browser.cache.memory.enable", true);
Services.io.offline = false;

View File

@ -1,4 +1,5 @@
no_tooltool=1
no_sccache=1
ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}

View File

@ -1,4 +1,5 @@
no_tooltool=1
no_sccache=1
. $topsrcdir/browser/config/mozconfigs/linux32/nightly

View File

@ -1,4 +1,5 @@
no_tooltool=1
no_sccache=1
ac_add_options --with-l10n-base=../../l10n
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}

View File

@ -1,4 +1,5 @@
no_tooltool=1
no_sccache=1
. $topsrcdir/browser/config/mozconfigs/linux64/nightly

View File

@ -9,7 +9,7 @@ $(python2.7 -c 'import json; p = json.loads(open("'"$topsrcdir"'/../buildprops.j
EOF
bucket=
if test -z "$SCCACHE_DISABLE" -a -z "$no_tooltool"; then
if test -z "$SCCACHE_DISABLE" -a -z "$no_sccache"; then
case "${branch}_${master}" in
try_*scl1.mozilla.com*|try_*.scl3.mozilla.com*)
bucket=mozilla-releng-ceph-cache-scl3-try

View File

@ -998,6 +998,7 @@ GK_ATOM(showresizer, "showresizer")
GK_ATOM(simple, "simple")
GK_ATOM(single, "single")
GK_ATOM(size, "size")
GK_ATOM(sizes, "sizes")
GK_ATOM(sizemode, "sizemode")
GK_ATOM(sizetopopup, "sizetopopup")
GK_ATOM(slider, "slider")

View File

@ -11,7 +11,6 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'content_canvas'
EXPORTS += [
'nsICanvasElementExternal.h',
'nsICanvasRenderingContextInternal.h',
]

View File

@ -1,58 +0,0 @@
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsICanvasElementExternal_h___
#define nsICanvasElementExternal_h___
#include "nsISupports.h"
#include "GraphicsFilter.h"
class gfxContext;
class nsIFrame;
struct gfxRect;
#define NS_ICANVASELEMENTEXTERNAL_IID \
{ 0x51870f54, 0x6c4c, 0x469a, {0xad, 0x46, 0xf0, 0xa9, 0x8e, 0x32, 0xa7, 0xe2 } }
class nsRenderingContext;
class nsICanvasRenderingContextInternal;
struct _cairo_surface;
/*
* This interface contains methods that are needed outside of the content/layout
* modules, specifically widget. It should eventually go away when we support
* libxul builds, and HTMLCanvasElement be used directly.
*
* Code internal to content/layout should /never/ use this interface; if the
* same functionality is needed in both places, two separate methods should be
* used.
*/
class nsICanvasElementExternal : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASELEMENTEXTERNAL_IID)
enum {
RenderFlagPremultAlpha = 0x1
};
/**
* Get the size in pixels of this canvas element
*/
NS_IMETHOD_(nsIntSize) GetSizeExternal() = 0;
/*
* Ask the canvas element to tell the contexts to render themselves
* to the given gfxContext at the origin of its coordinate space.
*/
NS_IMETHOD RenderContextsExternal(gfxContext *ctx,
GraphicsFilter aFilter,
uint32_t aFlags = RenderFlagPremultAlpha) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasElementExternal, NS_ICANVASELEMENTEXTERNAL_IID)
#endif /* nsICanvasElementExternal_h___ */

View File

@ -6,6 +6,7 @@
#ifndef nsICanvasRenderingContextInternal_h___
#define nsICanvasRenderingContextInternal_h___
#include "mozilla/gfx/2D.h"
#include "nsISupports.h"
#include "nsIInputStream.h"
#include "nsIDocShell.h"
@ -14,8 +15,8 @@
#include "mozilla/RefPtr.h"
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
{ 0x9a6a5bdf, 0x1261, 0x4057, \
{ 0x85, 0xcc, 0xaf, 0x97, 0x6c, 0x36, 0x99, 0xa9 } }
{ 0x3cc9e801, 0x1806, 0x4ff6, \
{ 0x86, 0x14, 0xf9, 0xd0, 0xf4, 0xfb, 0x3b, 0x08 } }
class gfxContext;
class gfxASurface;
@ -41,10 +42,6 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
enum {
RenderFlagPremultAlpha = 0x1
};
void SetCanvasElement(mozilla::dom::HTMLCanvasElement* aParentCanvas)
{
mCanvasElement = aParentCanvas;
@ -66,11 +63,6 @@ public:
NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) = 0;
// Render the canvas at the origin of the given gfxContext
NS_IMETHOD Render(gfxContext *ctx,
GraphicsFilter aFilter,
uint32_t aFlags = RenderFlagPremultAlpha) = 0;
// Creates an image buffer. Returns null on failure.
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) = 0;
@ -83,14 +75,13 @@ public:
NS_IMETHOD GetInputStream(const char *aMimeType,
const char16_t *aEncoderOptions,
nsIInputStream **aStream) = 0;
// If this canvas context can be represented with a simple Thebes surface,
// return the surface. Otherwise returns an error.
NS_IMETHOD GetThebesSurface(gfxASurface **surface) = 0;
// This gets an Azure SourceSurface for the canvas, this will be a snapshot
// of the canvas at the time it was called.
virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() = 0;
// If aPremultAlpha is provided, then it assumed the callee can handle
// un-premultiplied surfaces, and *aPremultAlpha will be set to false
// if one is returned.
virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) = 0;
// If this context is opaque, the backing store of the canvas should
// be created as opaque; all compositing operators should assume the

View File

@ -1053,51 +1053,6 @@ CanvasRenderingContext2D::SetIsIPC(bool isIPC)
return NS_OK;
}
NS_IMETHODIMP
CanvasRenderingContext2D::Render(gfxContext *ctx, GraphicsFilter aFilter, uint32_t aFlags)
{
nsresult rv = NS_OK;
EnsureTarget();
if (!IsTargetValid()) {
return NS_ERROR_FAILURE;
}
nsRefPtr<gfxASurface> surface;
if (NS_FAILED(GetThebesSurface(getter_AddRefs(surface)))) {
return NS_ERROR_FAILURE;
}
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
pat->SetFilter(aFilter);
pat->SetExtend(gfxPattern::EXTEND_PAD);
gfxContext::GraphicsOperator op = ctx->CurrentOperator();
if (mOpaque)
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
// XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
// pixel alignment for this stuff!
ctx->NewPath();
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
ctx->Fill();
if (mOpaque)
ctx->SetOperator(op);
if (!(aFlags & RenderFlagPremultAlpha)) {
nsRefPtr<gfxASurface> curSurface = ctx->CurrentSurface();
nsRefPtr<gfxImageSurface> gis = curSurface->GetAsImageSurface();
MOZ_ASSERT(gis, "If non-premult alpha, must be able to get image surface!");
gfxUtils::UnpremultiplyImageSurface(gis);
}
return rv;
}
NS_IMETHODIMP
CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value> aOptions)
{
@ -3266,28 +3221,6 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
error.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
// Special case for Canvas, which could be an Azure canvas!
nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
if (srcCanvas == this) {
// Self-copy.
srcSurf = mTarget->Snapshot();
imgSize = gfxIntSize(mWidth, mHeight);
} else if (srcCanvas) {
// This might not be an Azure canvas!
srcSurf = srcCanvas->GetSurfaceSnapshot();
if (srcSurf) {
if (mCanvasElement) {
// Do security check here.
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
element->NodePrincipal(),
canvas->IsWriteOnly(),
false);
}
imgSize = gfxIntSize(srcSurf->GetSize().width, srcSurf->GetSize().height);
}
}
} else {
if (image.IsHTMLImageElement()) {
HTMLImageElement* img = &image.GetAsHTMLImageElement();
@ -4147,27 +4080,6 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
return NS_OK;
}
NS_IMETHODIMP
CanvasRenderingContext2D::GetThebesSurface(gfxASurface **surface)
{
EnsureTarget();
if (!IsTargetValid()) {
return NS_ERROR_FAILURE;
}
nsRefPtr<gfxASurface> thebesSurface =
gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget);
if (!thebesSurface) {
return NS_ERROR_FAILURE;
}
*surface = thebesSurface;
NS_ADDREF(*surface);
return NS_OK;
}
static already_AddRefed<ImageData>
CreateImageData(JSContext* cx, CanvasRenderingContext2D* context,
uint32_t w, uint32_t h, ErrorResult& error)

View File

@ -457,16 +457,18 @@ public:
NS_IMETHOD SetDimensions(int32_t width, int32_t height) MOZ_OVERRIDE;
NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, int32_t width, int32_t height) MOZ_OVERRIDE;
NS_IMETHOD Render(gfxContext *ctx,
GraphicsFilter aFilter,
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
NS_IMETHOD GetInputStream(const char* aMimeType,
const char16_t* aEncoderOptions,
nsIInputStream **aStream) MOZ_OVERRIDE;
NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE
{ EnsureTarget(); return mTarget->Snapshot(); }
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr) MOZ_OVERRIDE
{
EnsureTarget();
if (aPremultAlpha) {
*aPremultAlpha = true;
}
return mTarget->Snapshot();
}
NS_IMETHOD SetIsOpaque(bool isOpaque) MOZ_OVERRIDE;
bool GetIsOpaque() MOZ_OVERRIDE { return mOpaque; }

View File

@ -136,25 +136,6 @@ WebGLContext::WebGLContext()
mFakeVertexAttrib0BufferObject = 0;
mFakeVertexAttrib0BufferStatus = WebGLVertexAttrib0Status::Default;
// these are de default values, see 6.2 State tables in the OpenGL ES 2.0.25 spec
mColorWriteMask[0] = 1;
mColorWriteMask[1] = 1;
mColorWriteMask[2] = 1;
mColorWriteMask[3] = 1;
mDepthWriteMask = 1;
mColorClearValue[0] = 0.f;
mColorClearValue[1] = 0.f;
mColorClearValue[2] = 0.f;
mColorClearValue[3] = 0.f;
mDepthClearValue = 1.f;
mStencilClearValue = 0;
mStencilRefFront = 0;
mStencilRefBack = 0;
mStencilValueMaskFront = 0xffffffff;
mStencilValueMaskBack = 0xffffffff;
mStencilWriteMaskFront = 0xffffffff;
mStencilWriteMaskBack = 0xffffffff;
mViewportX = 0;
mViewportY = 0;
mViewportWidth = 0;
@ -209,7 +190,7 @@ WebGLContext::WebGLContext()
InvalidateBufferFetching();
mIsScreenCleared = false;
mBackbufferNeedsClear = true;
mDisableFragHighP = false;
@ -423,7 +404,7 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
mHeight = gl->OffscreenSize().height;
mResetLayer = true;
ClearScreen();
mBackbufferNeedsClear = true;
return NS_OK;
}
@ -610,7 +591,11 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
gl->fClearDepth(1.0f);
gl->fClearStencil(0);
gl->ClearSafely();
mBackbufferNeedsClear = true;
// Clear immediately, because we need to present the cleared initial
// buffer.
ClearBackbufferIfNeeded();
mShouldPresent = true;
@ -625,46 +610,23 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
return NS_OK;
}
NS_IMETHODIMP
WebGLContext::Render(gfxContext *ctx, GraphicsFilter f, uint32_t aFlags)
void
WebGLContext::ClearBackbufferIfNeeded()
{
if (!gl)
return NS_OK;
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
gfxImageFormat::ARGB32);
if (surf->CairoStatus() != 0)
return NS_ERROR_FAILURE;
if (!mBackbufferNeedsClear)
return;
#ifdef DEBUG
gl->MakeCurrent();
ReadScreenIntoImageSurface(gl, surf);
bool srcPremultAlpha = mOptions.premultipliedAlpha;
bool dstPremultAlpha = aFlags & RenderFlagPremultAlpha;
GLuint fb = 0;
gl->GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &fb);
MOZ_ASSERT(fb == 0);
#endif
if (!srcPremultAlpha && dstPremultAlpha) {
gfxUtils::PremultiplyImageSurface(surf);
} else if (srcPremultAlpha && !dstPremultAlpha) {
gfxUtils::UnpremultiplyImageSurface(surf);
}
surf->MarkDirty();
ClearScreen();
nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
pat->SetFilter(f);
// Pixels from ReadPixels will be "upside down" compared to
// what cairo wants, so draw with a y-flip and a translte to
// flip them.
gfxMatrix m;
m.Translate(gfxPoint(0.0, mHeight));
m.Scale(1.0, -1.0);
pat->SetMatrix(m);
ctx->NewPath();
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
ctx->Fill();
return NS_OK;
mBackbufferNeedsClear = false;
}
void WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
@ -758,25 +720,31 @@ WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat)
*aImageBuffer = nullptr;
*aFormat = 0;
nsRefPtr<gfxImageSurface> imgsurf =
new gfxImageSurface(gfxIntSize(mWidth, mHeight),
gfxImageFormat::ARGB32);
// Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied
bool premult;
RefPtr<SourceSurface> snapshot =
GetSurfaceSnapshot(mOptions.premultipliedAlpha ? nullptr : &premult);
if (!snapshot) {
return;
}
MOZ_ASSERT(mOptions.premultipliedAlpha || !premult, "We must get unpremult when we ask for it!");
if (!imgsurf || imgsurf->CairoStatus()) {
RefPtr<DataSourceSurface> dataSurface = snapshot->GetDataSurface();
DataSourceSurface::MappedSurface map;
if (!dataSurface->Map(DataSourceSurface::MapType::READ, &map)) {
return;
}
nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf);
if (!ctx || ctx->HasError()) {
static const fallible_t fallible = fallible_t();
uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4];
if (!imageBuffer) {
dataSurface->Unmap();
return;
}
memcpy(imageBuffer, map.mData, mWidth * mHeight * 4);
// Use Render() to make sure that appropriate y-flip gets applied
uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0;
nsresult rv = Render(ctx, GraphicsFilter::FILTER_NEAREST, flags);
if (NS_FAILED(rv)) {
return;
}
dataSurface->Unmap();
int32_t format = imgIEncoder::INPUT_FORMAT_HOSTARGB;
if (!mOptions.premultipliedAlpha) {
@ -785,17 +753,10 @@ WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat)
// Yes, it is THAT silly.
// Except for different lossy conversions by color,
// we could probably just change the label, and not change the data.
gfxUtils::ConvertBGRAtoRGBA(imgsurf);
gfxUtils::ConvertBGRAtoRGBA(imageBuffer, mWidth * mHeight * 4);
format = imgIEncoder::INPUT_FORMAT_RGBA;
}
static const fallible_t fallible = fallible_t();
uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4];
if (!imageBuffer) {
return;
}
memcpy(imageBuffer, imgsurf->Data(), mWidth * mHeight * 4);
*aImageBuffer = imageBuffer;
*aFormat = format;
}
@ -827,12 +788,6 @@ WebGLContext::GetInputStream(const char* aMimeType,
encoder, aEncoderOptions, aStream);
}
NS_IMETHODIMP
WebGLContext::GetThebesSurface(gfxASurface **surface)
{
return NS_ERROR_NOT_AVAILABLE;
}
void WebGLContext::UpdateLastUseIndex()
{
static CheckedInt<uint64_t> sIndex = 0;
@ -1014,7 +969,6 @@ WebGLContext::ClearScreen()
colorAttachmentsMask[0] = true;
ForceClearFramebufferWithDefaultValues(clearMask, colorAttachmentsMask);
mIsScreenCleared = true;
}
#ifdef DEBUG
@ -1202,13 +1156,14 @@ WebGLContext::PresentScreenBuffer()
}
gl->MakeCurrent();
MOZ_ASSERT(!mBackbufferNeedsClear);
if (!gl->PublishFrame()) {
this->ForceLoseContext();
return false;
}
if (!mOptions.preserveDrawingBuffer) {
ClearScreen();
mBackbufferNeedsClear = true;
}
mShouldPresent = false;
@ -1376,9 +1331,61 @@ void
WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); }
mozilla::TemporaryRef<mozilla::gfx::SourceSurface>
WebGLContext::GetSurfaceSnapshot()
WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
{
return nullptr;
if (!gl)
return nullptr;
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
gfxImageFormat::ARGB32,
mWidth * 4, 0, false);
if (surf->CairoStatus() != 0) {
return nullptr;
}
gl->MakeCurrent();
{
ScopedBindFramebuffer autoFB(gl, 0);
ClearBackbufferIfNeeded();
ReadPixelsIntoImageSurface(gl, surf);
}
if (aPremultAlpha) {
*aPremultAlpha = true;
}
bool srcPremultAlpha = mOptions.premultipliedAlpha;
if (!srcPremultAlpha) {
if (aPremultAlpha) {
*aPremultAlpha = false;
} else {
gfxUtils::PremultiplyImageSurface(surf);
surf->MarkDirty();
}
}
RefPtr<DrawTarget> dt =
Factory::CreateDrawTarget(BackendType::CAIRO,
IntSize(mWidth, mHeight),
SurfaceFormat::B8G8R8A8);
if (!dt) {
return nullptr;
}
RefPtr<SourceSurface> source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, surf);
Matrix m;
m.Translate(0.0, mHeight);
m.Scale(1.0, -1.0);
dt->SetTransform(m);
dt->DrawSurface(source,
Rect(0, 0, mWidth, mHeight),
Rect(0, 0, mWidth, mHeight),
DrawSurfaceOptions(),
DrawOptions(1.0f, CompositionOp::OP_SOURCE));
return dt->Snapshot();
}
//

View File

@ -165,15 +165,11 @@ public:
{ return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD Reset() MOZ_OVERRIDE
{ /* (InitializeWithSurface) */ return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD Render(gfxContext *ctx,
GraphicsFilter f,
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
NS_IMETHOD GetInputStream(const char* aMimeType,
const char16_t* aEncoderOptions,
nsIInputStream **aStream) MOZ_OVERRIDE;
NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE;
mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha) MOZ_OVERRIDE;
NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; };
bool GetIsOpaque() MOZ_OVERRIDE { return false; }
@ -243,6 +239,7 @@ public:
// Calls ForceClearFramebufferWithDefaultValues() for the Context's 'screen'.
void ClearScreen();
void ClearBackbufferIfNeeded();
bool MinCapabilityMode() const { return mMinCapability; }
@ -841,7 +838,7 @@ protected:
bool mLoseContextOnHeapMinimize;
bool mCanLoseContextInForeground;
bool mShouldPresent;
bool mIsScreenCleared;
bool mBackbufferNeedsClear;
bool mDisableFragHighP;
template<typename WebGLObjectType>
@ -1034,7 +1031,7 @@ protected:
if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)
flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
if (!mPixelStorePremultiplyAlpha)
flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
flags |= nsLayoutUtils::SFE_PREFER_NO_PREMULTIPLY_ALPHA;
return nsLayoutUtils::SurfaceFromElement(aElement, flags);
}
template<class ElementType>

View File

@ -103,6 +103,8 @@ bool WebGLContext::DrawArrays_check(GLint first, GLsizei count, GLsizei primcoun
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
return false;
}
} else {
ClearBackbufferIfNeeded();
}
if (!DoFakeVertexAttrib0(checked_firstPlusCount.value())) {
@ -264,6 +266,8 @@ WebGLContext::DrawElements_check(GLsizei count, GLenum type,
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
return false;
}
} else {
ClearBackbufferIfNeeded();
}
if (!DoFakeVertexAttrib0(mMaxFetchedVertices)) {
@ -333,7 +337,7 @@ void WebGLContext::Draw_cleanup()
if (!mBoundFramebuffer) {
Invalidate();
mShouldPresent = true;
mIsScreenCleared = false;
MOZ_ASSERT(!mBackbufferNeedsClear);
}
if (gl->WorkAroundDriverBugs()) {

View File

@ -35,43 +35,13 @@ WebGLContext::Clear(GLbitfield mask)
gl->fClear(mask);
return;
} else {
ClearBackbufferIfNeeded();
}
// Ok, we're clearing the default framebuffer/screen.
bool needsClear = true;
if (mIsScreenCleared) {
bool isClearRedundant = true;
if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
if (mColorClearValue[0] != 0.0f ||
mColorClearValue[1] != 0.0f ||
mColorClearValue[2] != 0.0f ||
mColorClearValue[3] != 0.0f)
{
isClearRedundant = false;
}
}
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
if (mDepthClearValue != 1.0f) {
isClearRedundant = false;
}
}
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT) {
if (mStencilClearValue != 0) {
isClearRedundant = false;
}
}
if (isClearRedundant)
needsClear = false;
}
if (needsClear) {
gl->fClear(mask);
mIsScreenCleared = false;
}
gl->fClear(mask);
Invalidate();
mShouldPresent = true;

View File

@ -29,6 +29,7 @@
#include "nsLayoutUtils.h"
#include "CanvasUtils.h"
#include "gfxUtils.h"
#include "jsfriendapi.h"
@ -472,6 +473,8 @@ WebGLContext::CopyTexImage2D(GLenum target,
return ErrorInvalidOperation("copyTexImage2D: Read source attachment doesn't have the"
" correct color/depth/stencil type.");
}
} else {
ClearBackbufferIfNeeded();
}
bool texFormatRequiresAlpha = internalformat == LOCAL_GL_RGBA ||
@ -584,6 +587,8 @@ WebGLContext::CopyTexSubImage2D(GLenum target,
return ErrorInvalidOperation("copyTexSubImage2D: Read source attachment doesn't have the"
" correct color/depth/stencil type.");
}
} else {
ClearBackbufferIfNeeded();
}
bool texFormatRequiresAlpha = (internalFormat == LOCAL_GL_RGBA ||
@ -2194,6 +2199,8 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
return ErrorInvalidOperation("readPixels: Read source attachment doesn't have the"
" correct color/depth/stencil type.");
}
} else {
ClearBackbufferIfNeeded();
}
// Now that the errors are out of the way, on to actually reading
@ -2521,6 +2528,10 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE
return NS_OK;
}
if (!mPixelStorePremultiplyAlpha && res.mIsPremultiplied) {
data = gfxUtils::UnpremultiplyDataSurface(data);
}
// We disallow loading cross-domain images and videos that have not been validated
// with CORS as WebGL textures. The reason for doing that is that timing
// attacks on WebGL shaders are able to retrieve approximations of the

View File

@ -80,9 +80,8 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
if (MinCapabilityMode()) {
switch(pname) {
//
////////////////////////////
// Single-value params
//
// int
case LOCAL_GL_MAX_VERTEX_ATTRIBS:
@ -118,18 +117,15 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
}
}
if (IsExtensionEnabled(WEBGL_draw_buffers))
{
if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS)
{
if (IsExtensionEnabled(WEBGL_draw_buffers)) {
if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS) {
return JS::Int32Value(mGLMaxColorAttachments);
}
else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS)
{
} else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) {
return JS::Int32Value(mGLMaxDrawBuffers);
}
else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
} else if (pname >= LOCAL_GL_DRAW_BUFFER0 &&
pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers))
{
if (mBoundFramebuffer) {
GLint iv = 0;
@ -149,17 +145,12 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
}
if (IsExtensionEnabled(OES_vertex_array_object)) {
switch (pname) {
case LOCAL_GL_VERTEX_ARRAY_BINDING:
{
if (mBoundVertexArray == mDefaultVertexArray){
return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv);
}
return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv);
if (pname == LOCAL_GL_VERTEX_ARRAY_BINDING) {
if (mBoundVertexArray == mDefaultVertexArray){
return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv);
}
return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv);
}
}
@ -171,8 +162,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return StringValue(cx, "Mozilla", rv);
case LOCAL_GL_RENDERER:
return StringValue(cx, "Mozilla", rv);
case LOCAL_GL_VERSION:
{
case LOCAL_GL_VERSION: {
const char* version = 0;
if (IsWebGL2()) {
@ -189,13 +179,11 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
// Privileged string params exposed by WEBGL_debug_renderer_info:
case UNMASKED_VENDOR_WEBGL:
case UNMASKED_RENDERER_WEBGL:
{
case UNMASKED_RENDERER_WEBGL: {
// The privilege check is done in WebGLContext::IsExtensionSupported.
// So here we just have to check that the extension is enabled.
if (!IsExtensionEnabled(WEBGL_debug_renderer_info)) {
ErrorInvalidEnumInfo("getParameter: parameter", pname);
return JS::NullValue();
break;
}
GLenum glstringname = LOCAL_GL_NONE;
if (pname == UNMASKED_VENDOR_WEBGL) {
@ -207,9 +195,8 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return StringValue(cx, string, rv);
}
//
////////////////////////////////
// Single-value params
//
// unsigned int
case LOCAL_GL_CULL_FACE_MODE:
@ -230,8 +217,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_BLEND_DST_ALPHA:
case LOCAL_GL_BLEND_EQUATION_RGB:
case LOCAL_GL_BLEND_EQUATION_ALPHA:
case LOCAL_GL_GENERATE_MIPMAP_HINT:
{
case LOCAL_GL_GENERATE_MIPMAP_HINT: {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::NumberValue(uint32_t(i));
@ -254,23 +240,20 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_BLUE_BITS:
case LOCAL_GL_ALPHA_BITS:
case LOCAL_GL_DEPTH_BITS:
case LOCAL_GL_STENCIL_BITS:
{
case LOCAL_GL_STENCIL_BITS: {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
}
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT: {
if (IsExtensionEnabled(OES_standard_derivatives)) {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
} else {
break;
}
else {
ErrorInvalidEnum("getParameter: parameter", pname);
return JS::NullValue();
}
}
case LOCAL_GL_MAX_TEXTURE_SIZE:
return JS::Int32Value(mGLMaxTextureSize);
@ -291,8 +274,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
return JS::Int32Value(0);
case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS:
{
case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: {
uint32_t length = mCompressedTextureFormats.Length();
JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements());
if (!obj) {
@ -300,8 +282,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
}
return JS::ObjectOrNullValue(obj);
}
case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
{
case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: {
if (!IsWebGL2()) {
break;
}
@ -313,8 +294,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_STENCIL_BACK_VALUE_MASK:
case LOCAL_GL_STENCIL_BACK_WRITEMASK:
case LOCAL_GL_STENCIL_VALUE_MASK:
case LOCAL_GL_STENCIL_WRITEMASK:
{
case LOCAL_GL_STENCIL_WRITEMASK: {
GLint i = 0; // the GL api (glGetIntegerv) only does signed ints
gl->fGetIntegerv(pname, &i);
GLuint i_unsigned(i); // this is where -1 becomes 2^32-1
@ -323,21 +303,20 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
}
// float
case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
if (IsExtensionEnabled(EXT_texture_filter_anisotropic)) {
GLfloat f = 0.f;
gl->fGetFloatv(pname, &f);
return JS::DoubleValue(f);
} else {
ErrorInvalidEnumInfo("getParameter: parameter", pname);
return JS::NullValue();
break;
}
}
case LOCAL_GL_DEPTH_CLEAR_VALUE:
case LOCAL_GL_LINE_WIDTH:
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
case LOCAL_GL_POLYGON_OFFSET_UNITS:
case LOCAL_GL_SAMPLE_COVERAGE_VALUE:
{
case LOCAL_GL_SAMPLE_COVERAGE_VALUE: {
GLfloat f = 0.f;
gl->fGetFloatv(pname, &f);
return JS::DoubleValue(f);
@ -352,8 +331,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case LOCAL_GL_POLYGON_OFFSET_FILL:
case LOCAL_GL_SCISSOR_TEST:
case LOCAL_GL_SAMPLE_COVERAGE_INVERT:
case LOCAL_GL_DEPTH_WRITEMASK:
{
case LOCAL_GL_DEPTH_WRITEMASK: {
realGLboolean b = 0;
gl->fGetBooleanv(pname, &b);
return JS::BooleanValue(bool(b));
@ -369,13 +347,13 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
case UNPACK_COLORSPACE_CONVERSION_WEBGL:
return JS::NumberValue(uint32_t(mPixelStoreColorspaceConversion));
//
////////////////////////////////
// Complex values
//
case LOCAL_GL_DEPTH_RANGE: // 2 floats
case LOCAL_GL_ALIASED_POINT_SIZE_RANGE: // 2 floats
case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: // 2 floats
{
// 2 floats
case LOCAL_GL_DEPTH_RANGE:
case LOCAL_GL_ALIASED_POINT_SIZE_RANGE:
case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: {
GLfloat fv[2] = { 0 };
gl->fGetFloatv(pname, fv);
JSObject* obj = Float32Array::Create(cx, this, 2, fv);
@ -385,9 +363,9 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::ObjectOrNullValue(obj);
}
case LOCAL_GL_COLOR_CLEAR_VALUE: // 4 floats
case LOCAL_GL_BLEND_COLOR: // 4 floats
{
// 4 floats
case LOCAL_GL_COLOR_CLEAR_VALUE:
case LOCAL_GL_BLEND_COLOR: {
GLfloat fv[4] = { 0 };
gl->fGetFloatv(pname, fv);
JSObject* obj = Float32Array::Create(cx, this, 4, fv);
@ -397,8 +375,8 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::ObjectOrNullValue(obj);
}
case LOCAL_GL_MAX_VIEWPORT_DIMS: // 2 ints
{
// 2 ints
case LOCAL_GL_MAX_VIEWPORT_DIMS: {
GLint iv[2] = { 0 };
gl->fGetIntegerv(pname, iv);
JSObject* obj = Int32Array::Create(cx, this, 2, iv);
@ -408,9 +386,9 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::ObjectOrNullValue(obj);
}
case LOCAL_GL_SCISSOR_BOX: // 4 ints
case LOCAL_GL_VIEWPORT: // 4 ints
{
// 4 ints
case LOCAL_GL_SCISSOR_BOX:
case LOCAL_GL_VIEWPORT: {
GLint iv[4] = { 0 };
gl->fGetIntegerv(pname, iv);
JSObject* obj = Int32Array::Create(cx, this, 4, iv);
@ -420,8 +398,8 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::ObjectOrNullValue(obj);
}
case LOCAL_GL_COLOR_WRITEMASK: // 4 bools
{
// 4 bools
case LOCAL_GL_COLOR_WRITEMASK: {
realGLboolean gl_bv[4] = { 0 };
gl->fGetBooleanv(pname, gl_bv);
bool vals[4] = { bool(gl_bv[0]), bool(gl_bv[1]),
@ -433,53 +411,46 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return arr;
}
case LOCAL_GL_ARRAY_BUFFER_BINDING:
{
case LOCAL_GL_ARRAY_BUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
}
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
{
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: {
if (!IsWebGL2()) {
break;
}
return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
}
case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING:
{
case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundVertexArray->mBoundElementArrayBuffer.get(), rv);
}
case LOCAL_GL_RENDERBUFFER_BINDING:
{
case LOCAL_GL_RENDERBUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
}
case LOCAL_GL_FRAMEBUFFER_BINDING:
{
case LOCAL_GL_FRAMEBUFFER_BINDING: {
return WebGLObjectAsJSValue(cx, mBoundFramebuffer.get(), rv);
}
case LOCAL_GL_CURRENT_PROGRAM:
{
case LOCAL_GL_CURRENT_PROGRAM: {
return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv);
}
case LOCAL_GL_TEXTURE_BINDING_2D:
{
case LOCAL_GL_TEXTURE_BINDING_2D: {
return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv);
}
case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP:
{
case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP: {
return WebGLObjectAsJSValue(cx, mBoundCubeMapTextures[mActiveTexture].get(), rv);
}
default:
ErrorInvalidEnumInfo("getParameter: parameter", pname);
break;
}
ErrorInvalidEnumInfo("getParameter: parameter", pname);
return JS::NullValue();
}

View File

@ -1626,6 +1626,27 @@ WebGLContext::InitAndValidateGL()
mDisableFragHighP = true;
}
// These are the default values, see 6.2 State tables in the
// OpenGL ES 2.0.25 spec.
mColorWriteMask[0] = 1;
mColorWriteMask[1] = 1;
mColorWriteMask[2] = 1;
mColorWriteMask[3] = 1;
mDepthWriteMask = 1;
mColorClearValue[0] = 0.f;
mColorClearValue[1] = 0.f;
mColorClearValue[2] = 0.f;
mColorClearValue[3] = 0.f;
mDepthClearValue = 1.f;
mStencilClearValue = 0;
mStencilRefFront = 0;
mStencilRefBack = 0;
mStencilValueMaskFront = 0xffffffff;
mStencilValueMaskBack = 0xffffffff;
mStencilWriteMaskFront = 0xffffffff;
mStencilWriteMaskBack = 0xffffffff;
// Bindings, etc.
mActiveTexture = 0;
mEmitContextLostErrorOnce = true;
mWebGLError = LOCAL_GL_NO_ERROR;

View File

@ -13,7 +13,6 @@
#include "nsSize.h"
#include "nsError.h"
#include "nsICanvasElementExternal.h"
#include "mozilla/gfx/Rect.h"
class nsICanvasRenderingContextInternal;
@ -26,6 +25,9 @@ namespace layers {
class CanvasLayer;
class LayerManager;
}
namespace gfx {
class SourceSurface;
}
namespace dom {
@ -34,7 +36,6 @@ class HTMLCanvasPrintState;
class PrintCallback;
class HTMLCanvasElement MOZ_FINAL : public nsGenericHTMLElement,
public nsICanvasElementExternal,
public nsIDOMHTMLCanvasElement
{
enum {
@ -159,13 +160,7 @@ public:
*/
bool GetIsOpaque();
/*
* nsICanvasElementExternal -- for use outside of content/layout
*/
NS_IMETHOD_(nsIntSize) GetSizeExternal() MOZ_OVERRIDE;
NS_IMETHOD RenderContextsExternal(gfxContext *aContext,
GraphicsFilter aFilter,
uint32_t aFlags = RenderFlagPremultAlpha) MOZ_OVERRIDE;
virtual TemporaryRef<gfx::SourceSurface> GetSurfaceSnapshot(bool* aPremultAlpha = nullptr);
virtual bool ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,

View File

@ -38,6 +38,7 @@
#endif
using namespace mozilla::layers;
using namespace mozilla::gfx;
NS_IMPL_NS_NEW_HTML_ELEMENT(Canvas)
@ -130,9 +131,7 @@ NS_IMPL_ADDREF_INHERITED(HTMLCanvasElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLCanvasElement, Element)
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLCanvasElement)
NS_INTERFACE_TABLE_INHERITED2(HTMLCanvasElement,
nsIDOMHTMLCanvasElement,
nsICanvasElementExternal)
NS_INTERFACE_TABLE_INHERITED1(HTMLCanvasElement, nsIDOMHTMLCanvasElement)
NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLCanvasElement)
@ -934,19 +933,13 @@ HTMLCanvasElement::MarkContextClean()
mCurrentContext->MarkContextClean();
}
NS_IMETHODIMP_(nsIntSize)
HTMLCanvasElement::GetSizeExternal()
{
return GetWidthHeight();
}
NS_IMETHODIMP
HTMLCanvasElement::RenderContextsExternal(gfxContext *aContext, GraphicsFilter aFilter, uint32_t aFlags)
TemporaryRef<SourceSurface>
HTMLCanvasElement::GetSurfaceSnapshot(bool* aPremultAlpha)
{
if (!mCurrentContext)
return NS_OK;
return nullptr;
return mCurrentContext->Render(aContext, aFilter, aFlags);
return mCurrentContext->GetSurfaceSnapshot(aPremultAlpha);
}
} // namespace dom

View File

@ -196,10 +196,16 @@ HTMLLinkElement::ParseAttribute(int32_t aNamespaceID,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aNamespaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::crossorigin) {
ParseCORSValue(aValue, aResult);
return true;
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::crossorigin) {
ParseCORSValue(aValue, aResult);
return true;
}
if (aAttribute == nsGkAtoms::sizes) {
aResult.ParseAtomArray(aValue);
return true;
}
}
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,

View File

@ -109,6 +109,10 @@ public:
{
SetHTMLAttr(nsGkAtoms::hreflang, aHreflang, aRv);
}
nsDOMSettableTokenList* Sizes()
{
return GetTokenList(nsGkAtoms::sizes);
}
// XPCOM GetType is fine.
void SetType(const nsAString& aType, ErrorResult& aRv)
{

View File

@ -3154,6 +3154,7 @@ static nsIAtom** sPropertiesToTraverseAndUnlink[] =
&nsGkAtoms::itemref,
&nsGkAtoms::itemprop,
&nsGkAtoms::sandbox,
&nsGkAtoms::sizes,
nullptr
};

View File

@ -448,6 +448,7 @@ skip-if = buildapp == 'b2g' || e10s # b2g(multiple concurrent window.open()s fai
[test_imageSrcSet.html]
[test_li_attributes_reflection.html]
[test_link_attributes_reflection.html]
[test_link_sizes.html]
[test_map_attributes_reflection.html]
[test_meta_attributes_reflection.html]
[test_mod_attributes_reflection.html]

View File

@ -0,0 +1,35 @@
<!doctype html>
<html>
<head>
<title>Test link.sizes attribute</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" sizes="16x16 24x24 32x32 48x48">
</head>
<body>
<pre id="test">
<script>
var links = document.getElementsByTagName('link');
for (var i = 0; i < links.length; ++i) {
var link = links[i];
ok("sizes" in link, "link.sizes exists");
if (link.rel == 'shortcut icon') {
is(link.sizes.value, "16x16 24x24 32x32 48x48", 'link.sizes.value correct value');
is(link.sizes.length, 4, 'link.sizes.length correct value');
ok(link.sizes.contains('32x32'), 'link.sizes.contains() works');
link.sizes.add('64x64');
is(link.sizes.length, 5, 'link.sizes.length correct value');
link.sizes.remove('64x64');
is(link.sizes.length, 4, 'link.sizes.length correct value');
is(link.sizes + "", "16x16 24x24 32x32 48x48", 'link.sizes stringify correct value');
} else {
is(link.sizes.value, "", 'link.sizes correct value');
}
}
</script>
</pre>
</body>
</html>

View File

@ -502,6 +502,7 @@ AudioStream::CheckForStart()
NS_IMETHODIMP
AudioInitTask::Run()
{
MOZ_ASSERT(mThread);
if (NS_IsMainThread()) {
mThread->Shutdown(); // can't Shutdown from the thread itself, darn
mThread = nullptr;

View File

@ -433,7 +433,12 @@ public:
nsresult Dispatch()
{
return NS_NewNamedThread("CubebInit", getter_AddRefs(mThread), this);
// Can't add 'this' as the event to run, since mThread may not be set yet
nsresult rv = NS_NewNamedThread("CubebInit", getter_AddRefs(mThread));
if (NS_SUCCEEDED(rv)) {
rv = mThread->Dispatch(this, NS_DISPATCH_NORMAL);
}
return rv;
}
protected:

View File

@ -1259,8 +1259,8 @@ MediaStreamGraphImpl::RunThread()
UpdateStreamOrder();
}
TrackRate sampleRate;
// Find the sampling rate that we need to use for non-realtime graphs.
TrackRate sampleRate = IdealAudioRate();
if (!mRealtime) {
for (uint32_t i = 0; i < mStreams.Length(); ++i) {
AudioNodeStream* n = mStreams[i]->AsAudioNodeStream();
@ -1270,6 +1270,8 @@ MediaStreamGraphImpl::RunThread()
break;
}
}
} else {
sampleRate = IdealAudioRate();
}
GraphTime endBlockingDecisions =

View File

@ -30,10 +30,8 @@ GStreamerFormatHelper* GStreamerFormatHelper::Instance() {
}
void GStreamerFormatHelper::Shutdown() {
if (gInstance) {
delete gInstance;
gInstance = nullptr;
}
delete gInstance;
gInstance = nullptr;
}
static char const *const sContainers[6][2] = {

View File

@ -180,10 +180,8 @@ void AudioOutput::Close()
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
mTrack.clear();
if (mCallbackData) {
delete mCallbackData;
mCallbackData = NULL;
}
delete mCallbackData;
mCallbackData = nullptr;
}
// static

View File

@ -323,10 +323,8 @@ MediaPluginHost *GetMediaPluginHost()
void MediaPluginHost::Shutdown()
{
if (sMediaPluginHost) {
delete sMediaPluginHost;
sMediaPluginHost = nullptr;
}
delete sMediaPluginHost;
sMediaPluginHost = nullptr;
}
} // namespace mozilla

View File

@ -386,9 +386,7 @@ public:
tableInterpolationFactor);
// mPhase runs 0..periodicWaveSize here instead of 0..2*M_PI.
mPhase += periodicWaveSize * mFinalFrequency * rate;
if (mPhase >= periodicWaveSize) {
mPhase -= periodicWaveSize;
}
mPhase = fmod(mPhase, periodicWaveSize);
// Bilinear interpolation between adjacent samples in each table.
uint32_t j1 = floor(mPhase);
uint32_t j2 = j1 + 1;

View File

@ -468,10 +468,7 @@ MediaEngineWebRTCAudioSource::Shutdown()
mVoENetwork->DeRegisterExternalTransport(mChannel);
}
if (mNullTransport) {
delete mNullTransport;
}
delete mNullTransport;
return;
}
@ -491,9 +488,7 @@ MediaEngineWebRTCAudioSource::Shutdown()
mVoENetwork->DeRegisterExternalTransport(mChannel);
}
if (mNullTransport) {
delete mNullTransport;
}
delete mNullTransport;
mVoEProcessing = nullptr;
mVoENetwork = nullptr;

View File

@ -7,6 +7,8 @@
#include "mozilla/dom/ConsoleBinding.h"
#include "mozilla/dom/Exceptions.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/Maybe.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDocument.h"
#include "nsDOMNavigationTiming.h"
@ -16,6 +18,7 @@
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "xpcprivate.h"
#include "nsContentUtils.h"
#include "nsIConsoleAPIStorage.h"
#include "nsIDOMWindowUtils.h"
@ -171,7 +174,16 @@ public:
nsString mMethodString;
nsTArray<JS::Heap<JS::Value>> mArguments;
Sequence<ConsoleStackEntry> mStack;
// Stack management is complicated, because we want to do it as
// lazily as possible. Therefore, we have the following behavior:
// 1) mTopStackFrame is initialized whenever we have any JS on the stack
// 2) mReifiedStack is initialized if we're created in a worker.
// 3) mStack is set (possibly to null if there is no JS on the stack) if
// we're created on main thread.
Maybe<ConsoleStackEntry> mTopStackFrame;
Maybe<nsTArray<ConsoleStackEntry>> mReifiedStack;
nsCOMPtr<nsIStackFrame> mStack;
};
// This class is used to clear any exception at the end of this method.
@ -733,6 +745,58 @@ Console::__noSuchMethod__()
// Nothing to do.
}
static
nsresult
StackFrameToStackEntry(nsIStackFrame* aStackFrame,
ConsoleStackEntry& aStackEntry,
uint32_t aLanguage)
{
MOZ_ASSERT(aStackFrame);
nsresult rv = aStackFrame->GetFilename(aStackEntry.mFilename);
NS_ENSURE_SUCCESS(rv, rv);
int32_t lineNumber;
rv = aStackFrame->GetLineNumber(&lineNumber);
NS_ENSURE_SUCCESS(rv, rv);
aStackEntry.mLineNumber = lineNumber;
rv = aStackFrame->GetName(aStackEntry.mFunctionName);
NS_ENSURE_SUCCESS(rv, rv);
aStackEntry.mLanguage = aLanguage;
return NS_OK;
}
static
nsresult
ReifyStack(nsIStackFrame* aStack, nsTArray<ConsoleStackEntry>& aRefiedStack)
{
nsCOMPtr<nsIStackFrame> stack(aStack);
while (stack) {
uint32_t language;
nsresult rv = stack->GetLanguage(&language);
NS_ENSURE_SUCCESS(rv, rv);
if (language == nsIProgrammingLanguage::JAVASCRIPT ||
language == nsIProgrammingLanguage::JAVASCRIPT2) {
ConsoleStackEntry& data = *aRefiedStack.AppendElement();
rv = StackFrameToStackEntry(stack, data, language);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIStackFrame> caller;
rv = stack->GetCaller(getter_AddRefs(caller));
NS_ENSURE_SUCCESS(rv, rv);
stack.swap(caller);
}
return NS_OK;
}
// Queue a call to a console method. See the CALL_DELAY constant.
void
Console::Method(JSContext* aCx, MethodName aMethodName,
@ -797,8 +861,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
return;
}
// nsIStackFrame is not thread-safe so we take what we need and we store in
// an array of ConsoleStackEntry objects.
// Walk up to the first JS stack frame and save it if we find it.
do {
uint32_t language;
nsresult rv = stack->GetLanguage(&language);
@ -809,30 +872,16 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
if (language == nsIProgrammingLanguage::JAVASCRIPT ||
language == nsIProgrammingLanguage::JAVASCRIPT2) {
ConsoleStackEntry& data = *callData->mStack.AppendElement();
rv = stack->GetFilename(data.mFilename);
callData->mTopStackFrame.construct();
nsresult rv = StackFrameToStackEntry(stack,
callData->mTopStackFrame.ref(),
language);
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return;
}
int32_t lineNumber;
rv = stack->GetLineNumber(&lineNumber);
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return;
}
data.mLineNumber = lineNumber;
rv = stack->GetName(data.mFunctionName);
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return;
}
data.mLanguage = language;
break;
}
nsCOMPtr<nsIStackFrame> caller;
@ -845,6 +894,19 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
stack.swap(caller);
} while (stack);
if (NS_IsMainThread()) {
callData->mStack = stack;
} else {
// nsIStackFrame is not threadsafe, so we need to snapshot it now,
// before we post our runnable to the main thread.
callData->mReifiedStack.construct();
nsresult rv = ReifyStack(stack, callData->mReifiedStack.ref());
if (NS_WARN_IF(NS_FAILED(rv))) {
Throw(aCx, rv);
return;
}
}
// Monotonic timer for 'time' and 'timeEnd'
if ((aMethodName == MethodTime || aMethodName == MethodTimeEnd) && mWindow) {
nsGlobalWindow *win = static_cast<nsGlobalWindow*>(mWindow.get());
@ -918,14 +980,60 @@ Console::Notify(nsITimer *timer)
return NS_OK;
}
// We store information to lazily compute the stack in the reserved slots of
// LazyStackGetter. The first slot always stores a JS object: it's either the
// JS wrapper of the nsIStackFrame or the actual reified stack representation.
// The second slot is a PrivateValue() holding an nsIStackFrame* when we haven't
// reified the stack yet, or an UndefinedValue() otherwise.
enum {
SLOT_STACKOBJ,
SLOT_RAW_STACK
};
bool
LazyStackGetter(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
{
JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
JS::Rooted<JSObject*> callee(aCx, &args.callee());
JS::Value v = js::GetFunctionNativeReserved(&args.callee(), SLOT_RAW_STACK);
if (v.isUndefined()) {
// Already reified.
args.rval().set(js::GetFunctionNativeReserved(callee, SLOT_STACKOBJ));
return true;
}
nsIStackFrame* stack = reinterpret_cast<nsIStackFrame*>(v.toPrivate());
nsTArray<ConsoleStackEntry> reifiedStack;
nsresult rv = ReifyStack(stack, reifiedStack);
if (NS_FAILED(rv)) {
Throw(aCx, rv);
return false;
}
JS::Rooted<JS::Value> stackVal(aCx);
if (!ToJSValue(aCx, reifiedStack, &stackVal)) {
return false;
}
MOZ_ASSERT(stackVal.isObject());
js::SetFunctionNativeReserved(callee, SLOT_STACKOBJ, stackVal);
js::SetFunctionNativeReserved(callee, SLOT_RAW_STACK, JS::UndefinedValue());
args.rval().set(stackVal);
return true;
}
void
Console::ProcessCallData(ConsoleCallData* aData)
{
MOZ_ASSERT(aData);
MOZ_ASSERT(NS_IsMainThread());
ConsoleStackEntry frame;
if (!aData->mStack.IsEmpty()) {
frame = aData->mStack[0];
if (!aData->mTopStackFrame.empty()) {
frame = aData->mTopStackFrame.ref();
}
AutoSafeJSContext cx;
@ -971,14 +1079,9 @@ Console::ProcessCallData(ConsoleCallData* aData)
ArgumentsToValueList(aData->mArguments, event.mArguments.Value());
}
if (ShouldIncludeStackrace(aData->mMethodName)) {
event.mStacktrace.Construct();
event.mStacktrace.Value().SwapElements(aData->mStack);
}
else if (aData->mMethodName == MethodGroup ||
aData->mMethodName == MethodGroupCollapsed ||
aData->mMethodName == MethodGroupEnd) {
if (aData->mMethodName == MethodGroup ||
aData->mMethodName == MethodGroupCollapsed ||
aData->mMethodName == MethodGroupEnd) {
ComposeGroupName(cx, aData->mArguments, event.mGroupName);
}
@ -994,6 +1097,18 @@ Console::ProcessCallData(ConsoleCallData* aData)
event.mCounter = IncreaseCounter(cx, frame, aData->mArguments);
}
// We want to create a console event object and pass it to our
// nsIConsoleAPIStorage implementation. We want to define some accessor
// properties on this object, and those will need to keep an nsIStackFrame
// alive. But nsIStackFrame cannot be wrapped in an untrusted scope. And
// further, passing untrusted objects to system code is likely to run afoul of
// Object Xrays. So we want to wrap in a system-principal scope here. But
// which one? We could cheat and try to get the underlying JSObject* of
// mStorage, but that's a bit fragile. Instead, we just use the junk scope,
// with explicit permission from the XPConnect module owner. If you're
// tempted to do that anywhere else, talk to said module owner first.
JSAutoCompartment ac2(cx, xpc::GetJunkScope());
JS::Rooted<JS::Value> eventValue(cx);
if (!event.ToObject(cx, &eventValue)) {
Throw(cx, NS_ERROR_FAILURE);
@ -1007,6 +1122,51 @@ Console::ProcessCallData(ConsoleCallData* aData)
return;
}
if (ShouldIncludeStackrace(aData->mMethodName)) {
// Now define the "stacktrace" property on eventObj. There are two cases
// here. Either we came from a worker and have a reified stack, or we want
// to define a getter that will lazily reify the stack.
if (!aData->mReifiedStack.empty()) {
JS::Rooted<JS::Value> stacktrace(cx);
if (!ToJSValue(cx, aData->mReifiedStack.ref(), &stacktrace) ||
!JS_DefineProperty(cx, eventObj, "stacktrace", stacktrace,
JSPROP_ENUMERATE)) {
return;
}
} else {
JSFunction* fun = js::NewFunctionWithReserved(cx, LazyStackGetter, 0, 0,
eventObj, "stacktrace");
if (!fun) {
return;
}
JS::Rooted<JSObject*> funObj(cx, JS_GetFunctionObject(fun));
// We want to store our stack in the function and have it stay alive. But
// we also need sane access to the C++ nsIStackFrame. So store both a JS
// wrapper and the raw pointer: the former will keep the latter alive.
JS::Rooted<JS::Value> stackVal(cx);
nsresult rv = nsContentUtils::WrapNative(cx, aData->mStack,
&stackVal);
if (NS_FAILED(rv)) {
return;
}
js::SetFunctionNativeReserved(funObj, SLOT_STACKOBJ, stackVal);
js::SetFunctionNativeReserved(funObj, SLOT_RAW_STACK,
JS::PrivateValue(aData->mStack.get()));
if (!JS_DefineProperty(cx, eventObj, "stacktrace",
JS::UndefinedHandleValue,
JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_GETTER |
JSPROP_SETTER,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, funObj.get()),
nullptr)) {
return;
}
}
}
if (!mStorage) {
mStorage = do_GetService("@mozilla.org/consoleAPI-storage;1");
}

View File

@ -12459,82 +12459,38 @@ nsGlobalWindow::GetScrollFrame()
}
nsresult
nsGlobalWindow::BuildURIfromBase(const char *aURL, nsIURI **aBuiltURI,
JSContext **aCXused)
nsGlobalWindow::SecurityCheckURL(const char *aURL)
{
nsIScriptContext *scx = GetContextInternal();
JSContext *cx = nullptr;
*aBuiltURI = nullptr;
if (aCXused)
*aCXused = nullptr;
// get JSContext
NS_ASSERTION(scx, "opening window missing its context");
NS_ASSERTION(mDoc, "opening window missing its document");
if (!scx || !mDoc)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMChromeWindow> chrome_win = do_QueryObject(this);
if (nsContentUtils::IsCallerChrome() && !chrome_win) {
// If open() is called from chrome on a non-chrome window, we'll
// use the context from the window on which open() is being called
// to prevent giving chrome priveleges to new windows opened in
// such a way. This also makes us get the appropriate base URI for
// the below URI resolution code.
cx = scx->GetNativeContext();
} else {
// get the JSContext from the call stack
cx = nsContentUtils::GetCurrentJSContext();
}
/* resolve the URI, which could be relative to the calling window
(note the algorithm to get the base URI should match the one
used to actually kick off the load in nsWindowWatcher.cpp). */
nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8")); // default to utf-8
nsIURI* baseURI = nullptr;
nsCOMPtr<nsIURI> uriToLoad;
nsCOMPtr<nsPIDOMWindow> sourceWindow;
if (cx) {
nsIScriptContext *scriptcx = nsJSUtils::GetDynamicScriptContext(cx);
if (scriptcx)
sourceWindow = do_QueryInterface(scriptcx->GetGlobalObject());
JSContext* topCx = nsContentUtils::GetCurrentJSContext();
if (topCx) {
sourceWindow = do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(topCx));
}
if (!sourceWindow) {
sourceWindow = this;
}
AutoJSContext cx;
nsGlobalWindow* sourceWin = static_cast<nsGlobalWindow*>(sourceWindow.get());
JSAutoCompartment ac(cx, sourceWin->GetGlobalJSObject());
// Resolve the baseURI, which could be relative to the calling window.
//
// Note the algorithm to get the base URI should match the one
// used to actually kick off the load in nsWindowWatcher.cpp.
nsCOMPtr<nsIDocument> doc = sourceWindow->GetDoc();
nsIURI* baseURI = nullptr;
nsAutoCString charset(NS_LITERAL_CSTRING("UTF-8")); // default to utf-8
if (doc) {
baseURI = doc->GetDocBaseURI();
charset = doc->GetDocumentCharacterSet();
}
if (aCXused)
*aCXused = cx;
return NS_NewURI(aBuiltURI, nsDependentCString(aURL), charset.get(), baseURI);
}
nsresult
nsGlobalWindow::SecurityCheckURL(const char *aURL)
{
JSContext *cxUsed;
nsCOMPtr<nsIURI> uri;
if (NS_FAILED(BuildURIfromBase(aURL, getter_AddRefs(uri), &cxUsed))) {
return NS_ERROR_FAILURE;
nsresult rv = NS_NewURI(getter_AddRefs(uri), nsDependentCString(aURL),
charset.get(), baseURI);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!cxUsed) {
return NS_OK;
}
AutoPushJSContext cx(cxUsed);
if (NS_FAILED(nsContentUtils::GetSecurityManager()->
CheckLoadURIFromScript(cx, uri))) {
return NS_ERROR_FAILURE;

View File

@ -1198,8 +1198,7 @@ protected:
already_AddRefed<nsIBaseWindow> GetTreeOwnerWindow();
already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome();
nsresult SecurityCheckURL(const char *aURL);
nsresult BuildURIfromBase(const char *aURL, nsIURI **aBuiltURI,
JSContext **aCXused);
bool PopupWhitelisted();
PopupControlState RevisePopupAbuseLevel(PopupControlState);
void FireAbuseEvents(bool aBlocked, bool aWindow,

View File

@ -131,28 +131,7 @@ Throw(JSContext* aCx, nsresult aRv, const char* aMessage)
}
}
nsRefPtr<Exception> finalException;
// Do we use DOM exceptions for this error code?
switch (NS_ERROR_GET_MODULE(aRv)) {
case NS_ERROR_MODULE_DOM:
case NS_ERROR_MODULE_SVG:
case NS_ERROR_MODULE_DOM_XPATH:
case NS_ERROR_MODULE_DOM_INDEXEDDB:
case NS_ERROR_MODULE_DOM_FILEHANDLE:
finalException = DOMException::Create(aRv);
break;
default:
break;
}
// If not, use the default.
if (!finalException) {
// aMessage can be null.
finalException = new Exception(nsCString(aMessage), aRv,
EmptyCString(), nullptr, nullptr);
}
nsRefPtr<Exception> finalException = CreateException(aCx, aRv, aMessage);
MOZ_ASSERT(finalException);
if (!ThrowExceptionObject(aCx, finalException)) {
@ -164,6 +143,29 @@ Throw(JSContext* aCx, nsresult aRv, const char* aMessage)
return false;
}
already_AddRefed<Exception>
CreateException(JSContext* aCx, nsresult aRv, const char* aMessage)
{
// Do we use DOM exceptions for this error code?
switch (NS_ERROR_GET_MODULE(aRv)) {
case NS_ERROR_MODULE_DOM:
case NS_ERROR_MODULE_SVG:
case NS_ERROR_MODULE_DOM_XPATH:
case NS_ERROR_MODULE_DOM_INDEXEDDB:
case NS_ERROR_MODULE_DOM_FILEHANDLE:
return DOMException::Create(aRv);
default:
break;
}
// If not, use the default.
// aMessage can be null, so we can't use nsDependentCString on it.
nsRefPtr<Exception> exception =
new Exception(nsCString(aMessage), aRv,
EmptyCString(), nullptr, nullptr);
return exception.forget();
}
already_AddRefed<nsIStackFrame>
GetCurrentJSStack()
{

View File

@ -30,6 +30,11 @@ ThrowExceptionObject(JSContext* aCx, Exception* aException);
bool
ThrowExceptionObject(JSContext* aCx, nsIException* aException);
// Create an exception object for the given nsresult and message but
// don't set it pending on aCx. This never returns null.
already_AddRefed<Exception>
CreateException(JSContext* aCx, nsresult aRv, const char* aMessage = nullptr);
already_AddRefed<nsIStackFrame>
GetCurrentJSStack();

View File

@ -5,6 +5,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/Exceptions.h"
#include "nsAString.h"
#include "nsContentUtils.h"
#include "nsStringBuffer.h"
@ -49,5 +51,14 @@ ISupportsToJSValue(JSContext* aCx,
} // namespace tojsvalue_detail
bool
ToJSValue(JSContext* aCx,
nsresult aArgument,
JS::MutableHandle<JS::Value> aValue)
{
nsRefPtr<Exception> exception = CreateException(aCx, aArgument);
return ToJSValue(aCx, exception, aValue);
}
} // namespace dom
} // namespace mozilla

View File

@ -54,6 +54,14 @@ ToJSValue(JSContext* aCx,
return true;
}
// The uint32_t version is disabled for now because on the super-old b2g
// compiler nsresult and uint32_t are the same type. If someone needs this at
// some point we'll need to figure out how to make it work (e.g. by switching to
// traits structs and using the trick IPC's ParamTraits uses, where a traits
// struct templated on the type inherits from a base traits struct of some sort,
// templated on the same type, or something). Maybe b2g will update to a modern
// compiler before that happens....
#if 0
inline bool
ToJSValue(JSContext* aCx,
uint32_t aArgument,
@ -65,6 +73,7 @@ ToJSValue(JSContext* aCx,
aValue.setNumber(aArgument);
return true;
}
#endif
inline bool
ToJSValue(JSContext* aCx,
@ -203,6 +212,22 @@ ToJSValue(JSContext* aCx,
return aArgument.ToObject(aCx, aValue);
}
// Accept existing JS values (which may not be same-compartment with us
inline bool
ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
JS::MutableHandle<JS::Value> aValue)
{
aValue.set(aArgument);
return MaybeWrapValue(aCx, aValue);
}
// Accept nsresult, for use in rejections, and create an XPCOM
// exception object representing that nsresult.
bool
ToJSValue(JSContext* aCx,
nsresult aArgument,
JS::MutableHandle<JS::Value> aValue);
// Accept arrays of other things we accept
template <typename T>
bool

View File

@ -18,6 +18,8 @@
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
#include "mozilla/ipc/DocumentRendererChild.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
#include "mozilla/layers/ActiveElementManager.h"
#include "mozilla/layers/APZCCallbackHelper.h"
#include "mozilla/layers/AsyncPanZoomController.h"
#include "mozilla/layers/CompositorChild.h"
#include "mozilla/layers/ImageBridgeChild.h"
@ -68,13 +70,11 @@
#include "StructuredCloneUtils.h"
#include "nsViewportInfo.h"
#include "JavaScriptChild.h"
#include "APZCCallbackHelper.h"
#include "nsILoadContext.h"
#include "ipc/nsGUIEventIPC.h"
#include "mozilla/gfx/Matrix.h"
#include "UnitTransforms.h"
#include "ClientLayerManager.h"
#include "ActiveElementManager.h"
#include "nsColorPickerProxy.h"

View File

@ -42,7 +42,7 @@ namespace layout {
class RenderFrameChild;
}
namespace widget {
namespace layers {
class ActiveElementManager;
}
@ -232,7 +232,7 @@ class TabChild : public PBrowserChild,
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
typedef mozilla::layout::ScrollingBehavior ScrollingBehavior;
typedef mozilla::widget::ActiveElementManager ActiveElementManager;
typedef mozilla::layers::ActiveElementManager ActiveElementManager;
public:
/**

View File

@ -493,12 +493,21 @@ function PeerConnectionTest(options) {
PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
info("Closing peer connections. Connection state=" + this.connected);
function signalingstatechangeClose(state) {
info("'onsignalingstatechange' event '" + state + "' received");
is(state, "closed", "onsignalingstatechange event is closed");
}
// There is no onclose event for the remote peer existent yet. So close it
// side-by-side with the local peer.
if (this.pcLocal)
if (this.pcLocal) {
this.pcLocal.onsignalingstatechange = signalingstatechangeClose;
this.pcLocal.close();
if (this.pcRemote)
}
if (this.pcRemote) {
this.pcRemote.onsignalingstatechange = signalingstatechangeClose;
this.pcRemote.close();
}
this.connected = false;
onSuccess();
@ -585,8 +594,9 @@ function PCT_setLocalDescription(peer, desc, onSuccess) {
}
}
peer.onsignalingstatechange = function () {
info(peer + ": 'onsignalingstatechange' event registered, signalingState: " + peer.signalingState);
peer.onsignalingstatechange = function (state) {
//info(peer + ": 'onsignalingstatechange' event registered, signalingState: " + peer.signalingState);
info(peer + ": 'onsignalingstatechange' event '" + state + "' received");
eventFired = true;
check_next_test();
@ -646,8 +656,8 @@ function PCT_setRemoteDescription(peer, desc, onSuccess) {
}
}
peer.onsignalingstatechange = function () {
info(peer + ": 'onsignalingstatechange' event registered, signalingState: " + peer.signalingState);
peer.onsignalingstatechange = function (state) {
info(peer + ": 'onsignalingstatechange' event '" + state + "' received");
eventFired = true;
check_next_test();
@ -1168,7 +1178,9 @@ function PeerConnectionWrapper(label, configuration) {
this._pc.onsignalingstatechange = function (aEvent) {
info(self + ": 'onsignalingstatechange' event fired");
self.onsignalingstatechange();
// this calls the eventhandler only once and then overwrites it with the
// default unexpectedEvent handler
self.onsignalingstatechange(aEvent);
self.onsignalingstatechange = unexpectedEventAndFinish(self, 'onsignalingstatechange');
};
}

View File

@ -56,6 +56,11 @@
var description;
var exception = null;
// handle the event which the close() triggers
test.pcLocal.onsignalingstatechange = function (state) {
is(state, "closed", "Received expected onsignalingstatechange event 'closed'");
}
test.pcLocal.close();
try { description = test.pcLocal.localDescription; } catch (e) { exception = e; }
@ -66,6 +71,11 @@
ok(exception, "Attempt to access remoteDescription of pcLocal after close throws exception");
exception = null;
// handle the event which the close() triggers
test.pcRemote.onsignalingstatechange = function (state) {
is(state, "closed", "Received expected onsignalingstatechange event 'closed'");
}
test.pcRemote.close();
try { description = test.pcRemote.localDescription; } catch (e) { exception = e; }

View File

@ -49,6 +49,8 @@
exception = null;
try { pconnects.createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: "42" }] }); } catch (e) { exception = e; }
ok(!exception, "createOffer(step1, failed, { mandatory: { OfferToReceiveVideo: false, OfferToReceiveAudio: true, MozDontOfferDataChannel: true}, optional: [{ VoiceActivityDetection: true }, { FooBar: \"42\" }] }) succeeds");
pconnect.close();
pconnects.close();
pconnect = null;
pconnects = null;
SimpleTest.finish();

View File

@ -78,15 +78,17 @@ public:
JS::Handle<JS::Value> aValue);
// Helpers for using Promise from C++.
// Most DOM objects are handled already. To add a new type T, such as ints,
// or dictionaries, add a ToJSValue overload in ToJSValue.h.
// Most DOM objects are handled already. To add a new type T, add a
// ToJSValue overload in ToJSValue.h.
// aArg is a const reference so we can pass rvalues like integer constants
template <typename T>
void MaybeResolve(T& aArg) {
void MaybeResolve(const T& aArg) {
MaybeSomething(aArg, &Promise::MaybeResolve);
}
// aArg is a const reference so we can pass rvalues like NS_ERROR_*
template <typename T>
void MaybeReject(T& aArg) {
void MaybeReject(const T& aArg) {
MaybeSomething(aArg, &Promise::MaybeReject);
}

View File

@ -47,7 +47,12 @@ dictionary ConsoleEvent {
sequence<any> styles;
boolean private = false;
sequence<ConsoleStackEntry> stacktrace;
// stacktrace is handled via a getter in some cases so we can construct it
// lazily. Note that we're not making this whole thing an interface because
// consumers expect to see own properties on it, which would mean making the
// props unforgeable, which means lots of JSFunction allocations. Maybe we
// should fix those consumers, of course....
// sequence<ConsoleStackEntry> stacktrace;
DOMString groupName = "";
any timer = null;
any counter = null;

View File

@ -28,8 +28,7 @@ interface HTMLLinkElement : HTMLElement {
attribute DOMString hreflang;
[SetterThrows, Pure]
attribute DOMString type;
// Not supported yet:
// [PutForwards=value] readonly attribute DOMSettableTokenList sizes;
[PutForwards=value] readonly attribute DOMSettableTokenList sizes;
};
HTMLLinkElement implements LinkStyle;

View File

@ -4,7 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "APZCTreeManager.h"
#include "AsyncCompositionManager.h" // for ViewTransform
#include "Compositor.h" // for Compositor
#include "CompositorParent.h" // for CompositorParent, etc
#include "InputData.h" // for InputData, etc
@ -12,6 +11,7 @@
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "mozilla/dom/Touch.h" // for Touch
#include "mozilla/gfx/Point.h" // for Point
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
#include "mozilla/layers/AsyncPanZoomController.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/mozalloc.h" // for operator new

View File

@ -14,7 +14,6 @@
#include "FrameMetrics.h" // for FrameMetrics, etc
#include "GestureEventListener.h" // for GestureEventListener
#include "InputData.h" // for MultiTouchInput, etc
#include "LayerTransactionParent.h" // for LayerTransactionParent
#include "Units.h" // for CSSRect, CSSPoint, etc
#include "UnitTransforms.h" // for TransformTo
#include "base/message_loop.h" // for MessageLoop
@ -40,7 +39,7 @@
#include "mozilla/layers/APZCTreeManager.h" // for ScrollableLayerGuid
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
#include "mozilla/layers/Axis.h" // for AxisX, AxisY, Axis, etc
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/layers/LayerTransactionParent.h" // for LayerTransactionParent
#include "mozilla/layers/PCompositorParent.h" // for PCompositorParent
#include "mozilla/layers/TaskThrottler.h" // for TaskThrottler
#include "mozilla/mozalloc.h" // for operator new, etc
@ -619,9 +618,10 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
mX.StartTouch(point.x);
mY.StartTouch(point.y);
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
if (treeManagerLocal && controller) {
bool touchCanBePan = treeManagerLocal->CanBePanned(this);
mGeckoContentController->NotifyAPZStateChange(
controller->NotifyAPZStateChange(
GetGuid(), APZStateChange::StartTouch, touchCanBePan);
}
SetState(TOUCHING);
@ -962,8 +962,10 @@ nsEventStatus AsyncPanZoomController::GenerateSingleTap(const ScreenIntPoint& aP
}
void AsyncPanZoomController::OnTouchEndOrCancel() {
mGeckoContentController->NotifyAPZStateChange(
GetGuid(), APZStateChange::EndTouch, mTouchBlockState.mSingleTapOccurred);
if (nsRefPtr<GeckoContentController> controller = GetGeckoContentController()) {
controller->NotifyAPZStateChange(
GetGuid(), APZStateChange::EndTouch, mTouchBlockState.mSingleTapOccurred);
}
}
nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) {
@ -1108,7 +1110,9 @@ nsEventStatus AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent
}
if (IsPanningState(mState)) {
mGeckoContentController->NotifyAPZStateChange(GetGuid(), APZStateChange::StartPanning);
if (nsRefPtr<GeckoContentController> controller = GetGeckoContentController()) {
controller->NotifyAPZStateChange(GetGuid(), APZStateChange::StartPanning);
}
return nsEventStatus_eConsumeNoDefault;
}
// Don't consume an event that didn't trigger a panning.
@ -2007,12 +2011,12 @@ void AsyncPanZoomController::SetState(PanZoomState aNewState) {
mState = aNewState;
}
if (mGeckoContentController) {
if (nsRefPtr<GeckoContentController> controller = GetGeckoContentController()) {
if (!IsTransformingState(oldState) && IsTransformingState(aNewState)) {
mGeckoContentController->NotifyAPZStateChange(
controller->NotifyAPZStateChange(
GetGuid(), APZStateChange::TransformBegin);
} else if (IsTransformingState(oldState) && !IsTransformingState(aNewState)) {
mGeckoContentController->NotifyAPZStateChange(
controller->NotifyAPZStateChange(
GetGuid(), APZStateChange::TransformEnd);
}
}

View File

@ -8,7 +8,7 @@
#define mozilla_layers_AsyncPanZoomController_h
#include "CrossProcessMutex.h"
#include "GeckoContentController.h"
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/Monitor.h"

View File

@ -12,7 +12,7 @@
#include "nsIInterfaceRequestorUtils.h"
namespace mozilla {
namespace widget {
namespace layers {
bool
APZCCallbackHelper::HasValidPresShellId(nsIDOMWindowUtils* aUtils,

View File

@ -3,8 +3,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/. */
#ifndef __mozilla_widget_APZCCallbackHelper_h__
#define __mozilla_widget_APZCCallbackHelper_h__
#ifndef mozilla_layers_APZCCallbackHelper_h
#define mozilla_layers_APZCCallbackHelper_h
#include "FrameMetrics.h"
#include "nsIContent.h"
@ -12,7 +12,7 @@
#include "nsIDOMWindowUtils.h"
namespace mozilla {
namespace widget {
namespace layers {
/* This class contains some helper methods that facilitate implementing the
GeckoContentController callback interface required by the AsyncPanZoomController.
@ -100,4 +100,4 @@ public:
}
}
#endif /*__mozilla_widget_APZCCallbackHelper_h__ */
#endif /* mozilla_layers_APZCCallbackHelper_h */

View File

@ -15,7 +15,7 @@
#include "base/task.h"
namespace mozilla {
namespace widget {
namespace layers {
static int32_t sActivationDelayMs = 100;
static bool sActivationDelayMsSet = false;
@ -148,4 +148,4 @@ ActiveElementManager::CancelTask()
}
}
}
}

View File

@ -3,8 +3,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/. */
#ifndef __mozilla_widget_ActiveElementManager_h__
#define __mozilla_widget_ActiveElementManager_h__
#ifndef mozilla_layers_ActiveElementManager_h
#define mozilla_layers_ActiveElementManager_h
#include "nsCOMPtr.h"
#include "nsISupportsImpl.h"
@ -15,7 +15,7 @@ class nsIDOMElement;
class CancelableTask;
namespace mozilla {
namespace widget {
namespace layers {
/**
* Manages setting and clearing the ':active' CSS pseudostate in the presence
@ -82,4 +82,4 @@ private:
}
}
#endif /*__mozilla_widget_ActiveElementManager_h__ */
#endif /* mozilla_layers_ActiveElementManager_h */

View File

@ -34,7 +34,6 @@
#include "mozilla/layers/TextureHost.h"
#include "nsThreadUtils.h"
using namespace base;
using namespace mozilla::ipc;
using namespace mozilla::gfx;
@ -118,7 +117,7 @@ ImageBridgeParent::RecvUpdateNoSwap(const EditArray& aEdits)
static void
ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
Transport* aTransport,
ProcessHandle aOtherProcess)
base::ProcessHandle aOtherProcess)
{
aBridge->Open(aTransport, aOtherProcess, XRE_GetIOMessageLoop(), ipc::ParentSide);
}
@ -126,7 +125,7 @@ ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
/*static*/ PImageBridgeParent*
ImageBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
{
ProcessHandle processHandle;
base::ProcessHandle processHandle;
if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
return nullptr;
}

View File

@ -41,7 +41,7 @@
#include "GeckoProfiler.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/AsyncCompositionManager.h"
#include "AsyncPanZoomController.h"
#include "mozilla/layers/AsyncPanZoomController.h"
typedef std::vector<mozilla::layers::EditReply> EditReplyVector;

View File

@ -97,6 +97,16 @@ EXPORTS.gfxipc += [
]
EXPORTS.mozilla.layers += [
'apz/public/GeckoContentController.h',
# exporting things from apz/src is temporary until we extract a
# proper interface for the code there
'apz/src/APZCTreeManager.h',
'apz/src/AsyncPanZoomController.h',
'apz/src/Axis.h',
'apz/src/GestureEventListener.h',
'apz/src/TaskThrottler.h',
'apz/util/ActiveElementManager.h',
'apz/util/APZCCallbackHelper.h',
'AtomicRefCountedWithFinalize.h',
'basic/BasicCompositor.h',
'basic/MacIOSurfaceTextureHostBasic.h',
@ -110,7 +120,6 @@ EXPORTS.mozilla.layers += [
'client/TextureClient.h',
'client/TextureClientPool.h',
'client/TiledContentClient.h',
'composite/APZCTreeManager.h',
'composite/AsyncCompositionManager.h',
'composite/CanvasLayerComposite.h',
'composite/ColorLayerComposite.h',
@ -126,15 +135,11 @@ EXPORTS.mozilla.layers += [
'D3D9SurfaceImage.h',
'Effects.h',
'ImageDataSerializer.h',
'ipc/AsyncPanZoomController.h',
'ipc/Axis.h',
'ipc/CompositableForwarder.h',
'ipc/CompositableTransactionParent.h',
'ipc/CompositorChild.h',
'ipc/CompositorParent.h',
'ipc/FenceUtils.h',
'ipc/GeckoContentController.h',
'ipc/GestureEventListener.h',
'ipc/ImageBridgeChild.h',
'ipc/ImageBridgeParent.h',
'ipc/ISurfaceAllocator.h',
@ -144,7 +149,6 @@ EXPORTS.mozilla.layers += [
'ipc/ShadowLayersManager.h',
'ipc/SharedPlanarYCbCrImage.h',
'ipc/SharedRGBImage.h',
'ipc/TaskThrottler.h',
'LayersTypes.h',
'opengl/CompositingRenderTargetOGL.h',
'opengl/CompositorOGL.h',
@ -216,6 +220,13 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
]
UNIFIED_SOURCES += [
'apz/src/APZCTreeManager.cpp',
'apz/src/AsyncPanZoomController.cpp',
'apz/src/Axis.cpp',
'apz/src/GestureEventListener.cpp',
'apz/src/TaskThrottler.cpp',
'apz/util/ActiveElementManager.cpp',
'apz/util/APZCCallbackHelper.cpp',
'basic/BasicCanvasLayer.cpp',
'basic/BasicColorLayer.cpp',
'basic/BasicCompositor.cpp',
@ -242,7 +253,6 @@ UNIFIED_SOURCES += [
'client/TextureClient.cpp',
'client/TextureClientPool.cpp',
'client/TiledContentClient.cpp',
'composite/APZCTreeManager.cpp',
'composite/AsyncCompositionManager.cpp',
'composite/CanvasLayerComposite.cpp',
'composite/ColorLayerComposite.cpp',
@ -261,12 +271,9 @@ UNIFIED_SOURCES += [
'Effects.cpp',
'ImageDataSerializer.cpp',
'ImageLayers.cpp',
'ipc/AsyncPanZoomController.cpp',
'ipc/Axis.cpp',
'ipc/CompositableTransactionParent.cpp',
'ipc/CompositorChild.cpp',
'ipc/CompositorParent.cpp',
'ipc/GestureEventListener.cpp',
'ipc/ImageBridgeChild.cpp',
'ipc/ImageBridgeParent.cpp',
'ipc/ISurfaceAllocator.cpp',
@ -277,7 +284,6 @@ UNIFIED_SOURCES += [
'ipc/ShadowLayers.cpp',
'ipc/SharedPlanarYCbCrImage.cpp',
'ipc/SharedRGBImage.cpp',
'ipc/TaskThrottler.cpp',
'LayerScope.cpp',
'LayersLogging.cpp',
'LayerSorter.cpp',

View File

@ -830,13 +830,13 @@ gfxMacPlatformFontList::RegisteredFontsChangedNotificationCallback(CFNotificatio
return;
}
gfxMacPlatformFontList* fl = static_cast<gfxMacPlatformFontList*>(observer);
// xxx - should be carefully pruning the list of fonts, not rebuilding it from scratch
static_cast<gfxMacPlatformFontList*>(observer)->UpdateFontList();
fl->UpdateFontList();
// modify a preference that will trigger reflow everywhere
static const char kPrefName[] = "font.internaluseonly.changed";
bool fontInternalChange = Preferences::GetBool(kPrefName, false);
Preferences::SetBool(kPrefName, !fontInternalChange);
fl->ForceGlobalReflow();
}
gfxFontEntry*

View File

@ -9,6 +9,7 @@
#include "prlog.h"
#include "gfxPlatformFontList.h"
#include "gfxUserFontSet.h"
#include "nsUnicharUtils.h"
#include "nsUnicodeRange.h"
@ -303,6 +304,21 @@ gfxPlatformFontList::ResolveFontName(const nsAString& aFontName, nsAString& aRes
return false;
}
static PLDHashOperator
RebuildLocalFonts(nsPtrHashKey<gfxUserFontSet>* aKey,
void* aClosure)
{
aKey->GetKey()->RebuildLocalRules();
return PL_DHASH_NEXT;
}
void
gfxPlatformFontList::UpdateFontList()
{
InitFontList();
mUserFontSetList.EnumerateEntries(RebuildLocalFonts, nullptr);
}
struct FontListData {
FontListData(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,
@ -797,6 +813,11 @@ gfxPlatformFontList::LoadFontInfo()
}
#endif
if (done) {
mOtherFamilyNamesInitialized = true;
mFaceNamesInitialized = true;
}
return done;
}
@ -820,8 +841,6 @@ gfxPlatformFontList::CleanupLoader()
}
#endif
mOtherFamilyNamesInitialized = true;
mFaceNamesInitialized = true;
gfxFontInfoLoader::CleanupLoader();
}
@ -839,6 +858,15 @@ gfxPlatformFontList::GetPrefsAndStartLoader()
StartLoader(delay, interval);
}
void
gfxPlatformFontList::ForceGlobalReflow()
{
// modify a preference that will trigger reflow everywhere
static const char kPrefName[] = "font.internaluseonly.changed";
bool fontInternalChange = Preferences::GetBool(kPrefName, false);
Preferences::SetBool(kPrefName, !fontInternalChange);
}
// Support for memory reporting
static size_t

View File

@ -82,6 +82,8 @@ struct FontListSizes {
uint32_t mCharMapsSize; // memory used for cmap coverage info
};
class gfxUserFontSet;
class gfxPlatformFontList : public gfxFontInfoLoader
{
public:
@ -115,7 +117,7 @@ public:
virtual bool ResolveFontName(const nsAString& aFontName,
nsAString& aResolvedFontName);
void UpdateFontList() { InitFontList(); }
void UpdateFontList();
void ClearPrefFonts() { mPrefFonts.Clear(); }
@ -178,6 +180,15 @@ public:
// remove the cmap from the shared cmap set
void RemoveCmap(const gfxCharacterMap *aCharMap);
// keep track of userfont sets to notify when global fontlist changes occur
void AddUserFontSet(gfxUserFontSet *aUserFontSet) {
mUserFontSetList.PutEntry(aUserFontSet);
}
void RemoveUserFontSet(gfxUserFontSet *aUserFontSet) {
mUserFontSetList.RemoveEntry(aUserFontSet);
}
protected:
class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
{
@ -254,6 +265,9 @@ protected:
// read the loader initialization prefs, and start it
void GetPrefsAndStartLoader();
// for font list changes that affect all documents
void ForceGlobalReflow();
// used by memory reporter to accumulate sizes of family names in the hash
static size_t
SizeOfFamilyNameEntryExcludingThis(const nsAString& aKey,
@ -305,6 +319,8 @@ protected:
uint32_t mStartIndex;
uint32_t mIncrement;
uint32_t mNumFamilies;
nsTHashtable<nsPtrHashKey<gfxUserFontSet> > mUserFontSetList;
};
#endif /* GFXPLATFORMFONTLIST_H_ */

View File

@ -18,6 +18,7 @@
#include "gfxFontConstants.h"
#include "mozilla/Services.h"
#include "mozilla/gfx/2D.h"
#include "gfxPlatformFontList.h"
#include "opentype-sanitiser.h"
#include "ots-memory-stream.h"
@ -102,13 +103,21 @@ gfxProxyFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeed
}
gfxUserFontSet::gfxUserFontSet()
: mFontFamilies(5)
: mFontFamilies(5), mLocalRulesUsed(false)
{
IncrementGeneration();
gfxPlatformFontList *fp = gfxPlatformFontList::PlatformFontList();
if (fp) {
fp->AddUserFontSet(this);
}
}
gfxUserFontSet::~gfxUserFontSet()
{
gfxPlatformFontList *fp = gfxPlatformFontList::PlatformFontList();
if (fp) {
fp->RemoveUserFontSet(this);
}
}
gfxFontEntry*
@ -539,6 +548,7 @@ gfxUserFontSet::LoadNext(gfxMixedFontFamily *aFamily,
gfxFontEntry *fe =
gfxPlatform::GetPlatform()->LookupLocalFont(aProxyEntry,
currSrc.mLocalName);
mLocalRulesUsed = true;
if (fe) {
LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n",
this, aProxyEntry->mSrcIndex,
@ -664,6 +674,13 @@ gfxUserFontSet::IncrementGeneration()
mGeneration = sFontSetGeneration;
}
void
gfxUserFontSet::RebuildLocalRules()
{
if (mLocalRulesUsed) {
DoRebuildUserFontSet();
}
}
gfxFontEntry*
gfxUserFontSet::LoadFont(gfxMixedFontFamily *aFamily,

View File

@ -242,6 +242,9 @@ public:
// increment the generation on font load
void IncrementGeneration();
// rebuild if local rules have been used
void RebuildLocalRules();
class UserFontCache {
public:
// Record a loaded user-font in the cache. This requires that the
@ -418,11 +421,17 @@ protected:
static bool OTSMessage(void *aUserData, const char *format, ...);
// helper method for performing the actual userfont set rebuild
virtual void DoRebuildUserFontSet() = 0;
// font families defined by @font-face rules
nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies;
uint64_t mGeneration;
// true when local names have been looked up, false otherwise
bool mLocalRulesUsed;
static PRLogModuleInfo* GetUserFontsLog();
private:

View File

@ -141,6 +141,66 @@ gfxUtils::UnpremultiplyImageSurface(gfxImageSurface *aSourceSurface,
}
}
TemporaryRef<DataSourceSurface>
gfxUtils::UnpremultiplyDataSurface(DataSourceSurface* aSurface)
{
// Only premultiply ARGB32
if (aSurface->GetFormat() != SurfaceFormat::B8G8R8A8) {
return aSurface;
}
DataSourceSurface::MappedSurface map;
if (!aSurface->Map(DataSourceSurface::MapType::READ, &map)) {
return nullptr;
}
RefPtr<DataSourceSurface> dest = Factory::CreateDataSourceSurfaceWithStride(aSurface->GetSize(),
aSurface->GetFormat(),
map.mStride);
DataSourceSurface::MappedSurface destMap;
if (!dest->Map(DataSourceSurface::MapType::WRITE, &destMap)) {
aSurface->Unmap();
return nullptr;
}
uint8_t *src = map.mData;
uint8_t *dst = destMap.mData;
for (int32_t i = 0; i < aSurface->GetSize().height; ++i) {
uint8_t *srcRow = src + (i * map.mStride);
uint8_t *dstRow = dst + (i * destMap.mStride);
for (int32_t j = 0; j < aSurface->GetSize().width; ++j) {
#ifdef IS_LITTLE_ENDIAN
uint8_t b = *srcRow++;
uint8_t g = *srcRow++;
uint8_t r = *srcRow++;
uint8_t a = *srcRow++;
*dstRow++ = UnpremultiplyValue(a, b);
*dstRow++ = UnpremultiplyValue(a, g);
*dstRow++ = UnpremultiplyValue(a, r);
*dstRow++ = a;
#else
uint8_t a = *srcRow++;
uint8_t r = *srcRow++;
uint8_t g = *srcRow++;
uint8_t b = *srcRow++;
*dstRow++ = a;
*dstRow++ = UnpremultiplyValue(a, r);
*dstRow++ = UnpremultiplyValue(a, g);
*dstRow++ = UnpremultiplyValue(a, b);
#endif
}
}
aSurface->Unmap();
dest->Unmap();
return dest;
}
void
gfxUtils::ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface) {
@ -186,6 +246,24 @@ gfxUtils::ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
}
}
void
gfxUtils::ConvertBGRAtoRGBA(uint8_t* aData, uint32_t aLength)
{
uint8_t *src = aData;
uint8_t *srcEnd = src + aLength;
uint8_t buffer[4];
for (; src != srcEnd; src += 4) {
buffer[0] = src[2];
buffer[1] = src[1];
buffer[2] = src[0];
src[0] = buffer[0];
src[1] = buffer[1];
src[2] = buffer[2];
}
}
static bool
IsSafeImageTransformComponent(gfxFloat aValue)
{

View File

@ -44,9 +44,11 @@ public:
gfxImageSurface *aDestSurface = nullptr);
static void UnpremultiplyImageSurface(gfxImageSurface *aSurface,
gfxImageSurface *aDestSurface = nullptr);
static mozilla::TemporaryRef<DataSourceSurface> UnpremultiplyDataSurface(DataSourceSurface* aSurface);
static void ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface = nullptr);
static void ConvertBGRAtoRGBA(uint8_t* aData, uint32_t aLength);
/**
* Draw something drawable while working around limitations like bad support

View File

@ -23,6 +23,7 @@
#include "vm/GlobalObject.h"
#include "vm/Interpreter.h"
#include "vm/ProxyObject.h"
#include "vm/TraceLogging.h"
#include "jscntxtinlines.h"
#include "jsobjinlines.h"
@ -744,9 +745,9 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
RootedValue startValue(cx, UndefinedValue());
if (args.length() > 0) {
jsval v = args[0];
if (JSVAL_IS_TRACEABLE(v)) {
if (v.isMarkable()) {
startValue = v;
} else if (!JSVAL_IS_NULL(v)) {
} else if (!v.isNull()) {
JS_ReportError(cx,
"the first argument is not null or a heap-allocated "
"thing");
@ -771,11 +772,11 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
return false;
}
traceValue = args[2];
if (!JSVAL_IS_TRACEABLE(traceValue)){
if (!traceValue.isMarkable()){
JS_ReportError(cx, "cannot trace this kind of value");
return false;
}
traceThing = JSVAL_TO_TRACEABLE(traceValue);
traceThing = traceValue.toGCThing();
} else {
for (size_t i = 0; ;) {
if (JS_FlatStringEqualsAscii(flatStr, traceKindNames[i].name)) {
@ -1488,6 +1489,26 @@ TimesAccessed(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
static bool
EnableTraceLogger(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
args.rval().setBoolean(TraceLoggerEnable(logger));
return true;
}
static bool
DisableTraceLogger(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
TraceLogger *logger = TraceLoggerForMainThread(cx->runtime());
args.rval().setBoolean(TraceLoggerDisable(logger));
return true;
}
static const JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj] | 'compartment')",
@ -1723,6 +1744,15 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
"workerThreadCount()",
" Returns the number of worker threads available for off-main-thread tasks."),
JS_FN_HELP("startTraceLogger", EnableTraceLogger, 0, 0,
"startTraceLogger()",
" Start logging the mainThread.\n"
" Note: tracelogging starts automatically. Disable it by setting environment variable\n"
" TLOPTIONS=disableMainThread"),
JS_FN_HELP("stopTraceLogger", DisableTraceLogger, 0, 0,
"startTraceLogger()",
" Stop logging the mainThread."),
JS_FS_HELP_END
};

View File

@ -141,12 +141,6 @@ class BumpChunk
return aligned;
}
void *peek(size_t n) {
if (bump - bumpBase() < ptrdiff_t(n))
return nullptr;
return bump - n;
}
static BumpChunk *new_(size_t chunkSize);
static void delete_(BumpChunk *chunk);
};
@ -461,16 +455,6 @@ class LifoAlloc
return Mark(chunk_, position_);
}
};
// Return a modifiable pointer to the most recently allocated bytes. The
// type of the thing must be known, so is only applicable to some special-
// purpose allocators. Will return a nullptr if nothing has been allocated.
template <typename T>
T *peek() {
if (!latest)
return nullptr;
return static_cast<T *>(latest->peek(sizeof(T)));
}
};
class LifoAllocScope

View File

@ -352,7 +352,7 @@ JS::HeapCellRelocate(js::gc::Cell **cellp)
JS_PUBLIC_API(void)
JS::HeapValuePostBarrier(JS::Value *valuep)
{
JS_ASSERT(JSVAL_IS_TRACEABLE(*valuep));
JS_ASSERT(valuep->isMarkable());
if (valuep->isString() && StringIsPermanentAtom(valuep->toString()))
return;
JSRuntime *runtime = static_cast<js::gc::Cell *>(valuep->toGCThing())->runtimeFromMainThread();
@ -363,7 +363,7 @@ JS_PUBLIC_API(void)
JS::HeapValueRelocate(JS::Value *valuep)
{
/* Called with old contents of *valuep before overwriting. */
JS_ASSERT(JSVAL_IS_TRACEABLE(*valuep));
JS_ASSERT(valuep->isMarkable());
if (valuep->isString() && StringIsPermanentAtom(valuep->toString()))
return;
JSRuntime *runtime = static_cast<js::gc::Cell *>(valuep->toGCThing())->runtimeFromMainThread();

View File

@ -134,10 +134,6 @@ class StoreBuffer
void put(StoreBuffer *owner, const T &t) {
JS_ASSERT(storage_);
T *tip = storage_->peek<T>();
if (tip && tip->canMergeWith(t))
return tip->mergeInplace(t);
T *tp = storage_->new_<T>(t);
if (!tp)
CrashAtUnhandlableOOM("Failed to allocate for MonoTypeBuffer::put.");
@ -251,9 +247,6 @@ class StoreBuffer
return !nursery.isInside(edge) && nursery.isInside(*edge);
}
bool canMergeWith(const CellPtrEdge &other) const { return edge == other.edge; }
void mergeInplace(const CellPtrEdge &) {}
void mark(JSTracer *trc);
CellPtrEdge tagged() const { return CellPtrEdge((Cell **)(uintptr_t(edge) | 1)); }
@ -277,9 +270,6 @@ class StoreBuffer
return !nursery.isInside(edge) && nursery.isInside(deref());
}
bool canMergeWith(const ValueEdge &other) const { return edge == other.edge; }
void mergeInplace(const ValueEdge &) {}
void mark(JSTracer *trc);
ValueEdge tagged() const { return ValueEdge((JS::Value *)(uintptr_t(edge) | 1)); }
@ -321,16 +311,6 @@ class StoreBuffer
return !(*this == other);
}
bool canMergeWith(const SlotsEdge &other) const {
return objectAndKind_ == other.objectAndKind_;
}
void mergeInplace(const SlotsEdge &other) {
int32_t end = Max(start_ + count_, other.start_ + other.count_);
start_ = Min(start_, other.start_);
count_ = end - start_;
}
bool maybeInRememberedSet(const Nursery &nursery) const {
return !nursery.isInside(object());
}
@ -360,9 +340,6 @@ class StoreBuffer
static bool supportsDeduplication() { return true; }
void *deduplicationKey() const { return (void *)edge; }
bool canMergeWith(const WholeCellEdges &other) const { return edge == other.edge; }
void mergeInplace(const WholeCellEdges &) {}
void mark(JSTracer *trc);
typedef PointerEdgeHasher<WholeCellEdges> Hasher;

View File

@ -237,6 +237,33 @@ if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
})();
/* Implicit "use strict" context */
(function() {
var funcHeader = 'function (glob, ffi, heap) {',
funcBody = '\n"use asm";\n\
function g() {}\n\
return g;\n\n'
funcFooter = '}',
funcSource = funcHeader + funcBody + funcFooter
useStrict = '\n"use strict";\n';
var f4 = eval("\"use strict\";\n(" + funcSource + ")");
var expectedToString = funcHeader + useStrict + funcBody + funcFooter
var expectedToSource = '(' + expectedToString + ')'
assertEq(f4.toString(), expectedToString);
assertEq(f4.toSource(), expectedToSource);
if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
var f5 = eval("\"use strict\";\n(" + funcSource + ")");
assertEq(isAsmJSModuleLoadedFromCache(f5), true);
assertEq(f5.toString(), expectedToString);
assertEq(f5.toSource(), expectedToSource);
}
})();
/* Functions */
(function() {

View File

@ -0,0 +1,5 @@
function f(x) {
return Math.cos(~(~Math.pow(Number.MAX_VALUE, x)))
}
f(-0)
assertEq(f(undefined - undefined), 1)

View File

@ -0,0 +1,5 @@
function f(x) {
return Math.round(-Math.tan(x > 0))
}
f(2)
assertEq(f(-1), -0);

View File

@ -1143,7 +1143,13 @@ class MOZ_STACK_CLASS ModuleCompiler
uint32_t funcStart = parser_.pc->maybeFunction->pn_body->pn_pos.begin;
uint32_t offsetToEndOfUseAsm = parser_.tokenStream.currentToken().pos.end;
module_ = cx_->new_<AsmJSModule>(parser_.ss, funcStart, offsetToEndOfUseAsm);
// "use strict" should be added to the source if we are in an implicit
// strict context, see also comment above addUseStrict in
// js::FunctionToString.
bool strict = parser_.pc->sc->strict && !parser_.pc->sc->hasExplicitUseStrict();
module_ = cx_->new_<AsmJSModule>(parser_.ss, funcStart, offsetToEndOfUseAsm, strict);
if (!module_)
return false;
@ -1514,7 +1520,6 @@ class MOZ_STACK_CLASS ModuleCompiler
{
module_->initFuncEnd(parser_.tokenStream.currentToken().pos.end,
parser_.tokenStream.peekTokenPos().end);
masm_.finish();
if (masm_.oom())
return false;

View File

@ -800,8 +800,31 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
if (!src)
return nullptr;
if (!out.append(src->chars(), src->length()))
return nullptr;
if (module.strict()) {
// We need to add "use strict" in the body right after the opening
// brace.
size_t bodyStart = 0, bodyEnd;
// No need to test for functions created with the Function ctor as
// these doesn't implicitly inherit the "use strict" context. Strict mode is
// enabled for functions created with the Function ctor only if they begin with
// the "use strict" directive, but these functions won't validate as asm.js
// modules.
ConstTwoByteChars chars(src->chars(), src->length());
if (!FindBody(cx, fun, chars, src->length(), &bodyStart, &bodyEnd))
return nullptr;
if (!out.append(chars, bodyStart) ||
!out.append("\n\"use strict\";\n") ||
!out.append(chars + bodyStart, src->length() - bodyStart))
{
return nullptr;
}
} else {
if (!out.append(src->chars(), src->length()))
return nullptr;
}
if (funCtor && !out.append("\n}"))
return nullptr;

View File

@ -328,7 +328,8 @@ AsmJSModule::staticallyLink(ExclusiveContext *cx)
}
}
AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t funcStart, uint32_t offsetToEndOfUseAsm)
AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t funcStart,
uint32_t offsetToEndOfUseAsm, bool strict)
: globalArgumentName_(nullptr),
importArgumentName_(nullptr),
bufferArgumentName_(nullptr),
@ -344,6 +345,7 @@ AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t funcStart, uint32_
mozilla::PodZero(&pod);
scriptSource_->incref();
pod.minHeapLength_ = AsmJSAllocationGranularity;
pod.strict_ = strict;
}
AsmJSModule::~AsmJSModule()
@ -876,7 +878,7 @@ AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) con
{
AutoUnprotectCodeForClone cloneGuard(cx, *this);
*moduleOut = cx->new_<AsmJSModule>(scriptSource_, funcStart_, offsetToEndOfUseAsm_);
*moduleOut = cx->new_<AsmJSModule>(scriptSource_, funcStart_, offsetToEndOfUseAsm_, pod.strict_);
if (!*moduleOut)
return false;
@ -1313,8 +1315,9 @@ js::LookupAsmJSModuleInCache(ExclusiveContext *cx,
uint32_t funcStart = parser.pc->maybeFunction->pn_body->pn_pos.begin;
uint32_t offsetToEndOfUseAsm = parser.tokenStream.currentToken().pos.end;
bool strict = parser.pc->sc->strict && !parser.pc->sc->hasExplicitUseStrict();
ScopedJSDeletePtr<AsmJSModule> module(
cx->new_<AsmJSModule>(parser.ss, funcStart, offsetToEndOfUseAsm));
cx->new_<AsmJSModule>(parser.ss, funcStart, offsetToEndOfUseAsm, strict));
if (!module)
return false;
cursor = module->deserialize(cx, cursor);

View File

@ -431,6 +431,7 @@ class AsmJSModule
struct Pod {
uint32_t funcLength_;
uint32_t funcLengthWithRightBrace_;
bool strict_;
uint32_t numGlobalVars_;
uint32_t numFFIs_;
size_t funcPtrTableAndExitBytes_;
@ -464,7 +465,8 @@ class AsmJSModule
mutable bool codeIsProtected_;
public:
explicit AsmJSModule(ScriptSource *scriptSource, uint32_t functStart, uint32_t offsetToEndOfUseAsm);
explicit AsmJSModule(ScriptSource *scriptSource, uint32_t functStart,
uint32_t offsetToEndOfUseAsm, bool strict);
~AsmJSModule();
void trace(JSTracer *trc) {
@ -524,6 +526,9 @@ class AsmJSModule
uint32_t funcEndAfterCurly() const {
return funcStart_ + pod.funcLengthWithRightBrace_;
}
bool strict() const {
return pod.strict_;
}
bool addGlobalVarInit(const Value &v, AsmJSCoercion coercion, uint32_t *globalIndex) {
JS_ASSERT(pod.funcPtrTableAndExitBytes_ == 0);

View File

@ -586,13 +586,6 @@ IonBuilder::inlineMathAbs(CallInfo &callInfo)
MInstruction *ins = MAbs::New(alloc(), callInfo.getArg(0), absType);
current->add(ins);
if (IsFloatingPointType(argType) && returnType == MIRType_Int32) {
MToInt32 *toInt = MToInt32::New(alloc(), ins);
toInt->setCanBeNegativeZero(false);
current->add(toInt);
ins = toInt;
}
current->push(ins);
return InliningStatus_Inlined;
}

View File

@ -2328,12 +2328,6 @@ MToDouble::foldsTo(TempAllocator &alloc, bool useValueNumbers)
}
}
// Fold unnecessary numeric conversions.
if (input()->isToInt32()) {
replaceOperand(0, input()->getOperand(0));
conversion_ = NonStringPrimitives;
}
return this;
}

View File

@ -295,6 +295,7 @@ TypeBarrierPolicy::adjustInputs(TempAllocator &alloc, MInstruction *def)
// We can't unbox a value to null/undefined. So keep output also a value.
if (IsNullOrUndefined(outputType) || outputType == MIRType_Magic) {
JS_ASSERT(ins->defUseCount() == 0);
ins->setResultType(MIRType_Value);
return true;
}

View File

@ -14,6 +14,7 @@
#include "jit/MIR.h"
#include "jit/MIRGenerator.h"
#include "jit/ParallelFunctions.h"
#include "vm/TraceLogging.h"
#include "jit/IonFrames-inl.h"
@ -628,6 +629,11 @@ CodeGeneratorShared::callVM(const VMFunction &fun, LInstruction *ins, const Regi
}
#endif
#ifdef JS_TRACE_LOGGING
if (!emitTracelogStartEvent(TraceLogger::VM))
return false;
#endif
// Stack is:
// ... frame ...
// [args]
@ -667,6 +673,12 @@ CodeGeneratorShared::callVM(const VMFunction &fun, LInstruction *ins, const Regi
masm.implicitPop(fun.explicitStackSlots() * sizeof(void *) + framePop);
// Stack is:
// ... frame ...
#ifdef JS_TRACE_LOGGING
if (!emitTracelogStopEvent(TraceLogger::VM))
return false;
#endif
return true;
}
@ -1028,6 +1040,9 @@ CodeGeneratorShared::emitTracelogScript(bool isStart)
bool
CodeGeneratorShared::emitTracelogTree(bool isStart, uint32_t textId)
{
if (!TraceLogTextIdEnabled(textId))
return true;
RegisterSet regs = RegisterSet::Volatile();
Register logger = regs.takeGeneral();
@ -1037,28 +1052,15 @@ CodeGeneratorShared::emitTracelogTree(bool isStart, uint32_t textId)
if (!patchableTraceLoggers_.append(patchLocation))
return false;
if (isStart)
if (isStart) {
masm.tracelogStart(logger, textId);
else
} else {
#ifdef DEBUG
masm.tracelogStop(logger, textId);
masm.Pop(logger);
return true;
}
bool
CodeGeneratorShared::emitTracelogStopEvent()
{
RegisterSet regs = RegisterSet::Volatile();
Register logger = regs.takeGeneral();
masm.Push(logger);
CodeOffsetLabel patchLocation = masm.movWithPatch(ImmPtr(nullptr), logger);
if (!patchableTraceLoggers_.append(patchLocation))
return false;
masm.tracelogStop(logger);
#else
masm.tracelogStop(logger);
#endif
}
masm.Pop(logger);
return true;

View File

@ -467,13 +467,8 @@ class CodeGeneratorShared : public LInstructionVisitor
return emitTracelogTree(/* isStart =*/ true, textId);
}
bool emitTracelogStopEvent(uint32_t textId) {
#ifdef DEBUG
return emitTracelogTree(/* isStart =*/ false, textId);
#else
return emitTracelogScript(/* isStart =*/ false);
#endif
}
bool emitTracelogStopEvent();
#endif
};

View File

@ -760,6 +760,10 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
IonSpew(IonSpew_Pools, "[%d]***Offset was still out of range!***", id, codeOffset - magicAlign);
IonSpew(IonSpew_Pools, "[%d] Too complicated; bailingp", id);
this->fail_bail();
// only free up to the current offset
for (int pi = poolIdx; pi < numPoolKinds; pi++)
delete[] outcastEntries[pi];
delete[] preservedEntries;
return;
} else {
preservedEntries[idx] = true;
@ -783,12 +787,15 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
}
poolOffset += p->numEntries * p->immSize;
delete[] preservedEntries;
preservedEntries = nullptr;
}
// bind the current pool to the perforation point.
Pool **tmp = &perforatedNode->data;
*tmp = static_cast<Pool*>(this->LifoAlloc_.alloc(sizeof(Pool) * numPoolKinds));
if (tmp == nullptr) {
this->fail_oom();
for (int pi = 0; pi < numPoolKinds; pi++)
delete[] outcastEntries[pi];
return;
}
// The above operations may have changed the size of pools!
@ -804,6 +811,8 @@ struct AssemblerBufferWithConstantPool : public AssemblerBuffer<SliceSize, Inst>
for (int poolIdx = 0; poolIdx < numPoolKinds; poolIdx++) {
if (!pools[poolIdx].reset(this->LifoAlloc_)) {
this->fail_oom();
for (int pi = 0; pi < numPoolKinds; pi++)
delete[] outcastEntries[pi];
return;
}
}

Some files were not shown because too many files have changed in this diff Show More