mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Merge inbound to m-c.
This commit is contained in:
commit
9e685c22d5
2
CLOBBER
2
CLOBBER
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
14
b2g/config/tooltool-manifests/linux32/releng.manifest
Normal file
14
b2g/config/tooltool-manifests/linux32/releng.manifest
Normal file
@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"size": 50,
|
||||
"digest": "48f405d8c2712838b9dd3be118951c8b41c63c891576f5287d2e05afa8fd051a08807511259581aa3170a3c4f7d4e77e6c0539b00b8f6845f01562127f6a27fa",
|
||||
"algorithm": "sha512",
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 160232,
|
||||
"digest": "8656c3fc2daa66839ec81a0edbd9759040a83c7a41c3e472d7f90508b80eefd008b87305dc8549b4ff6098dc33fe17fedc9b4eb76cf5307d5f22dae925c033db",
|
||||
"algorithm": "sha512",
|
||||
"filename": "sccache.tar.xz"
|
||||
}
|
||||
]
|
14
b2g/config/tooltool-manifests/linux64/releng.manifest
Normal file
14
b2g/config/tooltool-manifests/linux64/releng.manifest
Normal file
@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"size": 50,
|
||||
"digest": "48f405d8c2712838b9dd3be118951c8b41c63c891576f5287d2e05afa8fd051a08807511259581aa3170a3c4f7d4e77e6c0539b00b8f6845f01562127f6a27fa",
|
||||
"algorithm": "sha512",
|
||||
"filename": "setup.sh"
|
||||
},
|
||||
{
|
||||
"size": 160232,
|
||||
"digest": "8656c3fc2daa66839ec81a0edbd9759040a83c7a41c3e472d7f90508b80eefd008b87305dc8549b4ff6098dc33fe17fedc9b4eb76cf5307d5f22dae925c033db",
|
||||
"algorithm": "sha512",
|
||||
"filename": "sccache.tar.xz"
|
||||
}
|
||||
]
|
@ -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"
|
||||
}
|
||||
]
|
@ -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;
|
||||
|
@ -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}
|
||||
|
@ -1,4 +1,5 @@
|
||||
no_tooltool=1
|
||||
no_sccache=1
|
||||
|
||||
. $topsrcdir/browser/config/mozconfigs/linux32/nightly
|
||||
|
||||
|
@ -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}
|
||||
|
@ -1,4 +1,5 @@
|
||||
no_tooltool=1
|
||||
no_sccache=1
|
||||
|
||||
. $topsrcdir/browser/config/mozconfigs/linux64/nightly
|
||||
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -11,7 +11,6 @@ XPIDL_SOURCES += [
|
||||
XPIDL_MODULE = 'content_canvas'
|
||||
|
||||
EXPORTS += [
|
||||
'nsICanvasElementExternal.h',
|
||||
'nsICanvasRenderingContextInternal.h',
|
||||
]
|
||||
|
||||
|
@ -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___ */
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -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>
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -3154,6 +3154,7 @@ static nsIAtom** sPropertiesToTraverseAndUnlink[] =
|
||||
&nsGkAtoms::itemref,
|
||||
&nsGkAtoms::itemprop,
|
||||
&nsGkAtoms::sandbox,
|
||||
&nsGkAtoms::sizes,
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
@ -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]
|
||||
|
35
content/html/content/test/test_link_sizes.html
Normal file
35
content/html/content/test/test_link_sizes.html
Normal 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>
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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 =
|
||||
|
@ -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] = {
|
||||
|
@ -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
|
||||
|
@ -323,10 +323,8 @@ MediaPluginHost *GetMediaPluginHost()
|
||||
|
||||
void MediaPluginHost::Shutdown()
|
||||
{
|
||||
if (sMediaPluginHost) {
|
||||
delete sMediaPluginHost;
|
||||
sMediaPluginHost = nullptr;
|
||||
}
|
||||
delete sMediaPluginHost;
|
||||
sMediaPluginHost = nullptr;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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:
|
||||
/**
|
||||
|
@ -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');
|
||||
};
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
@ -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"
|
@ -12,7 +12,7 @@
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
namespace layers {
|
||||
|
||||
bool
|
||||
APZCCallbackHelper::HasValidPresShellId(nsIDOMWindowUtils* aUtils,
|
@ -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 */
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -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 */
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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*
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
||||
|
5
js/src/jit-test/tests/ion/bug995675.js
Normal file
5
js/src/jit-test/tests/ion/bug995675.js
Normal file
@ -0,0 +1,5 @@
|
||||
function f(x) {
|
||||
return Math.cos(~(~Math.pow(Number.MAX_VALUE, x)))
|
||||
}
|
||||
f(-0)
|
||||
assertEq(f(undefined - undefined), 1)
|
5
js/src/jit-test/tests/ion/bug995826.js
Normal file
5
js/src/jit-test/tests/ion/bug995826.js
Normal file
@ -0,0 +1,5 @@
|
||||
function f(x) {
|
||||
return Math.round(-Math.tan(x > 0))
|
||||
}
|
||||
f(2)
|
||||
assertEq(f(-1), -0);
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user