This commit is contained in:
Ryan VanderMeulen 2014-05-13 16:27:03 -04:00
Родитель d501d6fc90 2bf68f16b6
Коммит d76da7eade
103 изменённых файлов: 1525 добавлений и 874 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -7891,15 +7891,15 @@ else
fi
AC_SUBST(CL_INCLUDES_PREFIX)
rm -f dummy-hello.c
dnl Make sure that the build system can handle non-ASCII characters
dnl in environment variables to prevent it from breaking silently on
dnl non-English systems.
NONASCII=$'\241\241'
AC_SUBST(NONASCII)
fi
fi
dnl Make sure that the build system can handle non-ASCII characters
dnl in environment variables to prevent it from breking silently on
dnl non-English systems.
NONASCII=$'\241\241'
AC_SUBST(NONASCII)
dnl ========================================================
dnl =
dnl = Static Build Options

Просмотреть файл

@ -92,6 +92,7 @@ class ImageLoader;
} // namespace css
namespace dom {
class AnimationTimeline;
class Attr;
class CDATASection;
class Comment;
@ -1859,6 +1860,8 @@ public:
virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager() = 0;
virtual mozilla::dom::AnimationTimeline* Timeline() = 0;
typedef mozilla::dom::CallbackObjectHolder<
mozilla::dom::FrameRequestCallback,
nsIFrameRequestCallback> FrameRequestCallbackHolder;

Просмотреть файл

@ -191,6 +191,7 @@
#include "nsWrapperCacheInlines.h"
#include "nsSandboxFlags.h"
#include "nsIAppsService.h"
#include "mozilla/dom/AnimationTimeline.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/Event.h"
@ -1961,6 +1962,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedEncoder)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStateObjectCached)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUndoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnimationTimeline)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTemplateContentsOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildrenCollection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRegistry)
@ -2030,6 +2032,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCachedEncoder)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mUndoManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnimationTimeline)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTemplateContentsOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRegistry)
@ -3131,6 +3134,16 @@ nsDocument::GetUndoManager()
return undoManager.forget();
}
AnimationTimeline*
nsDocument::Timeline()
{
if (!mAnimationTimeline) {
mAnimationTimeline = new AnimationTimeline(this);
}
return mAnimationTimeline;
}
/* Return true if the document is in the focused top-level window, and is an
* ancestor of the focused DOMWindow. */
NS_IMETHODIMP
@ -12130,8 +12143,9 @@ nsIDocument::WrapObject(JSContext *aCx)
}
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(GetInnerWindow());
if (!win) {
// No window, nothing else to do here
if (!win ||
static_cast<nsGlobalWindow*>(win.get())->IsDOMBinding()) {
// No window or window on new DOM binding, nothing else to do here.
return obj;
}

Просмотреть файл

@ -770,6 +770,8 @@ public:
virtual already_AddRefed<mozilla::dom::UndoManager> GetUndoManager() MOZ_OVERRIDE;
virtual mozilla::dom::AnimationTimeline* Timeline() MOZ_OVERRIDE;
virtual nsresult SetSubDocumentFor(Element* aContent,
nsIDocument* aSubDoc) MOZ_OVERRIDE;
virtual nsIDocument* GetSubDocumentFor(nsIContent* aContent) const MOZ_OVERRIDE;
@ -1635,6 +1637,8 @@ private:
nsRefPtr<mozilla::dom::UndoManager> mUndoManager;
nsRefPtr<mozilla::dom::AnimationTimeline> mAnimationTimeline;
enum ViewportType {
DisplayWidthHeight,
DisplayWidthHeightNoZoom,

Просмотреть файл

@ -1337,10 +1337,10 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
if (!gl)
return nullptr;
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
gfxImageFormat::ARGB32,
mWidth * 4, 0, false);
if (surf->CairoStatus() != 0) {
RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurfaceWithStride(IntSize(mWidth, mHeight),
SurfaceFormat::B8G8R8A8,
mWidth * 4);
if (!surf) {
return nullptr;
}
@ -1348,7 +1348,7 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
{
ScopedBindFramebuffer autoFB(gl, 0);
ClearBackbufferIfNeeded();
ReadPixelsIntoImageSurface(gl, surf);
ReadPixelsIntoDataSurface(gl, surf);
}
if (aPremultAlpha) {
@ -1359,8 +1359,7 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
if (aPremultAlpha) {
*aPremultAlpha = false;
} else {
gfxUtils::PremultiplyImageSurface(surf);
surf->MarkDirty();
gfxUtils::PremultiplyDataSurface(surf);
}
}
@ -1373,14 +1372,12 @@ WebGLContext::GetSurfaceSnapshot(bool* aPremultAlpha)
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,
dt->DrawSurface(surf,
Rect(0, 0, mWidth, mHeight),
Rect(0, 0, mWidth, mHeight),
DrawSurfaceOptions(),

Просмотреть файл

@ -7,6 +7,7 @@
#include "AudioNodeExternalInputStream.h"
#include "AudioChannelFormat.h"
#include "speex/speex_resampler.h"
#include "mozilla/dom/MediaStreamAudioSourceNode.h"
using namespace mozilla::dom;
@ -324,7 +325,7 @@ AudioNodeExternalInputStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
// GC stuff can result in our input stream being destroyed before this stream.
// Handle that.
if (mInputs.IsEmpty()) {
if (!IsEnabled() || mInputs.IsEmpty()) {
mLastChunks[0].SetNull(WEBAUDIO_BLOCK_SIZE);
AdvanceOutputSegment();
return;
@ -452,4 +453,10 @@ AudioNodeExternalInputStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
AdvanceOutputSegment();
}
bool
AudioNodeExternalInputStream::IsEnabled()
{
return ((MediaStreamAudioSourceNodeEngine*)Engine())->IsEnabled();
}
}

Просмотреть файл

@ -8,6 +8,7 @@
#include "MediaStreamGraph.h"
#include "AudioNodeStream.h"
#include "mozilla/Atomics.h"
// Forward declaration for mResamplerMap
typedef struct SpeexResamplerState_ SpeexResamplerState;
@ -94,6 +95,13 @@ private:
*/
size_t GetTrackMapEntry(const StreamBuffer::Track& aTrack,
GraphTime aFrom);
/**
* Determines if this is enabled or not. Disabled nodes produce silence.
* This node becomes disabled if the document principal does not subsume the
* DOMMediaStream principal.
*/
bool IsEnabled();
};
}

Просмотреть файл

@ -250,7 +250,40 @@ DOMMediaStream::SetTrackEnabled(TrackID aTrackID, bool aEnabled)
bool
DOMMediaStream::CombineWithPrincipal(nsIPrincipal* aPrincipal)
{
return nsContentUtils::CombineResourcePrincipals(&mPrincipal, aPrincipal);
bool changed =
nsContentUtils::CombineResourcePrincipals(&mPrincipal, aPrincipal);
if (changed) {
NotifyPrincipalChanged();
}
return changed;
}
void
DOMMediaStream::SetPrincipal(nsIPrincipal* aPrincipal)
{
mPrincipal = aPrincipal;
NotifyPrincipalChanged();
}
void
DOMMediaStream::NotifyPrincipalChanged()
{
for (uint32_t i = 0; i < mPrincipalChangeObservers.Length(); ++i) {
mPrincipalChangeObservers[i]->PrincipalChanged(this);
}
}
bool
DOMMediaStream::AddPrincipalChangeObserver(PrincipalChangeObserver* aObserver)
{
return mPrincipalChangeObservers.AppendElement(aObserver) != nullptr;
}
bool
DOMMediaStream::RemovePrincipalChangeObserver(PrincipalChangeObserver* aObserver)
{
return mPrincipalChangeObservers.RemoveElement(aObserver);
}
MediaStreamTrack*

Просмотреть файл

@ -120,7 +120,19 @@ public:
* one where the stream is accessible to script. Don't call this.
* CombineWithPrincipal is almost certainly more appropriate.
*/
void SetPrincipal(nsIPrincipal* aPrincipal) { mPrincipal = aPrincipal; }
void SetPrincipal(nsIPrincipal* aPrincipal);
/**
* Used to learn about dynamic changes in principal occur.
* Operations relating to these observers must be confined to the main thread.
*/
class PrincipalChangeObserver
{
public:
virtual void PrincipalChanged(DOMMediaStream* aMediaStream) = 0;
};
bool AddPrincipalChangeObserver(PrincipalChangeObserver* aObserver);
bool RemovePrincipalChangeObserver(PrincipalChangeObserver* aObserver);
/**
* Called when this stream's MediaStreamGraph has been shut down. Normally
@ -216,12 +228,6 @@ protected:
// MediaStream is owned by the graph, but we tell it when to die, and it won't
// die until we let it.
MediaStream* mStream;
// Principal identifying who may access the contents of this stream.
// If null, this stream can be used by anyone because it has no content yet.
nsCOMPtr<nsIPrincipal> mPrincipal;
// this is used in gUM and WebRTC to identify peers that this stream
// is allowed to be sent to
nsAutoPtr<PeerIdentity> mPeerIdentity;
nsAutoTArray<nsRefPtr<MediaStreamTrack>,2> mTracks;
nsRefPtr<StreamListener> mListener;
@ -236,6 +242,17 @@ protected:
// Indicate what track types have been added to this stream
uint8_t mTrackTypesAvailable;
bool mNotifiedOfMediaStreamGraphShutdown;
private:
void NotifyPrincipalChanged();
// Principal identifying who may access the contents of this stream.
// If null, this stream can be used by anyone because it has no content yet.
nsCOMPtr<nsIPrincipal> mPrincipal;
nsTArray<PrincipalChangeObserver*> mPrincipalChangeObservers;
// this is used in gUM and WebRTC to identify peers that this stream
// is allowed to be sent to
nsAutoPtr<PeerIdentity> mPeerIdentity;
};
class DOMLocalMediaStream : public DOMMediaStream,

Просмотреть файл

@ -1019,8 +1019,13 @@ void MediaDecoder::NotifyPrincipalChanged()
void MediaDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
{
MOZ_ASSERT(NS_IsMainThread());
if (mShuttingDown) {
return;
}
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
NS_ENSURE_TRUE_VOID(mDecoderStateMachine);
MOZ_ASSERT(mDecoderStateMachine);
if (mIgnoreProgressData) {
return;
}

Просмотреть файл

@ -292,7 +292,7 @@ protected:
TrackTicks aStart, TrackTicks aEnd)
{
MOZ_ASSERT(aStart <= aEnd, "Endpoints inverted");
MOZ_ASSERT(aStart >= 0 && aEnd <= aSource.mDuration, "Slice out of range");
NS_WARN_IF_FALSE(aStart >= 0 && aEnd <= aSource.mDuration, "Slice out of range");
mDuration += aEnd - aStart;
TrackTicks offset = 0;
for (uint32_t i = 0; i < aSource.mChunks.Length() && offset < aEnd; ++i) {

Просмотреть файл

@ -8,7 +8,7 @@
#include "mozilla/dom/MediaStreamAudioSourceNodeBinding.h"
#include "AudioNodeEngine.h"
#include "AudioNodeExternalInputStream.h"
#include "DOMMediaStream.h"
#include "nsIDocument.h"
namespace mozilla {
namespace dom {
@ -37,16 +37,52 @@ MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* aContext,
ChannelInterpretation::Speakers),
mInputStream(aMediaStream)
{
AudioNodeEngine* engine = new AudioNodeEngine(this);
AudioNodeEngine* engine = new MediaStreamAudioSourceNodeEngine(this);
mStream = aContext->Graph()->CreateAudioNodeExternalInputStream(engine);
ProcessedMediaStream* outputStream = static_cast<ProcessedMediaStream*>(mStream.get());
mInputPort = outputStream->AllocateInputPort(aMediaStream->GetStream(),
MediaInputPort::FLAG_BLOCK_INPUT);
mInputStream->AddConsumerToKeepAlive(this);
PrincipalChanged(mInputStream); // trigger enabling/disabling of the connector
mInputStream->AddPrincipalChangeObserver(this);
}
MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode()
{
if (mInputStream) {
mInputStream->RemovePrincipalChangeObserver(this);
}
}
/**
* Changes the principal. Note that this will be called on the main thread, but
* changes will be enacted on the MediaStreamGraph thread. If the principal
* change results in the document principal losing access to the stream, then
* there needs to be other measures in place to ensure that any media that is
* governed by the new stream principal is not available to the Media Stream
* Graph before this change completes. Otherwise, a site could get access to
* media that they are not authorized to receive.
*
* One solution is to block the altered content, call this method, then dispatch
* another change request to the MediaStreamGraph thread that allows the content
* under the new principal to flow. This might be unnecessary if the principal
* change is changing to be the document principal.
*/
void
MediaStreamAudioSourceNode::PrincipalChanged(DOMMediaStream* ms)
{
bool subsumes = false;
nsIDocument* doc = Context()->GetParentObject()->GetExtantDoc();
if (doc) {
nsIPrincipal* docPrincipal = doc->NodePrincipal();
nsIPrincipal* streamPrincipal = mInputStream->GetPrincipal();
if (NS_FAILED(docPrincipal->Subsumes(streamPrincipal, &subsumes))) {
subsumes = false;
}
}
auto stream = static_cast<AudioNodeExternalInputStream*>(mStream.get());
stream->SetInt32Parameter(MediaStreamAudioSourceNodeEngine::ENABLE, subsumes);
}
size_t
@ -83,4 +119,3 @@ MediaStreamAudioSourceNode::WrapObject(JSContext* aCx)
}
}

Просмотреть файл

@ -8,18 +8,42 @@
#define MediaStreamAudioSourceNode_h_
#include "AudioNode.h"
#include "DOMMediaStream.h"
#include "AudioNodeEngine.h"
namespace mozilla {
class DOMMediaStream;
namespace dom {
class MediaStreamAudioSourceNode : public AudioNode
class MediaStreamAudioSourceNodeEngine : public AudioNodeEngine
{
public:
MediaStreamAudioSourceNodeEngine(AudioNode* aNode)
: AudioNodeEngine(aNode), mEnabled(false) {}
bool IsEnabled() const { return mEnabled; }
enum Parameters {
ENABLE
};
virtual void SetInt32Parameter(uint32_t aIndex, int32_t aValue) MOZ_OVERRIDE
{
switch (aIndex) {
case ENABLE:
mEnabled = !!aValue;
break;
default:
NS_ERROR("MediaStreamAudioSourceNodeEngine bad parameter index");
}
}
private:
bool mEnabled;
};
class MediaStreamAudioSourceNode : public AudioNode,
public DOMMediaStream::PrincipalChangeObserver
{
public:
MediaStreamAudioSourceNode(AudioContext* aContext, DOMMediaStream* aMediaStream);
// Define constructor out-of-line so we can forward-declare DOMMediaStream
virtual ~MediaStreamAudioSourceNode();
NS_DECL_ISUPPORTS_INHERITED
@ -39,6 +63,8 @@ public:
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
virtual void PrincipalChanged(DOMMediaStream* aMediaStream) MOZ_OVERRIDE;
private:
nsRefPtr<MediaInputPort> mInputPort;
nsRefPtr<DOMMediaStream> mInputStream;

Просмотреть файл

@ -0,0 +1,52 @@
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AnimationTimeline.h"
#include "mozilla/dom/AnimationTimelineBinding.h"
#include "nsContentUtils.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsRefreshDriver.h"
#include "nsDOMNavigationTiming.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationTimeline, mDocument)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationTimeline, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationTimeline, Release)
JSObject*
AnimationTimeline::WrapObject(JSContext* aCx)
{
return AnimationTimelineBinding::Wrap(aCx, this);
}
Nullable<double>
AnimationTimeline::GetCurrentTime() const
{
Nullable<double> result; // Default ctor initializes to null
nsIPresShell* presShell = mDocument->GetShell();
if (!presShell)
return result;
nsPresContext* presContext = presShell->GetPresContext();
if (!presContext)
return result;
nsRefPtr<nsDOMNavigationTiming> timing = mDocument->GetNavigationTiming();
if (!timing)
return result;
TimeStamp now = presContext->RefreshDriver()->MostRecentRefresh();
result.SetValue(timing->TimeStampToDOMHighRes(now));
return result;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,46 @@
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_AnimationTimeline_h
#define mozilla_dom_AnimationTimeline_h
#include "nsWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h"
#include "js/TypeDecls.h"
#include "nsIDocument.h"
struct JSContext;
namespace mozilla {
namespace dom {
class AnimationTimeline MOZ_FINAL : public nsWrapperCache
{
public:
AnimationTimeline(nsIDocument* aDocument)
: mDocument(aDocument)
{
SetIsDOMBinding();
}
virtual ~AnimationTimeline() { }
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationTimeline)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationTimeline)
nsISupports* GetParentObject() const { return mDocument; }
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
Nullable<double> GetCurrentTime() const;
protected:
nsCOMPtr<nsIDocument> mDocument;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_AnimationTimeline_h

19
dom/animation/moz.build Normal file
Просмотреть файл

@ -0,0 +1,19 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
EXPORTS.mozilla.dom += [
'AnimationTimeline.h',
]
SOURCES += [
'AnimationTimeline.cpp',
]
FAIL_ON_WARNINGS = True
FINAL_LIBRARY = 'gklayout'

Просмотреть файл

@ -0,0 +1,105 @@
<!doctype html>
<meta charset=utf-8>
<title>Web Animations API: AnimationTimeline tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/WebIDLParser.js"></script>
<script src="/resources/idlharness.js"></script>
<div id="log"></div>
<iframe src="data:text/html;charset=utf-8," width="10" height="10" id="iframe"></iframe>
<script type="text/plain" id="AnimationTimeline-IDL">
interface AnimationTimeline {
readonly attribute double? currentTime;
};
</script>
<script>
'use strict';
var idlArray;
test(function() {
idlArray = new IdlArray();
idlArray.add_idls(
document.getElementById('AnimationTimeline-IDL').textContent);
idlArray.add_objects( { AnimationTimeline: ['document.timeline'] } );
});
idlArray.test();
test(function() {
assert_equals(document.timeline, document.timeline,
'document.timeline returns the same object every time');
var iframe = document.getElementById('iframe');
assert_not_equals(document.timeline, iframe.contentDocument.timeline,
'document.timeline returns a different object for each document');
assert_not_equals(iframe.contentDocument.timeline, null,
'document.timeline on an iframe is not null');
},
'document.timeline identity tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#the-document-timeline',
assert: [ 'Each document has a timeline called the document timeline' ],
author: 'Brian Birtles'
});
async_test(function(t) {
assert_true(document.timeline.currentTime > 0,
'document.timeline.currentTime is positive');
// document.timeline.currentTime should be set even before document
// load fires. We expect this code to be run before document load and hence
// the above assertion is sufficient.
// If the following assertion fails, this test needs to be redesigned.
assert_true(document.readyState !== 'complete',
'Test is running prior to document load');
// Test that the document timeline's current time is measured from
// navigationStart.
//
// We can't just compare document.timeline.currentTime to
// window.performance.now() because currentTime is only updated on a sample
// so we use requestAnimationFrame instead.
window.requestAnimationFrame(t.step_func(function(rafTime) {
assert_equals(document.timeline.currentTime, rafTime,
'document.timeline.currentTime matches' +
' requestAnimationFrame time');
t.done();
}));
},
'document.timeline.currentTime value tests',
{
help: [
'http://dev.w3.org/fxtf/web-animations/#the-global-clock',
'http://dev.w3.org/fxtf/web-animations/#the-document-timeline'
],
assert: [
'The global clock is a source of monotonically increasing time values',
'The time values of the document timeline are calculated as a fixed' +
' offset from the global clock',
'the zero time corresponds to the navigationStart moment',
'the time value of each document timeline must be equal to the time ' +
'passed to animation frame request callbacks for that browsing context'
],
author: 'Brian Birtles'
});
async_test(function(t) {
var valueAtStart = document.timeline.currentTime;
var timeAtStart = window.performance.now();
while (window.performance.now() - timeAtStart < 100) {
// Wait 100ms
}
assert_equals(document.timeline.currentTime, valueAtStart,
'document.timeline.currentTime does not change within a script block');
window.requestAnimationFrame(t.step_func(function() {
assert_true(document.timeline.currentTime > valueAtStart,
'document.timeline.currentTime increases between script blocks');
t.done();
}));
},
'document.timeline.currentTime liveness tests',
{
help: 'http://dev.w3.org/fxtf/web-animations/#script-execution-and-live-updates-to-the-model',
assert: [ 'The value returned by the currentTime attribute of a' +
' document timeline will not change within a script block' ],
author: 'Brian Birtles'
});
</script>

Просмотреть файл

@ -0,0 +1 @@
[animation-timeline/test_animation-timeline.html]

Просмотреть файл

@ -1797,8 +1797,17 @@ nsWindowSH::PostCreate(nsIXPConnectWrappedNative *wrapper,
const NativeProperties* eventTargetProperties =
EventTargetBinding::sNativePropertyHooks->mNativeProperties.regular;
return DefineWebIDLBindingPropertiesOnXPCObject(cx, window, windowProperties, true) &&
DefineWebIDLBindingPropertiesOnXPCObject(cx, window, eventTargetProperties, true) ?
if (!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, windowProperties) ||
!DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(cx, window, eventTargetProperties)) {
return NS_ERROR_FAILURE;
}
if (!GlobalPropertiesAreOwn()) {
return NS_OK;
}
return DefineWebIDLBindingPropertiesOnXPCObject(cx, window, windowProperties) &&
DefineWebIDLBindingPropertiesOnXPCObject(cx, window, eventTargetProperties) ?
NS_OK : NS_ERROR_FAILURE;
}

Просмотреть файл

@ -36,6 +36,7 @@
#include "nsIController.h"
#include "nsScriptNameSpaceManager.h"
#include "nsWindowMemoryReporter.h"
#include "WindowNamedPropertiesHandler.h"
// Helper Classes
#include "nsJSUtils.h"
@ -1119,6 +1120,11 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
// Initialize the PRCList (this).
PR_INIT_CLIST(this);
if (Preferences::GetBool("dom.window_experimental_bindings") ||
!aOuterWindow) {
SetIsDOMBinding();
}
if (aOuterWindow) {
// |this| is an inner window, add this inner window to the outer
// window list of inners.
@ -1148,7 +1154,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
Freeze();
mObserver = nullptr;
SetIsDOMBinding();
}
// We could have failed the first time through trying
@ -1950,8 +1955,7 @@ nsGlobalWindow::TraceGlobalJSObject(JSTracer* aTrc)
JSObject*
nsGlobalWindow::OuterObject(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
nsGlobalWindow* origWin;
UNWRAP_OBJECT(Window, aObj, origWin);
nsGlobalWindow* origWin = UnwrapDOMObject<nsGlobalWindow>(aObj);
nsGlobalWindow* win = origWin->GetOuterWindowInternal();
if (!win) {
@ -1961,6 +1965,7 @@ nsGlobalWindow::OuterObject(JSContext* aCx, JS::Handle<JSObject*> aObj)
// null to prevent leaking an inner window to code in a different
// window.
NS_WARNING("nsGlobalWindow::OuterObject shouldn't fail!");
Throw(aCx, NS_ERROR_UNEXPECTED);
return nullptr;
}
@ -1973,6 +1978,7 @@ nsGlobalWindow::OuterObject(JSContext* aCx, JS::Handle<JSObject*> aObj)
// need to wrap here.
if (!JS_WrapObject(aCx, &winObj)) {
NS_WARNING("nsGlobalWindow::OuterObject shouldn't fail!");
Throw(aCx, NS_ERROR_UNEXPECTED);
return nullptr;
}
@ -2208,26 +2214,34 @@ CreateNativeGlobalForInner(JSContext* aCx,
}
}
nsIXPConnect* xpc = nsContentUtils::XPConnect();
// Determine if we need the Components object.
bool needComponents = nsContentUtils::IsSystemPrincipal(aPrincipal) ||
TreatAsRemoteXUL(aPrincipal);
uint32_t flags = needComponents ? 0 : nsIXPConnect::OMIT_COMPONENTS_OBJECT;
flags |= nsIXPConnect::DONT_FIRE_ONNEWGLOBALHOOK;
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
aCx, ToSupports(aNewInner),
aPrincipal, flags, options, getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);
if (aNewInner->IsDOMBinding()) {
aGlobal.set(WindowBinding::Wrap(aCx, aNewInner, aNewInner, options,
nsJSPrincipals::get(aPrincipal), false));
if (!aGlobal || !xpc::InitGlobalObject(aCx, aGlobal, flags)) {
return NS_ERROR_FAILURE;
}
} else {
nsIXPConnect* xpc = nsContentUtils::XPConnect();
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
aCx, ToSupports(aNewInner),
aPrincipal, flags, options, getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);
aGlobal.set(holder->GetJSObject());
MOZ_ASSERT(aGlobal);
}
aGlobal.set(holder->GetJSObject());
MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
// Set the location information for the new global, so that tools like
// about:memory may use that information
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(aNewInner->GetWrapperPreserveColor() == aGlobal);
xpc::SetLocationForGlobal(aGlobal, aURI);
return NS_OK;
@ -2536,14 +2550,21 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// If we created a new inner window above, we need to do the last little bit
// of initialization now that the dust has settled.
if (createdInnerWindow) {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
nsresult rv = xpc->GetWrappedNativeOfJSObject(cx, newInnerGlobal,
getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);
NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
rv = wrapper->FinishInitForWrappedGlobal();
NS_ENSURE_SUCCESS(rv, rv);
if (newInnerWindow->IsDOMBinding()) {
JS::Rooted<JSObject*> global(cx, newInnerGlobal);
JS::Rooted<JSObject*> proto(cx);
JS_GetPrototype(cx, global, &proto);
WindowNamedPropertiesHandler::Install(cx, proto);
} else {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
nsresult rv = xpc->GetWrappedNativeOfJSObject(cx, newInnerGlobal,
getter_AddRefs(wrapper));
NS_ENSURE_SUCCESS(rv, rv);
NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
rv = wrapper->FinishInitForWrappedGlobal();
NS_ENSURE_SUCCESS(rv, rv);
}
}
if (!aState) {

Просмотреть файл

@ -543,11 +543,23 @@ CreateInterfaceObject(JSContext* cx, JS::Handle<JSObject*> global,
return constructor;
}
bool
DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties)
{
if (properties->unforgeableAttributes &&
!DefinePrefable(cx, obj, properties->unforgeableAttributes)) {
return false;
}
return true;
}
bool
DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties,
bool defineUnforgeableAttributes)
const NativeProperties* properties)
{
if (properties->methods &&
!DefinePrefable(cx, obj, properties->methods)) {
@ -559,11 +571,6 @@ DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
return false;
}
if (defineUnforgeableAttributes && properties->unforgeableAttributes &&
!DefinePrefable(cx, obj, properties->unforgeableAttributes)) {
return false;
}
return true;
}
@ -576,45 +583,54 @@ CreateInterfacePrototypeObject(JSContext* cx, JS::Handle<JSObject*> global,
{
JS::Rooted<JSObject*> ourProto(cx,
JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global));
if (!ourProto) {
if (!ourProto ||
!DefineProperties(cx, ourProto, properties, chromeOnlyProperties)) {
return nullptr;
}
return ourProto;
}
bool
DefineProperties(JSContext* cx, JS::Handle<JSObject*> obj,
const NativeProperties* properties,
const NativeProperties* chromeOnlyProperties)
{
if (properties) {
if (properties->methods &&
!DefinePrefable(cx, ourProto, properties->methods)) {
return nullptr;
!DefinePrefable(cx, obj, properties->methods)) {
return false;
}
if (properties->attributes &&
!DefinePrefable(cx, ourProto, properties->attributes)) {
return nullptr;
!DefinePrefable(cx, obj, properties->attributes)) {
return false;
}
if (properties->constants &&
!DefinePrefable(cx, ourProto, properties->constants)) {
return nullptr;
!DefinePrefable(cx, obj, properties->constants)) {
return false;
}
}
if (chromeOnlyProperties) {
if (chromeOnlyProperties->methods &&
!DefinePrefable(cx, ourProto, chromeOnlyProperties->methods)) {
return nullptr;
!DefinePrefable(cx, obj, chromeOnlyProperties->methods)) {
return false;
}
if (chromeOnlyProperties->attributes &&
!DefinePrefable(cx, ourProto, chromeOnlyProperties->attributes)) {
return nullptr;
!DefinePrefable(cx, obj, chromeOnlyProperties->attributes)) {
return false;
}
if (chromeOnlyProperties->constants &&
!DefinePrefable(cx, ourProto, chromeOnlyProperties->constants)) {
return nullptr;
!DefinePrefable(cx, obj, chromeOnlyProperties->constants)) {
return false;
}
}
return ourProto;
return true;
}
void
@ -2181,12 +2197,15 @@ IsInCertifiedApp(JSContext* aCx, JSObject* aObj)
Preferences::GetBool("dom.ignore_webidl_scope_checks", false);
}
#ifdef DEBUG
void
TraceGlobal(JSTracer* aTrc, JSObject* aObj)
VerifyTraceProtoAndIfaceCacheCalled(JSTracer *trc, void **thingp,
JSGCTraceKind kind)
{
MOZ_ASSERT(js::GetObjectClass(aObj)->flags & JSCLASS_DOM_GLOBAL);
mozilla::dom::TraceProtoAndIfaceCache(aTrc, aObj);
// We don't do anything here, we only want to verify that
// TraceProtoAndIfaceCache was called.
}
#endif
void
FinalizeGlobal(JSFreeOp* aFreeOp, JSObject* aObj)
@ -2394,5 +2413,21 @@ ConvertExceptionToPromise(JSContext* cx,
return WrapNewBindingObject(cx, promise, rval);
}
/* static */
void
CreateGlobalOptions<nsGlobalWindow>::TraceGlobal(JSTracer* aTrc, JSObject* aObj)
{
mozilla::dom::TraceProtoAndIfaceCache(aTrc, aObj);
xpc::GetCompartmentPrivate(aObj)->scope->TraceSelf(aTrc);
}
/* static */
bool
CreateGlobalOptions<nsGlobalWindow>::PostCreateGlobal(JSContext* aCx,
JS::Handle<JSObject*> aGlobal)
{
return XPCWrappedNativeScope::GetNewOrUsed(aCx, aGlobal);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -483,11 +483,35 @@ AllocateProtoAndIfaceCache(JSObject* obj, ProtoAndIfaceCache::Kind aKind)
JS::PrivateValue(protoAndIfaceCache));
}
#ifdef DEBUG
void
VerifyTraceProtoAndIfaceCacheCalled(JSTracer *trc, void **thingp,
JSGCTraceKind kind);
struct VerifyTraceProtoAndIfaceCacheCalledTracer : public JSTracer
{
bool ok;
VerifyTraceProtoAndIfaceCacheCalledTracer(JSRuntime *rt)
: JSTracer(rt, VerifyTraceProtoAndIfaceCacheCalled), ok(false)
{}
};
#endif
inline void
TraceProtoAndIfaceCache(JSTracer* trc, JSObject* obj)
{
MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
#ifdef DEBUG
if (trc->callback == VerifyTraceProtoAndIfaceCacheCalled) {
// We don't do anything here, we only want to verify that
// TraceProtoAndIfaceCache was called.
static_cast<VerifyTraceProtoAndIfaceCacheCalledTracer*>(trc)->ok = true;
return;
}
#endif
if (!HasProtoAndIfaceCache(obj))
return;
ProtoAndIfaceCache* protoAndIfaceCache = GetProtoAndIfaceCache(obj);
@ -581,6 +605,24 @@ CreateInterfaceObjects(JSContext* cx, JS::Handle<JSObject*> global,
const NativeProperties* chromeOnlyProperties,
const char* name, bool defineOnGlobal);
/**
* Define the properties (regular and chrome-only) on obj.
*
* obj the object to instal the properties on. This should be the interface
* prototype object for regular interfaces and the instance object for
* interfaces marked with Global.
* properties contains the methods, attributes and constants to be defined on
* objects in any compartment.
* chromeProperties contains the methods, attributes and constants to be defined
* on objects in chrome compartments. This must be null if the
* interface doesn't have any ChromeOnly properties or if the
* object is being created in non-chrome compartment.
*/
bool
DefineProperties(JSContext* cx, JS::Handle<JSObject*> obj,
const NativeProperties* properties,
const NativeProperties* chromeOnlyProperties);
/*
* Define the unforgeable attributes on an object.
*/
@ -588,11 +630,15 @@ bool
DefineUnforgeableAttributes(JSContext* cx, JS::Handle<JSObject*> obj,
const Prefable<const JSPropertySpec>* props);
bool
DefineWebIDLBindingUnforgeablePropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties);
bool
DefineWebIDLBindingPropertiesOnXPCObject(JSContext* cx,
JS::Handle<JSObject*> obj,
const NativeProperties* properties,
bool defineUnforgeableAttributes);
const NativeProperties* properties);
#ifdef _MSC_VER
#define HAS_MEMBER_CHECK(_name) \
@ -2540,9 +2586,6 @@ IsInPrivilegedApp(JSContext* aCx, JSObject* aObj);
bool
IsInCertifiedApp(JSContext* aCx, JSObject* aObj);
void
TraceGlobal(JSTracer* aTrc, JSObject* aObj);
void
FinalizeGlobal(JSFreeOp* aFop, JSObject* aObj);
@ -2553,55 +2596,86 @@ ResolveGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj,
bool
EnumerateGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj);
template <class T, JS::Handle<JSObject*> (*ProtoGetter)(JSContext*,
JS::Handle<JSObject*>)>
JSObject*
CreateGlobal(JSContext* aCx, T* aObject, nsWrapperCache* aCache,
const JSClass* aClass, JS::CompartmentOptions& aOptions,
JSPrincipals* aPrincipal)
template <class T>
struct CreateGlobalOptions
{
MOZ_ASSERT(!NS_IsMainThread());
static MOZ_CONSTEXPR_VAR ProtoAndIfaceCache::Kind ProtoAndIfaceCacheKind =
ProtoAndIfaceCache::NonWindowLike;
// Intl API is broken and makes JS_InitStandardClasses fail intermittently,
// see bug 934889.
static MOZ_CONSTEXPR_VAR bool ForceInitStandardClassesToFalse = true;
static void TraceGlobal(JSTracer* aTrc, JSObject* aObj)
{
mozilla::dom::TraceProtoAndIfaceCache(aTrc, aObj);
}
static bool PostCreateGlobal(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
{
MOZ_ALWAYS_TRUE(TryPreserveWrapper(aGlobal));
aOptions.setTrace(TraceGlobal);
return true;
}
};
JS::Rooted<JSObject*> global(aCx,
JS_NewGlobalObject(aCx, aClass, aPrincipal, JS::DontFireOnNewGlobalHook,
aOptions));
if (!global) {
template <>
struct CreateGlobalOptions<nsGlobalWindow>
{
static MOZ_CONSTEXPR_VAR ProtoAndIfaceCache::Kind ProtoAndIfaceCacheKind =
ProtoAndIfaceCache::WindowLike;
static MOZ_CONSTEXPR_VAR bool ForceInitStandardClassesToFalse = false;
static void TraceGlobal(JSTracer* aTrc, JSObject* aObj);
static bool PostCreateGlobal(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
};
template <class T, ProtoGetter GetProto>
bool
CreateGlobal(JSContext* aCx, T* aNative, nsWrapperCache* aCache,
const JSClass* aClass, JS::CompartmentOptions& aOptions,
JSPrincipals* aPrincipal, bool aInitStandardClasses,
JS::MutableHandle<JSObject*> aGlobal)
{
aOptions.setTrace(CreateGlobalOptions<T>::TraceGlobal);
aGlobal.set(JS_NewGlobalObject(aCx, aClass, aPrincipal,
JS::DontFireOnNewGlobalHook, aOptions));
if (!aGlobal) {
NS_WARNING("Failed to create global");
return nullptr;
}
JSAutoCompartment ac(aCx, global);
JSAutoCompartment ac(aCx, aGlobal);
dom::AllocateProtoAndIfaceCache(global, ProtoAndIfaceCache::WindowLike);
{
JS::AutoAssertNoGC nogc;
js::SetReservedSlot(global, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aObject));
NS_ADDREF(aObject);
// The setup of our global needs to be done before a GC happens.
js::SetReservedSlot(aGlobal, DOM_OBJECT_SLOT, PRIVATE_TO_JSVAL(aNative));
NS_ADDREF(aNative);
aCache->SetIsDOMBinding();
aCache->SetWrapper(global);
aCache->SetIsDOMBinding();
aCache->SetWrapper(aGlobal);
/* Intl API is broken and makes this fail intermittently, see bug 934889.
if (!JS_InitStandardClasses(aCx, global)) {
dom::AllocateProtoAndIfaceCache(aGlobal,
CreateGlobalOptions<T>::ProtoAndIfaceCacheKind);
if (!CreateGlobalOptions<T>::PostCreateGlobal(aCx, aGlobal)) {
return false;
}
}
if (aInitStandardClasses &&
!CreateGlobalOptions<T>::ForceInitStandardClassesToFalse &&
!JS_InitStandardClasses(aCx, aGlobal)) {
NS_WARNING("Failed to init standard classes");
return nullptr;
return false;
}
*/
JS::Handle<JSObject*> proto = ProtoGetter(aCx, global);
NS_ENSURE_TRUE(proto, nullptr);
if (!JS_SetPrototype(aCx, global, proto)) {
JS::Handle<JSObject*> proto = GetProto(aCx, aGlobal);
if (!proto || !JS_SplicePrototype(aCx, aGlobal, proto)) {
NS_WARNING("Failed to set proto");
return nullptr;
return false;
}
MOZ_ALWAYS_TRUE(TryPreserveWrapper(global));
MOZ_ASSERT(UnwrapDOMObjectToISupports(global));
return global;
return true;
}
/*
@ -2661,6 +2735,15 @@ ConvertExceptionToPromise(JSContext* cx,
JSObject* promiseScope,
JS::MutableHandle<JS::Value> rval);
// While we wait for the outcome of spec discussions on whether properties for
// DOM global objects live on the object or the prototype, we supply this one
// place to switch the behaviour, so we can easily turn this off on branches.
inline bool
GlobalPropertiesAreOwn()
{
return true;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -2482,13 +2482,17 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
else:
domClass = "nullptr"
if self.properties.hasNonChromeOnly():
isGlobal = self.descriptor.interface.getExtendedAttribute("Global") is not None
if not isGlobal and self.properties.hasNonChromeOnly():
properties = "&sNativeProperties"
elif self.properties.hasNonChromeOnly():
properties = "!GlobalPropertiesAreOwn() ? &sNativeProperties : nullptr"
else:
properties = "nullptr"
if self.properties.hasChromeOnly():
accessCheck = "nsContentUtils::ThreadsafeIsCallerChrome()"
chromeProperties = accessCheck + " ? &sChromeOnlyNativeProperties : nullptr"
if not isGlobal and self.properties.hasChromeOnly():
chromeProperties = "nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
elif self.properties.hasChromeOnly():
chromeProperties = "!GlobalPropertiesAreOwn() && nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
else:
chromeProperties = "nullptr"
@ -2957,12 +2961,29 @@ class CGWrapGlobalMethod(CGAbstractMethod):
Argument(descriptor.nativeType + '*', 'aObject'),
Argument('nsWrapperCache*', 'aCache'),
Argument('JS::CompartmentOptions&', 'aOptions'),
Argument('JSPrincipals*', 'aPrincipal')]
Argument('JSPrincipals*', 'aPrincipal'),
Argument('bool', 'aInitStandardClasses')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
self.descriptor = descriptor
self.properties = properties
def definition_body(self):
if self.properties.hasNonChromeOnly():
properties = "GlobalPropertiesAreOwn() ? &sNativeProperties : nullptr"
else:
properties = "nullptr"
if self.properties.hasChromeOnly():
chromeProperties = "GlobalPropertiesAreOwn() && nsContentUtils::ThreadsafeIsCallerChrome() ? &sChromeOnlyNativeProperties : nullptr"
else:
chromeProperties = "nullptr"
if self.descriptor.workers:
fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
// JS_FireOnNewGlobalObject(aCx, obj);
"""
else:
fireOnNewGlobal = ""
return fill(
"""
${assertions}
@ -2970,29 +2991,39 @@ class CGWrapGlobalMethod(CGAbstractMethod):
"nsISupports must be on our primary inheritance chain");
JS::Rooted<JSObject*> obj(aCx);
obj = CreateGlobal<${nativeType}, GetProtoObject>(aCx,
aObject,
aCache,
Class.ToJSClass(),
aOptions,
aPrincipal);
CreateGlobal<${nativeType}, GetProtoObject>(aCx,
aObject,
aCache,
Class.ToJSClass(),
aOptions,
aPrincipal,
aInitStandardClasses,
&obj);
if (!obj) {
return nullptr;
}
// obj is a new global, so has a new compartment. Enter it
// before doing anything with it.
JSAutoCompartment ac(aCx, obj);
if (!DefineProperties(aCx, obj, ${properties}, ${chromeProperties})) {
return nullptr;
}
$*{unforgeable}
$*{slots}
// XXXkhuey can't do this yet until workers can lazy resolve.
// JS_FireOnNewGlobalObject(aCx, obj);
$*{fireOnNewGlobal}
return obj;
""",
assertions=AssertInheritanceChain(self.descriptor),
nativeType=self.descriptor.nativeType,
properties=properties,
chromeProperties=chromeProperties,
unforgeable=InitUnforgeableProperties(self.descriptor, self.properties),
slots=InitMemberSlots(self.descriptor, True))
slots=InitMemberSlots(self.descriptor, True),
fireOnNewGlobal=fireOnNewGlobal)
class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):

Просмотреть файл

@ -34,7 +34,8 @@
}, 200);
return function cancel() {
if (interval) {
ok(false, 'timed out waiting for audio check');
ok(false, type + ' (' + successMessage + ')' +
' failed after waiting full duration');
clearInterval(interval);
done();
}
@ -56,8 +57,6 @@
analyser.getByteTimeDomainData(view);
var silent = check(constraintApplied, isSilence(view), 'be silence for audio');
// TODO: silence cross origin input to webaudio, bug 966066
silent = constraintApplied ? !silent : silent;
return sampleCount > 0 && silent;
}
return periodicCheck('audio', testAudio,
@ -101,7 +100,8 @@
ctx.getImageData(0, 0, 1, 1);
return check(constraintApplied, false, 'throw on getImageData for video');
} catch (e) {
return check(constraintApplied, e.name === 'SecurityError', 'get a security error');
return check(constraintApplied, e.name === 'SecurityError',
'get a security error: ' + e.name);
}
}

Просмотреть файл

@ -493,24 +493,70 @@ function PeerConnectionTest(options) {
PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
info("Closing peer connections. Connection state=" + this.connected);
function signalingstatechangeClose(state) {
var self = this;
var closeTimeout = null;
var waitingForLocal = false;
var waitingForRemote = false;
var everythingClosed = false;
function verifyClosed() {
if ((self.waitingForLocal || self.waitingForRemote) ||
(self.pcLocal && (self.pcLocal.signalingState !== "closed")) ||
(self.pcRemote && (self.pcRemote.signalingState !== "closed"))) {
info("still waiting for closure");
}
else if (!everythingClosed) {
info("No closure pending");
if (self.pcLocal) {
is(self.pcLocal.signalingState, "closed", "pcLocal is in 'closed' state");
}
if (self.pcRemote) {
is(self.pcRemote.signalingState, "closed", "pcRemote is in 'closed' state");
}
clearTimeout(closeTimeout);
self.connected = false;
everythingClosed = true;
onSuccess();
}
}
function signalingstatechangeLocalClose(state) {
info("'onsignalingstatechange' event '" + state + "' received");
is(state, "closed", "onsignalingstatechange event is closed");
self.waitingForLocal = false;
verifyClosed();
}
// There is no onclose event for the remote peer existent yet. So close it
// side-by-side with the local peer.
if (this.pcLocal) {
this.pcLocal.onsignalingstatechange = signalingstatechangeClose;
this.pcLocal.close();
function signalingstatechangeRemoteClose(state) {
info("'onsignalingstatechange' event '" + state + "' received");
is(state, "closed", "onsignalingstatechange event is closed");
self.waitingForRemote = false;
verifyClosed();
}
if (this.pcRemote) {
this.pcRemote.onsignalingstatechange = signalingstatechangeClose;
this.pcRemote.close();
}
this.connected = false;
onSuccess();
function closeEverything() {
if ((self.pcLocal) && (self.pcLocal.signalingState !== "closed")) {
info("Closing pcLocal");
self.pcLocal.onsignalingstatechange = signalingstatechangeLocalClose;
self.waitingForLocal = true;
self.pcLocal.close();
}
if ((self.pcRemote) && (self.pcRemote.signalingState !== "closed")) {
info("Closing pcRemote");
self.pcRemote.onsignalingstatechange = signalingstatechangeRemoteClose;
self.waitingForRemote = true;
self.pcRemote.close();
}
verifyClosed();
}
closeTimeout = setTimeout(function() {
ok(false, "Closing PeerConnections timed out!");
// it is not a success, but the show must go on
onSuccess();
}, 60000);
closeEverything();
};
/**
@ -595,7 +641,6 @@ function PCT_setLocalDescription(peer, desc, stateExpected, onSuccess) {
}
peer.onsignalingstatechange = function (state) {
//info(peer + ": 'onsignalingstatechange' event registered, signalingState: " + peer.signalingState);
info(peer + ": 'onsignalingstatechange' event '" + state + "' received");
if(stateExpected === state && eventFired == false) {
eventFired = true;

Просмотреть файл

@ -35,6 +35,7 @@ interfaces = [
PARALLEL_DIRS += ['interfaces/' + i for i in interfaces]
PARALLEL_DIRS += [
'animation',
'apps',
'base',
'activities',

Просмотреть файл

@ -115,6 +115,8 @@ var interfaceNamesInGlobalScope =
"AnalyserNode",
// IMPORTANT: Do not change this list without review from a DOM peer!
"AnimationEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "AnimationTimeline", pref: "dom.animations-api.core.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"Attr",
// IMPORTANT: Do not change this list without review from a DOM peer!

Просмотреть файл

@ -0,0 +1,18 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dev.w3.org/fxtf/web-animations/#the-animationtimeline-interface
*
* Copyright © 2014 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Pref="dom.animations-api.core.enabled"]
interface AnimationTimeline {
readonly attribute double? currentTime;
// AnimationPlayer play (optional TimedItem? source = null);
// sequence<AnimationPlayer> getAnimationPlayers ();
};

Просмотреть файл

@ -3,15 +3,6 @@
* 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/.
*
* The origin of this IDL file is:
* http://dom.spec.whatwg.org/#interface-document
* http://www.whatwg.org/specs/web-apps/current-work/#the-document-object
* http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#api
* http://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#extensions-to-the-document-interface
* http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#sec-document-interface
* http://dev.w3.org/csswg/cssom/#extensions-to-the-document-interface
* http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
*
* http://mxr.mozilla.org/mozilla-central/source/dom/interfaces/core/nsIDOMDocument.idl
*/
@ -294,6 +285,12 @@ partial interface Document {
//(Not implemented)NodeList findAll(DOMString selectors, optional (Element or sequence<Node>)? refNodes);
};
// http://dev.w3.org/fxtf/web-animations/#extensions-to-the-document-interface
partial interface Document {
[Pref="dom.animations-api.core.enabled"]
readonly attribute AnimationTimeline timeline;
};
// Mozilla extensions of various sorts
partial interface Document {
// nsIDOMDocumentXBL. Wish we could make these [ChromeOnly], but

Просмотреть файл

@ -19,6 +19,7 @@ WEBIDL_FILES = [
'ActivityRequestHandler.webidl',
'AnalyserNode.webidl',
'AnimationEvent.webidl',
'AnimationTimeline.webidl',
'AppInfo.webidl',
'AppNotificationServiceOptions.webidl',
'ArchiveReader.webidl',

Просмотреть файл

@ -299,7 +299,8 @@ DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
options,
GetWorkerPrincipal());
GetWorkerPrincipal(),
true);
}
void
@ -336,7 +337,8 @@ SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
mWorkerPrivate->CopyJSCompartmentOptions(options);
return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this, options,
GetWorkerPrincipal());
GetWorkerPrincipal(),
true);
}
bool

Просмотреть файл

@ -10,7 +10,6 @@
#include "nsXPCOM.h"
#include "nsSupportsPrimitives.h"
#include "nsIComponentManager.h"
#include "nsCommandGroup.h"
#include "nsIControllerCommand.h"
#include "nsCRT.h"
@ -19,31 +18,29 @@
class nsGroupsEnumerator : public nsISimpleEnumerator
{
public:
nsGroupsEnumerator(nsHashtable& inHashTable);
virtual ~nsGroupsEnumerator();
nsGroupsEnumerator(nsControllerCommandGroup::GroupsHashtable &inHashTable);
virtual ~nsGroupsEnumerator();
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
protected:
static bool HashEnum(nsHashKey *aKey, void *aData, void* aClosure);
nsresult Initialize();
static PLDHashOperator HashEnum(const nsACString &aKey, nsTArray<nsCString> *aData, void *aClosure);
nsresult Initialize();
protected:
nsHashtable& mHashTable;
int32_t mIndex;
char ** mGroupNames; // array of pointers to char16_t* in the hash table
bool mInitted;
nsControllerCommandGroup::GroupsHashtable &mHashTable;
int32_t mIndex;
char **mGroupNames; // array of pointers to char16_t* in the hash table
bool mInitted;
};
/* Implementation file */
NS_IMPL_ISUPPORTS(nsGroupsEnumerator, nsISimpleEnumerator)
nsGroupsEnumerator::nsGroupsEnumerator(nsHashtable& inHashTable)
nsGroupsEnumerator::nsGroupsEnumerator(nsControllerCommandGroup::GroupsHashtable &inHashTable)
: mHashTable(inHashTable)
, mIndex(-1)
, mGroupNames(nullptr)
@ -61,7 +58,7 @@ nsGroupsEnumerator::~nsGroupsEnumerator()
NS_IMETHODIMP
nsGroupsEnumerator::HasMoreElements(bool *_retval)
{
nsresult rv = NS_OK;
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(_retval);
@ -70,7 +67,7 @@ nsGroupsEnumerator::HasMoreElements(bool *_retval)
if (NS_FAILED(rv)) return rv;
}
*_retval = (mIndex < mHashTable.Count() - 1);
*_retval = (mIndex < static_cast<int32_t>(mHashTable.Count()) - 1);
return NS_OK;
}
@ -78,7 +75,7 @@ nsGroupsEnumerator::HasMoreElements(bool *_retval)
NS_IMETHODIMP
nsGroupsEnumerator::GetNext(nsISupports **_retval)
{
nsresult rv = NS_OK;
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(_retval);
@ -88,7 +85,7 @@ nsGroupsEnumerator::GetNext(nsISupports **_retval)
}
mIndex ++;
if (mIndex >= mHashTable.Count())
if (mIndex >= static_cast<int32_t>(mHashTable.Count()))
return NS_ERROR_FAILURE;
char *thisGroupName = mGroupNames[mIndex];
@ -102,15 +99,13 @@ nsGroupsEnumerator::GetNext(nsISupports **_retval)
/* static */
/* return false to stop */
bool
nsGroupsEnumerator::HashEnum(nsHashKey *aKey, void *aData, void* aClosure)
PLDHashOperator
nsGroupsEnumerator::HashEnum(const nsACString &aKey, nsTArray<nsCString> *aData, void *aClosure)
{
nsGroupsEnumerator* groupsEnum = reinterpret_cast<nsGroupsEnumerator *>(aClosure);
nsCStringKey* stringKey = static_cast<nsCStringKey*>(aKey);
groupsEnum->mGroupNames[groupsEnum->mIndex] = (char*)stringKey->GetString();
groupsEnum->mIndex ++;
return true;
nsGroupsEnumerator *groupsEnum = static_cast<nsGroupsEnumerator*>(aClosure);
groupsEnum->mGroupNames[groupsEnum->mIndex] = (char*)aKey.Data();
groupsEnum->mIndex++;
return PL_DHASH_NEXT;
}
nsresult
@ -122,7 +117,7 @@ nsGroupsEnumerator::Initialize()
if (!mGroupNames) return NS_ERROR_OUT_OF_MEMORY;
mIndex = 0;
mHashTable.Enumerate(HashEnum, (void*)this);
mHashTable.EnumerateRead(HashEnum, this);
mIndex = -1;
mInitted = true;
@ -136,20 +131,18 @@ nsGroupsEnumerator::Initialize()
class nsNamedGroupEnumerator : public nsISimpleEnumerator
{
public:
nsNamedGroupEnumerator(nsTArray<char*>* inArray);
virtual ~nsNamedGroupEnumerator();
nsNamedGroupEnumerator(nsTArray<nsCString> *inArray);
virtual ~nsNamedGroupEnumerator();
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
protected:
nsTArray<char*>* mGroupArray;
int32_t mIndex;
nsTArray<nsCString> *mGroupArray;
int32_t mIndex;
};
nsNamedGroupEnumerator::nsNamedGroupEnumerator(nsTArray<char*>* inArray)
nsNamedGroupEnumerator::nsNamedGroupEnumerator(nsTArray<nsCString> *inArray)
: mGroupArray(inArray)
, mIndex(-1)
{
@ -181,18 +174,17 @@ nsNamedGroupEnumerator::GetNext(nsISupports **_retval)
if (!mGroupArray)
return NS_ERROR_FAILURE;
mIndex ++;
mIndex++;
if (mIndex >= int32_t(mGroupArray->Length()))
return NS_ERROR_FAILURE;
char16_t *thisGroupName = (char16_t*)mGroupArray->ElementAt(mIndex);
NS_ASSERTION(thisGroupName, "Bad Element in mGroupArray");
const nsCString& thisGroupName = mGroupArray->ElementAt(mIndex);
nsresult rv;
nsCOMPtr<nsISupportsString> supportsString = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
nsCOMPtr<nsISupportsCString> supportsString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
supportsString->SetData(nsDependentString(thisGroupName));
supportsString->SetData(thisGroupName);
return CallQueryInterface(supportsString, _retval);
}
@ -216,7 +208,7 @@ nsControllerCommandGroup::~nsControllerCommandGroup()
void
nsControllerCommandGroup::ClearGroupsHash()
{
mGroupsHash.Reset(ClearEnumerator, (void *)this);
mGroupsHash.Clear();
}
#if 0
@ -225,24 +217,21 @@ nsControllerCommandGroup::ClearGroupsHash()
/* void addCommandToGroup (in DOMString aCommand, in DOMString aGroup); */
NS_IMETHODIMP
nsControllerCommandGroup::AddCommandToGroup(const char * aCommand, const char *aGroup)
nsControllerCommandGroup::AddCommandToGroup(const char *aCommand, const char *aGroup)
{
nsCStringKey groupKey(aGroup);
nsTArray<char*>* commandList;
if ((commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey)) == nullptr)
nsDependentCString groupKey(aGroup);
nsTArray<nsCString> *commandList;
if ((commandList = mGroupsHash.Get(groupKey)) == nullptr)
{
// make this list
commandList = new nsAutoTArray<char*, 8>;
mGroupsHash.Put(&groupKey, (void *)commandList);
commandList = new nsAutoTArray<nsCString, 8>;
mGroupsHash.Put(groupKey, commandList);
}
// add the command to the list. Note that we're not checking for duplicates here
char* commandString = NS_strdup(aCommand); // we store allocated char16_t* in the array
if (!commandString) return NS_ERROR_OUT_OF_MEMORY;
#ifdef DEBUG
char** appended =
nsCString *appended =
#endif
commandList->AppendElement(commandString);
commandList->AppendElement(aCommand);
NS_ASSERTION(appended, "Append failed");
return NS_OK;
@ -250,43 +239,41 @@ nsControllerCommandGroup::AddCommandToGroup(const char * aCommand, const char *a
/* void removeCommandFromGroup (in DOMString aCommand, in DOMString aGroup); */
NS_IMETHODIMP
nsControllerCommandGroup::RemoveCommandFromGroup(const char * aCommand, const char * aGroup)
nsControllerCommandGroup::RemoveCommandFromGroup(const char *aCommand, const char *aGroup)
{
nsCStringKey groupKey(aGroup);
nsTArray<char*>* commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey);
if (!commandList) return NS_OK; // no group
nsDependentCString groupKey(aGroup);
nsTArray<nsCString> *commandList = mGroupsHash.Get(groupKey);
if (!commandList) return NS_OK; // no group
uint32_t numEntries = commandList->Length();
for (uint32_t i = 0; i < numEntries; i ++)
for (uint32_t i = 0; i < numEntries; i++)
{
char* commandString = commandList->ElementAt(i);
if (!nsCRT::strcmp(aCommand,commandString))
nsCString commandString = commandList->ElementAt(i);
if (nsDependentCString(aCommand) != commandString)
{
commandList->RemoveElementAt(i);
nsMemory::Free(commandString);
break;
}
}
return NS_OK;
}
/* boolean isCommandInGroup (in DOMString aCommand, in DOMString aGroup); */
NS_IMETHODIMP
nsControllerCommandGroup::IsCommandInGroup(const char * aCommand, const char * aGroup, bool *_retval)
nsControllerCommandGroup::IsCommandInGroup(const char *aCommand, const char *aGroup, bool *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
*_retval = false;
nsCStringKey groupKey(aGroup);
nsTArray<char*>* commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey);
if (!commandList) return NS_OK; // no group
nsDependentCString groupKey(aGroup);
nsTArray<nsCString> *commandList = mGroupsHash.Get(groupKey);
if (!commandList) return NS_OK; // no group
uint32_t numEntries = commandList->Length();
for (uint32_t i = 0; i < numEntries; i ++)
for (uint32_t i = 0; i < numEntries; i++)
{
char* commandString = commandList->ElementAt(i);
if (!nsCRT::strcmp(aCommand,commandString))
nsCString commandString = commandList->ElementAt(i);
if (nsDependentCString(aCommand) != commandString)
{
*_retval = true;
break;
@ -299,7 +286,7 @@ nsControllerCommandGroup::IsCommandInGroup(const char * aCommand, const char * a
NS_IMETHODIMP
nsControllerCommandGroup::GetGroupsEnumerator(nsISimpleEnumerator **_retval)
{
nsGroupsEnumerator* groupsEnum = new nsGroupsEnumerator(mGroupsHash);
nsGroupsEnumerator *groupsEnum = new nsGroupsEnumerator(mGroupsHash);
if (!groupsEnum) return NS_ERROR_OUT_OF_MEMORY;
return groupsEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)_retval);
@ -307,12 +294,12 @@ nsControllerCommandGroup::GetGroupsEnumerator(nsISimpleEnumerator **_retval)
/* nsISimpleEnumerator getEnumeratorForGroup (in DOMString aGroup); */
NS_IMETHODIMP
nsControllerCommandGroup::GetEnumeratorForGroup(const char * aGroup, nsISimpleEnumerator **_retval)
nsControllerCommandGroup::GetEnumeratorForGroup(const char *aGroup, nsISimpleEnumerator **_retval)
{
nsCStringKey groupKey(aGroup);
nsTArray<char*>* commandList = (nsTArray<char*> *)mGroupsHash.Get(&groupKey); // may be null
nsDependentCString groupKey(aGroup);
nsTArray<nsCString> *commandList = mGroupsHash.Get(groupKey); // may be null
nsNamedGroupEnumerator* theGroupEnum = new nsNamedGroupEnumerator(commandList);
nsNamedGroupEnumerator *theGroupEnum = new nsNamedGroupEnumerator(commandList);
if (!theGroupEnum) return NS_ERROR_OUT_OF_MEMORY;
return theGroupEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)_retval);
@ -321,21 +308,3 @@ nsControllerCommandGroup::GetEnumeratorForGroup(const char * aGroup, nsISimpleEn
#if 0
#pragma mark -
#endif
bool nsControllerCommandGroup::ClearEnumerator(nsHashKey *aKey, void *aData, void* closure)
{
nsTArray<char*>* commandList = (nsTArray<char*> *)aData;
if (commandList)
{
uint32_t numEntries = commandList->Length();
for (uint32_t i = 0; i < numEntries; i ++)
{
char* commandString = commandList->ElementAt(i);
nsMemory::Free(commandString);
}
delete commandList;
}
return true;
}

Просмотреть файл

@ -3,15 +3,12 @@
* 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 nsCommandGroup_h__
#define nsCommandGroup_h__
#include "nsIController.h"
#include "nsHashtable.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
// {ecd55a01-2780-11d5-a73c-ca641a6813bc}
#define NS_CONTROLLER_COMMAND_GROUP_CID \
@ -20,34 +17,24 @@
#define NS_CONTROLLER_COMMAND_GROUP_CONTRACTID \
"@mozilla.org/embedcomp/controller-command-group;1"
class nsControllerCommandGroup : public nsIControllerCommandGroup
{
public:
nsControllerCommandGroup();
virtual ~nsControllerCommandGroup();
nsControllerCommandGroup();
virtual ~nsControllerCommandGroup();
NS_DECL_ISUPPORTS
NS_DECL_NSICONTROLLERCOMMANDGROUP
public:
typedef nsClassHashtable<nsCStringHashKey, nsTArray<nsCString>> GroupsHashtable;
protected:
void ClearGroupsHash();
void ClearGroupsHash();
protected:
static bool ClearEnumerator(nsHashKey *aKey, void *aData, void* closure);
protected:
nsHashtable mGroupsHash; // hash keyed on command group.
// Entries are nsTArray<char*>
// This could be made more space-efficient, maybe with atoms
GroupsHashtable mGroupsHash; // hash keyed on command group.
// This could be made more space-efficient, maybe with atoms
};
#endif // nsCommandGroup_h__

Просмотреть файл

@ -62,6 +62,15 @@ NudgeToInteger(float *aVal)
}
}
static inline void
NudgeToInteger(float *aVal, float aErr)
{
float r = floorf(*aVal + 0.5f);
if (FuzzyEqual(r, *aVal, aErr)) {
*aVal = r;
}
}
static inline Float
Distance(Point aA, Point aB)
{

Просмотреть файл

@ -39,7 +39,7 @@ Inline documentation about TextureClient and TextureHost can be found in:
TextureClient is the client-side handle on a MozSurface, while TextureHost is the equivalent host-side representation. There can only be one TextureClient for a given TextureHost, and one TextureHost for a given TextureClient. Likewise, there can only be one shared object for a given TextureClient/TextureHost pair.
A MozSurface containing data that is shared between a client process and a host process exists in the foolowing form:
A MozSurface containing data that is shared between a client process and a host process exists in the following form:
```
.
@ -88,7 +88,7 @@ A surface lets you *borrow* a DrawTarget that is only valid between Lock and Unl
It is invalid to hold a reference to the DrawTarget after Unlock, and a different DrawTarget may be obtained during the next Lock/Unlock interval.
In some cases we want to use MozSurface without Drawing into it. For instance to share video frames accross processes. Some surface types may also not be accessible through a DrawTarget (for example YCbCr surfaces).
In some cases we want to use MozSurface without drawing into it. For instance to share video frames accross processes. Some surface types may also not be accessible through a DrawTarget (for example YCbCr surfaces).
bool CanExposeDrawTarget();

Просмотреть файл

@ -249,8 +249,8 @@ static void CopyDataSourceSurface(DataSourceSurface* aSource,
DataSourceSurface* aDest)
{
MOZ_ASSERT(aSource->GetSize() == aDest->GetSize());
MOZ_ASSERT(aSource->GetFormat() == SurfaceFormat::R8G8B8A8 ||
aSource->GetFormat() == SurfaceFormat::R8G8B8X8);
MOZ_ASSERT(aSource->GetFormat() == SurfaceFormat::B8G8R8A8 ||
aSource->GetFormat() == SurfaceFormat::B8G8R8X8);
uint8_t *srcRow = aSource->GetData();
size_t srcRowBytes = aSource->GetSize().width * BytesPerPixel(aSource->GetFormat());
@ -328,44 +328,40 @@ GuessAlignment(int width, int pixelSize, int rowStride)
}
void
ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) {
gl->MakeCurrent();
MOZ_ASSERT(dest->GetSize() != gfxIntSize(0, 0));
MOZ_ASSERT(dest->GetSize().width != 0);
MOZ_ASSERT(dest->GetSize().height != 0);
/* gfxImageFormat::ARGB32:
* RGBA+UByte: be[RGBA], le[ABGR]
* RGBA+UInt: be[ABGR], le[RGBA]
* BGRA+UInt: be[ARGB], le[BGRA]
* BGRA+UIntRev: be[BGRA], le[ARGB]
*
* gfxImageFormat::RGB16_565:
* RGB+UShort: le[rrrrrggg,gggbbbbb]
*/
bool hasAlpha = dest->Format() == gfxImageFormat::ARGB32;
bool hasAlpha = dest->GetFormat() == SurfaceFormat::B8G8R8A8 ||
dest->GetFormat() == SurfaceFormat::R8G8B8A8;
int destPixelSize;
GLenum destFormat;
GLenum destType;
switch (dest->Format()) {
case gfxImageFormat::RGB24: // XRGB
case gfxImageFormat::ARGB32:
destPixelSize = 4;
switch (dest->GetFormat()) {
case SurfaceFormat::B8G8R8A8:
case SurfaceFormat::B8G8R8X8:
// Needs host (little) endian ARGB.
destFormat = LOCAL_GL_BGRA;
destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
break;
case gfxImageFormat::RGB16_565:
destPixelSize = 2;
case SurfaceFormat::R8G8B8A8:
case SurfaceFormat::R8G8B8X8:
// Needs host (little) endian ABGR.
destFormat = LOCAL_GL_RGBA;
destType = LOCAL_GL_UNSIGNED_BYTE;
break;
case SurfaceFormat::R5G6B5:
destFormat = LOCAL_GL_RGB;
destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV;
break;
default:
MOZ_CRASH("Bad format.");
}
MOZ_ASSERT(dest->Width() * destPixelSize <= dest->Stride());
destPixelSize = BytesPerPixel(dest->GetFormat());
MOZ_ASSERT(dest->GetSize().width * destPixelSize <= dest->Stride());
GLenum readFormat = destFormat;
GLenum readType = destType;
@ -373,20 +369,15 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
destFormat, destType,
readFormat, readType);
nsAutoPtr<gfxImageSurface> tempSurf;
gfxImageSurface* readSurf = nullptr;
// Figure out alignment. We don't need to know why, we just need it
// to be valid.
int readAlignment = GuessAlignment(dest->Width(),
RefPtr<DataSourceSurface> tempSurf;
DataSourceSurface* readSurf = dest;
int readAlignment = GuessAlignment(dest->GetSize().width,
destPixelSize,
dest->Stride());
if (!readAlignment) // Couldn't calculate a valid alignment.
if (!readAlignment) {
needsTempSurf = true;
if (!needsTempSurf) {
readSurf = dest;
} else {
}
if (needsTempSurf) {
if (gl->DebugMode()) {
NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
}
@ -431,154 +422,11 @@ ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
}
}
tempSurf = new gfxImageSurface(dest->GetSize(),
SurfaceFormatToImageFormat(readFormatGFX),
false);
readSurf = tempSurf;
}
MOZ_ASSERT(readAlignment);
GLint currentPackAlignment = 0;
gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &currentPackAlignment);
if (currentPackAlignment != readAlignment)
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readAlignment);
GLsizei width = dest->Width();
GLsizei height = dest->Height();
readSurf->Flush();
gl->fReadPixels(0, 0,
width, height,
readFormat, readType,
readSurf->Data());
readSurf->MarkDirty();
if (currentPackAlignment != readAlignment)
gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
if (readSurf != dest) {
MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);
// So we just copied in RGBA in big endian, or le: 0xAABBGGRR.
// We want 0xAARRGGBB, so swap R and B:
dest->Flush();
RefPtr<DataSourceSurface> readDSurf =
Factory::CreateWrappingDataSourceSurface(readSurf->Data(),
readSurf->Stride(),
ToIntSize(readSurf->GetSize()),
ImageFormatToSurfaceFormat(readSurf->Format()));
SwapRAndBComponents(readDSurf);
dest->MarkDirty();
gfxContext ctx(dest);
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
ctx.SetSource(readSurf);
ctx.Paint();
}
// Check if GL is giving back 1.0 alpha for
// RGBA reads to RGBA images from no-alpha buffers.
#ifdef XP_MACOSX
if (gl->WorkAroundDriverBugs() &&
gl->Vendor() == gl::GLVendor::NVIDIA &&
dest->Format() == gfxImageFormat::ARGB32 &&
width && height)
{
GLint alphaBits = 0;
gl->fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits);
if (!alphaBits) {
const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0);
MOZ_ASSERT(dest->Width() * destPixelSize == dest->Stride());
dest->Flush();
uint32_t* itr = (uint32_t*)dest->Data();
uint32_t testPixel = *itr;
if ((testPixel & alphaMask) != alphaMask) {
// We need to set the alpha channel to 1.0 manually.
uint32_t* itrEnd = itr + width*height; // Stride is guaranteed to be width*4.
for (; itr != itrEnd; itr++) {
*itr |= alphaMask;
}
}
dest->MarkDirty();
}
}
#endif
}
void
ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) {
gl->MakeCurrent();
MOZ_ASSERT(dest->GetSize().width != 0);
MOZ_ASSERT(dest->GetSize().height != 0);
bool hasAlpha = dest->GetFormat() == SurfaceFormat::B8G8R8A8 ||
dest->GetFormat() == SurfaceFormat::R8G8B8A8;
int destPixelSize;
GLenum destFormat;
GLenum destType;
switch (dest->GetFormat()) {
case SurfaceFormat::B8G8R8A8:
case SurfaceFormat::B8G8R8X8:
// Needs host (little) endian ARGB.
destFormat = LOCAL_GL_BGRA;
destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
break;
case SurfaceFormat::R8G8B8A8:
case SurfaceFormat::R8G8B8X8:
// Needs host (little) endian ABGR.
destFormat = LOCAL_GL_RGBA;
destType = LOCAL_GL_UNSIGNED_BYTE;
break;
case SurfaceFormat::R5G6B5:
destFormat = LOCAL_GL_RGB;
destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV;
break;
default:
MOZ_CRASH("Bad format.");
}
destPixelSize = BytesPerPixel(dest->GetFormat());
MOZ_ASSERT(dest->GetSize().width * destPixelSize <= dest->Stride());
GLenum readFormat = destFormat;
GLenum readType = destType;
bool needsTempSurf = !GetActualReadFormats(gl,
destFormat, destType,
readFormat, readType);
RefPtr<DataSourceSurface> tempSurf;
DataSourceSurface* readSurf = nullptr;
int readAlignment = 0;
if (needsTempSurf) {
if (gl->DebugMode()) {
NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
}
SurfaceFormat readFormatGFX;
// If needs temp surface, readFormat is always LOCAL_GL_RGBA
// and readType is always LOCAL_GL_UNSIGNED_BYTE
MOZ_ASSERT(readFormat == LOCAL_GL_RGBA);
MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_BYTE);
readFormatGFX = hasAlpha ? SurfaceFormat::R8G8B8A8
: SurfaceFormat::R8G8B8X8;
readAlignment = 1;
int32_t stride = dest->GetSize().width * BytesPerPixel(readFormatGFX);
tempSurf = Factory::CreateDataSourceSurfaceWithStride(dest->GetSize(),
readFormatGFX,
stride);
readSurf = tempSurf;
} else {
// Figure out alignment. We don't need to know why, we just need it
// to be valid.
readAlignment = GuessAlignment(dest->GetSize().width,
destPixelSize,
dest->Stride());
readSurf = dest;
}
MOZ_ASSERT(readAlignment);
MOZ_ASSERT(reinterpret_cast<uintptr_t>(readSurf->GetData()) % readAlignment == 0);
@ -705,14 +553,6 @@ ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, SurfaceFormat aFo
return surf.forget();
}
void
ReadScreenIntoImageSurface(GLContext* gl, gfxImageSurface* dest)
{
ScopedBindFramebuffer autoFB(gl, 0);
ReadPixelsIntoImageSurface(gl, dest);
}
#define CLEANUP_IF_GLERROR_OCCURRED(x) \
if (DidGLErrorOccur(x)) { \
isurf = nullptr; \

Просмотреть файл

@ -26,8 +26,6 @@ namespace gl {
void ReadPixelsIntoDataSurface(GLContext* aGL,
gfx::DataSourceSurface* aSurface);
void ReadPixelsIntoImageSurface(GLContext* aGL, gfxImageSurface* aSurface);
void ReadScreenIntoImageSurface(GLContext* aGL, gfxImageSurface* aSurface);
TemporaryRef<gfx::DataSourceSurface>
ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, gfx::SurfaceFormat aFormat);

Просмотреть файл

@ -17,11 +17,12 @@
#include "gfxUtils.h" // for gfxUtils
#include "gfx2DGlue.h" // for thebes --> moz2d transition
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/gfx/Tools.h"
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
#include "nsISupportsImpl.h" // for gfxContext::AddRef, etc
#include "nsRect.h" // for nsIntRect
#include "nsSize.h" // for nsIntSize
#include "LayerUtils.h"
#include "gfxUtils.h"
using namespace mozilla::gfx;
using namespace mozilla::gl;
@ -126,7 +127,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat);
mGLContext->Screen()->Readback(sharedSurf, data);
if (needsPremult) {
PremultiplySurface(data);
gfxUtils::PremultiplyDataSurface(data);
}
aDestTarget->ReleaseBits(destData);
return;
@ -144,7 +145,7 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
// Readback handles Flush/MarkDirty.
mGLContext->Screen()->Readback(sharedSurf, data);
if (needsPremult) {
PremultiplySurface(data);
gfxUtils::PremultiplyDataSurface(data);
}
resultSurf = data;
}
@ -170,7 +171,9 @@ CopyableCanvasLayer::GetTempSurface(const IntSize& aSize,
aSize != mCachedTempSurface->GetSize() ||
aFormat != mCachedTempSurface->GetFormat())
{
mCachedTempSurface = Factory::CreateDataSourceSurface(aSize, aFormat);
// Create a surface aligned to 8 bytes since that's the highest alignment WebGL can handle.
uint32_t stride = GetAlignedStride<8>(aSize.width * BytesPerPixel(aFormat));
mCachedTempSurface = Factory::CreateDataSourceSurfaceWithStride(aSize, aFormat, stride);
}
return mCachedTempSurface;

Просмотреть файл

@ -108,6 +108,8 @@ struct LayerPropertiesBase : public LayerProperties
, mMaskLayer(nullptr)
, mVisibleRegion(aLayer->GetVisibleRegion())
, mInvalidRegion(aLayer->GetInvalidRegion())
, mPostXScale(aLayer->GetPostXScale())
, mPostYScale(aLayer->GetPostYScale())
, mOpacity(aLayer->GetLocalOpacity())
, mUseClipRect(!!aLayer->GetClipRect())
{
@ -142,7 +144,9 @@ struct LayerPropertiesBase : public LayerProperties
{
gfx3DMatrix transform;
gfx::To3DMatrix(mLayer->GetTransform(), transform);
bool transformChanged = !mTransform.FuzzyEqual(transform);
bool transformChanged = !mTransform.FuzzyEqual(transform) ||
mLayer->GetPostXScale() != mPostXScale ||
mLayer->GetPostYScale() != mPostYScale;
Layer* otherMask = mLayer->GetMaskLayer();
const nsIntRect* otherClip = mLayer->GetClipRect();
nsIntRegion result;
@ -166,13 +170,6 @@ struct LayerPropertiesBase : public LayerProperties
}
}
nsIntRegion visible;
visible.Xor(mVisibleRegion, mLayer->GetVisibleRegion());
if (!visible.IsEmpty()) {
aGeometryChanged = true;
}
AddTransformedRegion(result, visible, mTransform);
AddRegion(result, ComputeChangeInternal(aCallback, aGeometryChanged));
AddTransformedRegion(result, mLayer->GetInvalidRegion(), mTransform);
@ -216,6 +213,8 @@ struct LayerPropertiesBase : public LayerProperties
nsIntRegion mVisibleRegion;
nsIntRegion mInvalidRegion;
gfx3DMatrix mTransform;
float mPostXScale;
float mPostYScale;
float mOpacity;
nsIntRect mClipRect;
bool mUseClipRect;
@ -225,6 +224,8 @@ struct ContainerLayerProperties : public LayerPropertiesBase
{
ContainerLayerProperties(ContainerLayer* aLayer)
: LayerPropertiesBase(aLayer)
, mPreXScale(aLayer->GetPreXScale())
, mPreYScale(aLayer->GetPreYScale())
{
for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) {
mChildren.AppendElement(CloneLayerTreePropertiesInternal(child));
@ -237,6 +238,21 @@ struct ContainerLayerProperties : public LayerPropertiesBase
ContainerLayer* container = mLayer->AsContainerLayer();
nsIntRegion result;
if (mPreXScale != container->GetPreXScale() ||
mPreYScale != container->GetPreYScale()) {
aGeometryChanged = true;
result = OldTransformedBounds();
AddRegion(result, NewTransformedBounds());
// If we don't have to generate invalidations separately for child
// layers then we can just stop here since we've already invalidated the entire
// old and new bounds.
if (!aCallback) {
ClearInvalidations(mLayer);
return result;
}
}
// A low frame rate is especially visible to users when scrolling, so we
// particularly want to avoid unnecessary invalidation at that time. For us
// here, that means avoiding unnecessary invalidation of child items when
@ -312,6 +328,8 @@ struct ContainerLayerProperties : public LayerPropertiesBase
// The old list of children:
nsAutoTArray<nsAutoPtr<LayerPropertiesBase>,1> mChildren;
float mPreXScale;
float mPreYScale;
};
struct ColorLayerProperties : public LayerPropertiesBase

Просмотреть файл

@ -1,101 +0,0 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LayerUtils.h"
#include "PremultiplyTables.h"
#include "mozilla/Endian.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
static inline const uint8_t PremultiplyValue(uint8_t a, uint8_t v) {
return PremultiplyTable[a*256+v];
}
static inline const uint8_t UnpremultiplyValue(uint8_t a, uint8_t v) {
return UnpremultiplyTable[a*256+v];
}
#ifdef DEBUG
static bool IsLittleEndian()
{
// Violate strict aliasing, because violating strict aliasing is how
// we always pack and unpack between uint32_t and uint8_t[].
uint16_t testShort;
static const uint8_t testBytes[2] = { 0xAA, 0xBB };
memcpy(&testShort, testBytes, sizeof(testBytes));
return testShort == 0xBBAA;
}
#endif // DEBUG
#ifdef MOZ_LITTLE_ENDIAN
#define ASSERT_ENDIAN() MOZ_ASSERT(IsLittleEndian(), "Defined as little endian, but actually big!")
#else
#define ASSERT_ENDIAN() MOZ_ASSERT(!IsLittleEndian(), "Defined as big endian, but actually little!")
#endif
void
PremultiplySurface(DataSourceSurface* srcSurface,
DataSourceSurface* destSurface)
{
if (!destSurface)
destSurface = srcSurface;
IntSize srcSize = srcSurface->GetSize();
MOZ_ASSERT(srcSurface->GetFormat() == destSurface->GetFormat() &&
srcSize.width == destSurface->GetSize().width &&
srcSize.height == destSurface->GetSize().height &&
srcSurface->Stride() == destSurface->Stride(),
"Source and destination surfaces don't have identical characteristics");
MOZ_ASSERT(srcSurface->Stride() == srcSize.width * 4,
"Source surface stride isn't tightly packed");
// Only premultiply ARGB32
if (srcSurface->GetFormat() != SurfaceFormat::B8G8R8A8) {
if (destSurface != srcSurface) {
memcpy(destSurface->GetData(), srcSurface->GetData(),
srcSurface->Stride() * srcSize.height);
}
return;
}
uint8_t *src = srcSurface->GetData();
uint8_t *dst = destSurface->GetData();
// Assert that our endian define is correct.
ASSERT_ENDIAN();
uint32_t dim = srcSize.width * srcSize.height;
for (uint32_t i = 0; i < dim; ++i) {
#ifdef MOZ_LITTLE_ENDIAN
uint8_t b = *src++;
uint8_t g = *src++;
uint8_t r = *src++;
uint8_t a = *src++;
*dst++ = PremultiplyValue(a, b);
*dst++ = PremultiplyValue(a, g);
*dst++ = PremultiplyValue(a, r);
*dst++ = a;
#else
uint8_t a = *src++;
uint8_t r = *src++;
uint8_t g = *src++;
uint8_t b = *src++;
*dst++ = a;
*dst++ = PremultiplyValue(a, r);
*dst++ = PremultiplyValue(a, g);
*dst++ = PremultiplyValue(a, b);
#endif
}
}
}
}

Просмотреть файл

@ -1,21 +0,0 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_LAYERS_LAYERUTILS_H_
#define MOZILLA_LAYERS_LAYERUTILS_H_
#include "mozilla/gfx/2D.h"
namespace mozilla {
namespace layers {
void
PremultiplySurface(gfx::DataSourceSurface* srcSurface,
gfx::DataSourceSurface* destSurface = nullptr);
}
}
#endif /* MOZILLA_LAYERS_LAYERUTILS_H_ */

Просмотреть файл

@ -70,9 +70,10 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
if (mTextureFlags & TextureFlags::NEEDS_Y_FLIP) {
flags |= TextureFlags::NEEDS_Y_FLIP;
}
mBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format),
flags,
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
mBuffer = CreateTextureClientForDrawing(gfx::ImageFormatToSurfaceFormat(format),
flags,
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend(),
aSize);
MOZ_ASSERT(mBuffer->CanExposeDrawTarget());
mBuffer->AllocateForSurface(aSize);

Просмотреть файл

@ -124,6 +124,10 @@ ImageHost::Composite(EffectChain& aEffectChain,
} else {
effect->mTextureCoords = Rect(0, 0, 1, 1);
}
if (mFrontBuffer->GetFlags() & TextureFlags::NEEDS_Y_FLIP) {
effect->mTextureCoords.y = effect->mTextureCoords.YMost();
effect->mTextureCoords.height = -effect->mTextureCoords.height;
}
GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain,
aOpacity, aTransform);
GetCompositor()->DrawDiagnostics(DiagnosticFlags::IMAGE | DiagnosticFlags::BIGIMAGE,

Просмотреть файл

@ -294,7 +294,6 @@ UNIFIED_SOURCES += [
'LayerScope.cpp',
'LayersLogging.cpp',
'LayerSorter.cpp',
'LayerUtils.cpp',
'opengl/CompositingRenderTargetOGL.cpp',
'opengl/CompositorOGL.cpp',
'opengl/OGLShaderProgram.cpp',

Просмотреть файл

@ -880,3 +880,24 @@ void gfx3DMatrix::NudgeToIntegers(void)
NudgeToInteger(&_43);
NudgeToInteger(&_44);
}
void gfx3DMatrix::NudgeToIntegersFixedEpsilon(void)
{
static const float error = 1e-5;
NudgeToInteger(&_11, error);
NudgeToInteger(&_12, error);
NudgeToInteger(&_13, error);
NudgeToInteger(&_14, error);
NudgeToInteger(&_21, error);
NudgeToInteger(&_22, error);
NudgeToInteger(&_23, error);
NudgeToInteger(&_24, error);
NudgeToInteger(&_31, error);
NudgeToInteger(&_32, error);
NudgeToInteger(&_33, error);
NudgeToInteger(&_34, error);
NudgeToInteger(&_41, error);
NudgeToInteger(&_42, error);
NudgeToInteger(&_43, error);
NudgeToInteger(&_44, error);
}

Просмотреть файл

@ -344,6 +344,7 @@ public:
gfxFloat Determinant() const;
void NudgeToIntegers(void);
void NudgeToIntegersFixedEpsilon();
private:

Просмотреть файл

@ -3489,11 +3489,6 @@ public:
return mFonts.Length();
}
bool Equals(const gfxFontGroup& other) const {
return mFamilies.Equals(other.mFamilies) &&
mStyle.Equals(other.mStyle);
}
const gfxFontStyle *GetStyle() const { return &mStyle; }
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);

Просмотреть файл

@ -423,22 +423,6 @@ gfxPlatformFontList::PreloadNamesList()
}
void
gfxPlatformFontList::SetFixedPitch(const nsAString& aFamilyName)
{
gfxFontFamily *family = FindFamily(aFamilyName);
if (!family) return;
family->FindStyleVariations();
nsTArray<nsRefPtr<gfxFontEntry> >& fontlist = family->GetFontList();
uint32_t i, numFonts = fontlist.Length();
for (i = 0; i < numFonts; i++) {
fontlist[i]->mFixedPitch = 1;
}
}
void
gfxPlatformFontList::LoadBadUnderlineList()
{

Просмотреть файл

@ -264,9 +264,6 @@ protected:
// load the bad underline blacklist from pref.
void LoadBadUnderlineList();
// explicitly set fixed-pitch flag for all faces
void SetFixedPitch(const nsAString& aFamilyName);
void GenerateFontListKey(const nsAString& aKeyName, nsAString& aResult);
static PLDHashOperator

Просмотреть файл

@ -36,34 +36,24 @@ static const uint8_t UnpremultiplyValue(uint8_t a, uint8_t v) {
}
void
gfxUtils::PremultiplyImageSurface(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface)
gfxUtils::PremultiplyDataSurface(DataSourceSurface *aSurface)
{
if (!aDestSurface)
aDestSurface = aSourceSurface;
MOZ_ASSERT(aSourceSurface->Format() == aDestSurface->Format() &&
aSourceSurface->Width() == aDestSurface->Width() &&
aSourceSurface->Height() == aDestSurface->Height() &&
aSourceSurface->Stride() == aDestSurface->Stride(),
"Source and destination surfaces don't have identical characteristics");
MOZ_ASSERT(aSourceSurface->Stride() == aSourceSurface->Width() * 4,
"Source surface stride isn't tightly packed");
// Only premultiply ARGB32
if (aSourceSurface->Format() != gfxImageFormat::ARGB32) {
if (aDestSurface != aSourceSurface) {
memcpy(aDestSurface->Data(), aSourceSurface->Data(),
aSourceSurface->Stride() * aSourceSurface->Height());
}
if (aSurface->GetFormat() != SurfaceFormat::B8G8R8A8) {
return;
}
uint8_t *src = aSourceSurface->Data();
uint8_t *dst = aDestSurface->Data();
DataSourceSurface::MappedSurface map;
if (!aSurface->Map(DataSourceSurface::MapType::READ_WRITE, &map)) {
return;
}
MOZ_ASSERT(map.mStride == aSurface->GetSize().width * 4,
"Source surface stride isn't tightly packed");
uint32_t dim = aSourceSurface->Width() * aSourceSurface->Height();
uint8_t *src = map.mData;
uint8_t *dst = map.mData;
uint32_t dim = aSurface->GetSize().width * aSurface->GetSize().height;
for (uint32_t i = 0; i < dim; ++i) {
#ifdef IS_LITTLE_ENDIAN
uint8_t b = *src++;
@ -87,59 +77,8 @@ gfxUtils::PremultiplyImageSurface(gfxImageSurface *aSourceSurface,
*dst++ = PremultiplyValue(a, b);
#endif
}
}
void
gfxUtils::UnpremultiplyImageSurface(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface)
{
if (!aDestSurface)
aDestSurface = aSourceSurface;
MOZ_ASSERT(aSourceSurface->Format() == aDestSurface->Format() &&
aSourceSurface->Width() == aDestSurface->Width() &&
aSourceSurface->Height() == aDestSurface->Height(),
"Source and destination surfaces don't have identical characteristics");
// Only premultiply ARGB32
if (aSourceSurface->Format() != gfxImageFormat::ARGB32) {
if (aDestSurface != aSourceSurface) {
aDestSurface->CopyFrom(aSourceSurface);
}
return;
}
uint8_t *src = aSourceSurface->Data();
uint8_t *dst = aDestSurface->Data();
for (int32_t i = 0; i < aSourceSurface->Height(); ++i) {
uint8_t *srcRow = src + (i * aSourceSurface->Stride());
uint8_t *dstRow = dst + (i * aDestSurface->Stride());
for (int32_t j = 0; j < aSourceSurface->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();
}
TemporaryRef<DataSourceSurface>

Просмотреть файл

@ -40,10 +40,7 @@ public:
* If the source is not gfxImageFormat::ARGB32, no operation is performed. If
* aDestSurface is given, the data is copied over.
*/
static void PremultiplyImageSurface(gfxImageSurface *aSourceSurface,
gfxImageSurface *aDestSurface = nullptr);
static void UnpremultiplyImageSurface(gfxImageSurface *aSurface,
gfxImageSurface *aDestSurface = nullptr);
static void PremultiplyDataSurface(DataSourceSurface *aSurface);
static mozilla::TemporaryRef<DataSourceSurface> UnpremultiplyDataSurface(DataSourceSurface* aSurface);
static void ConvertBGRAtoRGBA(gfxImageSurface *aSourceSurface,

Просмотреть файл

@ -188,12 +188,12 @@ nsresult nsDateTimeFormatMac::FormatTMTime(nsILocale* locale,
CFSTR("h"), CFSTR("H"),
CFRangeMake(0, CFStringGetLength(newFormat)),
0);
NS_ASSERTION(replaceCount == 1, "Unexpected number of \"h\" occurrences");
NS_ASSERTION(replaceCount <= 2, "Unexpected number of \"h\" occurrences");
replaceCount = CFStringFindAndReplace(newFormat,
CFSTR("a"), CFSTR(""),
CFRangeMake(0, CFStringGetLength(newFormat)),
0);
NS_ASSERTION(replaceCount == 1, "Unexpected number of \"a\" occurrences");
NS_ASSERTION(replaceCount <= 1, "Unexpected number of \"a\" occurrences");
CFDateFormatterSetFormat(formatter, newFormat);
CFRelease(newFormat); // note we don't own oldFormat
}

Просмотреть файл

@ -1048,7 +1048,7 @@ InitClass(JSContext *cx, Handle<GlobalObject*> global, const Class *clasp, JSPro
return nullptr;
proto->setPrivate(nullptr);
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 0));
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 1));
if (!ctor ||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
!DefinePropertiesAndBrand(cx, proto, properties, methods) ||

Просмотреть файл

@ -3675,15 +3675,15 @@ else
fi
AC_SUBST(CL_INCLUDES_PREFIX)
rm -f dummy-hello.c
dnl Make sure that the build system can handle non-ASCII characters
dnl in environment variables to prevent it from breaking silently on
dnl non-English systems.
NONASCII=$'\241\241'
AC_SUBST(NONASCII)
fi
fi
dnl Make sure that the build system can handle non-ASCII characters
dnl in environment variables to prevent it from breking silently on
dnl non-English systems.
NONASCII=$'\241\241'
AC_SUBST(NONASCII)
dnl ========================================================
dnl = Disable -fstrict-aliasing with GCC 4.4 and earlier.
dnl = See bugs 821502 and 832623.

Просмотреть файл

@ -0,0 +1,64 @@
var count = 0;
function Parent() {
// Scanning "this" properties here with Object.keys() solved the bug in my case
//Object.keys(this);
this.log('Parent ctor');
this.meth1();
this.log('data3 before : ' + this.data3);
this.meth2();
// Added properties lost in ChildA
this.log('data3 after : ' + this.data3);
this.log('');
if (count++)
assertEq(this.data3, 'z');
}
Parent.prototype.meth1 = function () {
this.log('Parent.meth1()');
};
Parent.prototype.meth2 = function () {
this.log('Parent.meth2()');
// Requirement for the bug : Parent.meth2() needs to add data
this.data4 = 'x';
};
Parent.prototype.log = function (data) {
print(data);
}
// Intermediate constructor to instantiate children prototype without executing Parent constructor code
function ParentEmptyCtor() { }
ParentEmptyCtor.prototype = Parent.prototype;
function ChildA() {
this.log('ChildA ctor');
Parent.call(this);
}
ChildA.prototype = new ParentEmptyCtor();
// Using Object.create() instead solves the bug
//ChildA.prototype = Object.create(ParentEmptyCtor.prototype);
ChildA.prototype.constructor = ChildA;
ChildA.prototype.meth1 = function () {
this.log('ChildA.meth1()');
this.data3 = 'z';
};
ChildA.prototype.meth2 = function () {
this.log('ChildA.meth2()');
};
function ChildB() {
this.log('ChildB ctor');
Parent.call(this);
}
ChildB.prototype = new ParentEmptyCtor();
//ChildB.prototype = Object.create(ParentEmptyCtor.prototype);
ChildB.prototype.constructor = ChildB;
function demo() {
// Requirement for the bug : ChildB needs to be instantiated before ChildA
new ChildB();
new ChildA();
}
demo();

Просмотреть файл

@ -9,7 +9,7 @@ assertEq(desc.writable, true);
assertEq(typeof Map, 'function');
assertEq(Object.keys(Map).length, 0);
assertEq(Map.length, 0);
assertEq(Map.length, 1);
assertEq(Map.name, "Map");
assertEq(Object.getPrototypeOf(Map.prototype), Object.prototype);

Просмотреть файл

@ -9,7 +9,7 @@ assertEq(desc.writable, true);
assertEq(typeof Set, 'function');
assertEq(Object.keys(Set).length, 0);
assertEq(Set.length, 0);
assertEq(Set.length, 1);
assertEq(Set.name, "Set");
assertEq(Object.getPrototypeOf(Set.prototype), Object.prototype);

Просмотреть файл

@ -0,0 +1,35 @@
// WeakMap surfaces
var desc = Object.getOwnPropertyDescriptor(this, "WeakMap");
assertEq(desc.enumerable, false);
assertEq(desc.configurable, true);
assertEq(desc.writable, true);
assertEq(typeof WeakMap, 'function');
assertEq(Object.keys(WeakMap).length, 0);
assertEq(WeakMap.length, 1);
assertEq(WeakMap.name, "WeakMap");
assertEq(Object.getPrototypeOf(WeakMap.prototype), Object.prototype);
assertEq(Object.prototype.toString.call(WeakMap.prototype), "[object WeakMap]");
assertEq(Object.prototype.toString.call(new WeakMap), "[object WeakMap]");
assertEq(Object.prototype.toString.call(WeakMap()), "[object WeakMap]");
assertEq(Object.keys(WeakMap.prototype).join(), "");
assertEq(WeakMap.prototype.constructor, WeakMap);
function checkMethod(name, arity) {
var desc = Object.getOwnPropertyDescriptor(WeakMap.prototype, name);
assertEq(desc.enumerable, false);
assertEq(desc.configurable, true);
assertEq(desc.writable, true);
assertEq(typeof desc.value, 'function');
assertEq(desc.value.name, name);
assertEq(desc.value.length, arity);
}
// XXX: WeakMap#get implementation has an undocumented 2nd argument
//checkMethod("get", 1);
checkMethod("has", 1);
checkMethod("set", 2);
checkMethod("delete", 1);
checkMethod("clear", 0);

Просмотреть файл

@ -2147,14 +2147,10 @@ AnalyzePoppedThis(JSContext *cx, types::TypeObject *type,
JS_ASSERT(!baseobj->inDictionaryMode());
Vector<MResumePoint *> callerResumePoints(cx);
MBasicBlock *block = ins->block();
for (MResumePoint *rp = block->callerResumePoint();
for (MResumePoint *rp = ins->block()->callerResumePoint();
rp;
block = rp->block(), rp = block->callerResumePoint())
rp = rp->block()->callerResumePoint())
{
JSScript *script = rp->block()->info().script();
if (!types::AddClearDefiniteFunctionUsesInScript(cx, type, script, block->info().script()))
return true;
if (!callerResumePoints.append(rp))
return false;
}
@ -2373,7 +2369,24 @@ jit::AnalyzeNewScriptProperties(JSContext *cx, JSFunction *fun,
return false;
}
if (!handled)
return true;
break;
}
if (baseobj->slotSpan() != 0) {
// We found some definite properties, but their correctness is still
// contingent on the correct frames being inlined. Add constraints to
// invalidate the definite properties if additional functions could be
// called at the inline frame sites.
Vector<MBasicBlock *> exitBlocks(cx);
for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) {
if (MResumePoint *rp = block->callerResumePoint()) {
if (block->numPredecessors() == 1 && block->getPredecessor(0) == rp->block()) {
JSScript *script = rp->block()->info().script();
if (!types::AddClearDefiniteFunctionUsesInScript(cx, type, script, block->info().script()))
return false;
}
}
}
}
return true;

Просмотреть файл

@ -4193,6 +4193,11 @@ IonBuilder::selectInliningTargets(ObjectVector &targets, CallInfo &callInfo, Boo
if (!choiceSet.reserve(targets.length()))
return false;
// Don't inline polymorphic sites during the definite properties analysis.
// AddClearDefiniteFunctionUsesInScript depends on this for correctness.
if (info().executionMode() == DefinitePropertiesAnalysis && targets.length() > 1)
return true;
for (size_t i = 0; i < targets.length(); i++) {
JSFunction *target = &targets[i]->as<JSFunction>();
bool inlineable;

Просмотреть файл

@ -23,6 +23,3 @@ JSAPI_TESTS_AUTOLOAD := jsapi-tests-gdb.py.in
JSAPI_TESTS_AUTOLOAD_FLAGS := -Dtopsrcdir=$(abspath $(srcdir)/..)
include $(topsrcdir)/config/rules.mk
check::
$(wildcard $(RUN_TEST_PROGRAM)) $(DIST)/bin/jsapi-tests$(BIN_SUFFIX)

Просмотреть файл

@ -3360,7 +3360,9 @@ types::AddClearDefiniteFunctionUsesInScript(JSContext *cx, TypeObject *type,
// |script|, and add constraints to ensure that if the type sets' contents
// change then the definite properties are cleared from the type.
// This ensures that the inlining performed when the definite properties
// analysis was done is stable.
// analysis was done is stable. We only need to look at type sets which
// contain a single object, as IonBuilder does not inline polymorphic sites
// during the definite properties analysis.
TypeObjectKey *calleeKey = Type::ObjectType(calleeScript->functionNonDelazifying()).objectKey();

Просмотреть файл

@ -500,7 +500,7 @@ js_InitWeakMapClass(JSContext *cx, HandleObject obj)
return nullptr;
RootedFunction ctor(cx, global->createConstructor(cx, WeakMap_construct,
cx->names().WeakMap, 0));
cx->names().WeakMap, 1));
if (!ctor)
return nullptr;

Просмотреть файл

@ -3501,14 +3501,15 @@ Parent(JSContext *cx, unsigned argc, jsval *vp)
}
Rooted<JSObject*> parent(cx, JS_GetParent(&v.toObject()));
args.rval().setObjectOrNull(parent);
/* Outerize if necessary. Embrace the ugliness! */
/* Outerize if necessary. */
if (parent) {
if (js::ObjectOp op = parent->getClass()->ext.outerObject)
args.rval().setObjectOrNull(op(cx, parent));
parent = GetOuterObject(cx, parent);
if (!parent)
return false;
}
args.rval().setObjectOrNull(parent);
return true;
}

Просмотреть файл

@ -582,13 +582,15 @@ TraceLogger::startEvent(uint32_t id)
return;
}
if (!tree.ensureSpaceBeforeAdd()) {
if (!tree.hasSpaceForAdd()){
uint64_t start = rdtsc() - traceLoggers.startupTime;
if (!flush()) {
fprintf(stderr, "TraceLogging: Couldn't write the data to disk.\n");
enabled = false;
failed = true;
return;
if (!tree.ensureSpaceBeforeAdd()) {
if (!flush()) {
fprintf(stderr, "TraceLogging: Couldn't write the data to disk.\n");
enabled = false;
failed = true;
return;
}
}
// Log the time it took to flush the events as being from the

Просмотреть файл

@ -203,9 +203,15 @@ class ContinuousSpace {
return data()[currentId()];
}
bool ensureSpaceBeforeAdd(uint32_t count = 1) {
bool hasSpaceForAdd(uint32_t count = 1) {
if (next_ + count <= capacity_)
return true;
return false;
}
bool ensureSpaceBeforeAdd(uint32_t count = 1) {
if (hasSpaceForAdd(count))
return true;
uint32_t nCapacity = capacity_ * 2;
if (next_ + count > nCapacity)

Просмотреть файл

@ -143,11 +143,11 @@ xpc_qsDefineQuickStubs(JSContext *cx, JSObject *protoArg, unsigned flags,
if (entry->newBindingProperties) {
if (entry->newBindingProperties->regular) {
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->regular, false);
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->regular);
}
if (entry->newBindingProperties->chromeOnly &&
xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) {
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->chromeOnly, false);
mozilla::dom::DefineWebIDLBindingPropertiesOnXPCObject(cx, proto, entry->newBindingProperties->chromeOnly);
}
}
// Next.

Просмотреть файл

@ -78,8 +78,10 @@ XPCWrappedNativeScope::XPCWrappedNativeScope(JSContext *cx,
// add ourselves to the scopes list
{
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(js::GetObjectClass(aGlobal)->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS |
JSCLASS_HAS_PRIVATE));
DebugOnly<const js::Class*> clasp = js::GetObjectClass(aGlobal);
MOZ_ASSERT(clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS |
JSCLASS_HAS_PRIVATE) ||
mozilla::dom::IsDOMClass(clasp));
#ifdef DEBUG
for (XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext)
MOZ_ASSERT(aGlobal != cur->GetGlobalJSObjectPreserveColor(), "dup object");

Просмотреть файл

@ -328,36 +328,9 @@ nsXPConnect::InitClasses(JSContext * aJSContext, JSObject * aGlobalJSObj)
return NS_OK;
}
#ifdef DEBUG
static void
VerifyTraceXPCGlobalCalled(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
// We don't do anything here, we only want to verify that TraceXPCGlobal
// was called.
}
struct VerifyTraceXPCGlobalCalledTracer : public JSTracer
{
bool ok;
VerifyTraceXPCGlobalCalledTracer(JSRuntime *rt)
: JSTracer(rt, VerifyTraceXPCGlobalCalled), ok(false)
{}
};
#endif
void
TraceXPCGlobal(JSTracer *trc, JSObject *obj)
{
#ifdef DEBUG
if (trc->callback == VerifyTraceXPCGlobalCalled) {
// We don't do anything here, we only want to verify that TraceXPCGlobal
// was called.
reinterpret_cast<VerifyTraceXPCGlobalCalledTracer*>(trc)->ok = true;
return;
}
#endif
if (js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL)
mozilla::dom::TraceProtoAndIfaceCache(trc, obj);
}
@ -388,7 +361,7 @@ CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal,
// more complicated. Manual inspection shows that they do the right thing.
if (!((const js::Class*)clasp)->ext.isWrappedNative)
{
VerifyTraceXPCGlobalCalledTracer trc(JS_GetRuntime(cx));
VerifyTraceProtoAndIfaceCacheCalledTracer trc(JS_GetRuntime(cx));
JS_TraceChildren(&trc, global, JSTRACE_OBJECT);
MOZ_ASSERT(trc.ok, "Trace hook on global needs to call TraceXPCGlobal for XPConnect compartments.");
}

Просмотреть файл

@ -3399,6 +3399,8 @@ JSObject *
CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal,
JS::CompartmentOptions& aOptions);
// InitGlobalObject enters the compartment of aGlobal, so it doesn't matter what
// compartment aJSContext is in.
bool
InitGlobalObject(JSContext* aJSContext, JS::Handle<JSObject*> aGlobal,
uint32_t aFlags);

Просмотреть файл

@ -275,13 +275,15 @@ DisplayItemClip::RemoveRoundedCorners()
mRoundedClipRects.Clear();
}
// Computes the difference between aR1 and aR2, limited to aBounds.
static void
AccumulateRectDifference(const nsRect& aR1, const nsRect& aR2, nsRegion* aOut)
AccumulateRectDifference(const nsRect& aR1, const nsRect& aR2, const nsRect& aBounds, nsRegion* aOut)
{
if (aR1.IsEqualInterior(aR2))
return;
nsRegion r;
r.Xor(aR1, aR2);
r.And(r, aBounds);
aOut->Or(*aOut, r);
}
@ -299,8 +301,8 @@ DisplayItemClip::AddOffsetAndComputeDifference(const nsPoint& aOffset,
return;
}
if (mHaveClipRect) {
AccumulateRectDifference((mClipRect + aOffset).Intersect(aBounds),
aOther.mClipRect.Intersect(aOtherBounds),
AccumulateRectDifference(mClipRect + aOffset, aOther.mClipRect,
aBounds.Union(aOtherBounds),
aDifference);
}
for (uint32_t i = 0; i < mRoundedClipRects.Length(); ++i) {

Просмотреть файл

@ -1472,6 +1472,11 @@ ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aAnimatedGeometryRoot
if (!FuzzyEqual(data->mXScale, mParameters.mXScale, 0.00001f) ||
!FuzzyEqual(data->mYScale, mParameters.mYScale, 0.00001f) ||
data->mAppUnitsPerDevPixel != mAppUnitsPerDevPixel) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf_stderr("Recycled layer %p changed scale\n", layer.get());
}
#endif
InvalidateEntireThebesLayer(layer, aAnimatedGeometryRoot);
#ifndef MOZ_ANDROID_OMTC
didResetScrollPositionForLayerPixelAlignment = true;
@ -3107,7 +3112,9 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
// Set any matrix entries close to integers to be those exact integers.
// This protects against floating-point inaccuracies causing problems
// in the checks below.
transform.NudgeToIntegers();
// We use the fixed epsilon version here because we don't want the nudging
// to depend on the scroll position.
transform.NudgeToIntegersFixedEpsilon();
}
gfxMatrix transform2d;
if (aContainerFrame &&

Просмотреть файл

@ -4511,7 +4511,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const FrameTransformProperties&
nsIFrame** aOutAncestor)
{
return GetResultingTransformMatrixInternal(aProperties, aOrigin, aAppUnitsPerPixel,
aBoundsOverride, aOutAncestor);
aBoundsOverride, aOutAncestor, false);
}
gfx3DMatrix
@ -4519,14 +4519,16 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
const nsPoint& aOrigin,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride,
nsIFrame** aOutAncestor)
nsIFrame** aOutAncestor,
bool aOffsetByOrigin)
{
FrameTransformProperties props(aFrame,
aAppUnitsPerPixel,
aBoundsOverride);
return GetResultingTransformMatrixInternal(props, aOrigin, aAppUnitsPerPixel,
aBoundsOverride, aOutAncestor);
return GetResultingTransformMatrixInternal(props, aOrigin, aAppUnitsPerPixel,
aBoundsOverride, aOutAncestor,
aOffsetByOrigin);
}
gfx3DMatrix
@ -4534,7 +4536,8 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
const nsPoint& aOrigin,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride,
nsIFrame** aOutAncestor)
nsIFrame** aOutAncestor,
bool aOffsetByOrigin)
{
const nsIFrame *frame = aProperties.mFrame;
@ -4542,14 +4545,6 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
*aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(frame);
}
/* Account for the -moz-transform-origin property by translating the
* coordinate space to the new origin.
*/
gfxPoint3D newOrigin =
gfxPoint3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
0.0f);
/* Get the underlying transform matrix. This requires us to get the
* bounds of the frame.
*/
@ -4598,28 +4593,51 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
result = result * nsLayoutUtils::ChangeMatrixBasis(aProperties.mToPerspectiveOrigin - aProperties.mToTransformOrigin, perspective);
}
gfxPoint3D rounded(hasSVGTransforms ? newOrigin.x : NS_round(newOrigin.x),
hasSVGTransforms ? newOrigin.y : NS_round(newOrigin.y),
0);
/* Account for the -moz-transform-origin property by translating the
* coordinate space to the new origin.
*/
gfxPoint3D newOrigin =
gfxPoint3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
0.0f);
gfxPoint3D roundedOrigin(hasSVGTransforms ? newOrigin.x : NS_round(newOrigin.x),
hasSVGTransforms ? newOrigin.y : NS_round(newOrigin.y),
0);
gfxPoint3D offsetBetweenOrigins = roundedOrigin + aProperties.mToTransformOrigin;
if (frame && frame->Preserves3D()) {
// Include the transform set on our parent
NS_ASSERTION(frame->GetParent() &&
frame->GetParent()->IsTransformed() &&
frame->GetParent()->Preserves3DChildren(),
"Preserve3D mismatch!");
FrameTransformProperties props(frame->GetParent(),
aAppUnitsPerPixel,
nullptr);
gfx3DMatrix parent =
GetResultingTransformMatrixInternal(props,
aOrigin - frame->GetPosition(),
aAppUnitsPerPixel, nullptr, aOutAncestor);
return nsLayoutUtils::ChangeMatrixBasis(rounded + aProperties.mToTransformOrigin, result) * parent;
// Include the transform set on our parent
NS_ASSERTION(frame->GetParent() &&
frame->GetParent()->IsTransformed() &&
frame->GetParent()->Preserves3DChildren(),
"Preserve3D mismatch!");
FrameTransformProperties props(frame->GetParent(),
aAppUnitsPerPixel,
nullptr);
gfx3DMatrix parent =
GetResultingTransformMatrixInternal(props,
aOrigin - frame->GetPosition(),
aAppUnitsPerPixel, nullptr,
aOutAncestor, false);
result = nsLayoutUtils::ChangeMatrixBasis(offsetBetweenOrigins, result) * parent;
if (aOffsetByOrigin) {
result.Translate(roundedOrigin);
}
return result;
}
return nsLayoutUtils::ChangeMatrixBasis
(rounded + aProperties.mToTransformOrigin, result);
if (aOffsetByOrigin) {
// We can fold the final translation by roundedOrigin into the first matrix
// basis change translation. This is more stable against variation due to
// insufficient floating point precision than reversing the translation
// afterwards.
result.Translate(-aProperties.mToTransformOrigin);
result.TranslatePost(offsetBetweenOrigins);
} else {
result = nsLayoutUtils::ChangeMatrixBasis(offsetBetweenOrigins, result);
}
return result;
}
bool
@ -4726,19 +4744,17 @@ nsDisplayTransform::GetTransform()
mTransform = mTransformGetter(mFrame, scale);
mTransform = nsLayoutUtils::ChangeMatrixBasis(newOrigin, mTransform);
} else {
mTransform =
GetResultingTransformMatrix(mFrame, ToReferenceFrame(), scale);
/**
* Shift the coorindates to be relative to our reference frame instead of relative to this frame.
* When we have preserve-3d, our reference frame is already guaranteed to be an ancestor of the
* preserve-3d chain, so we only need to do this once.
* Passing true as the final argument means that we want to shift the
* coordinates to be relative to our reference frame instead of relative
* to this frame.
* When we have preserve-3d, our reference frame is already guaranteed
* to be an ancestor of the preserve-3d chain, so we only need to do
* this once.
*/
bool hasSVGTransforms = mFrame->IsSVGTransformed();
gfxPoint3D rounded(hasSVGTransforms ? newOrigin.x : NS_round(newOrigin.x),
hasSVGTransforms ? newOrigin.y : NS_round(newOrigin.y),
0);
mTransform.Translate(rounded);
mTransform =
GetResultingTransformMatrix(mFrame, ToReferenceFrame(), scale,
nullptr, nullptr, true);
}
}
return mTransform;

Просмотреть файл

@ -3345,12 +3345,15 @@ public:
* for the frame's bounding rectangle. Otherwise, it will use the
* value of aBoundsOverride. This is mostly for internal use and in
* most cases you will not need to specify a value.
* @param aOffsetByOrigin If true, the resulting matrix will be translated
* by aOrigin. This translation is applied *before* the CSS transform.
*/
static gfx3DMatrix GetResultingTransformMatrix(const nsIFrame* aFrame,
const nsPoint& aOrigin,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride = nullptr,
nsIFrame** aOutAncestor = nullptr);
nsIFrame** aOutAncestor = nullptr,
bool aOffsetByOrigin = false);
static gfx3DMatrix GetResultingTransformMatrix(const FrameTransformProperties& aProperties,
const nsPoint& aOrigin,
float aAppUnitsPerPixel,
@ -3372,7 +3375,8 @@ private:
const nsPoint& aOrigin,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride,
nsIFrame** aOutAncestor);
nsIFrame** aOutAncestor,
bool aOffsetByOrigin);
nsDisplayWrapList mStoredList;
gfx3DMatrix mTransform;

Просмотреть файл

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
li::-moz-list-bullet {
direction: rtl;
margin-right: 1em;
}
</style>
</head>
<body>
Body
<ul>
<li>list item</li>
</ul>
</body>
</html>

Просмотреть файл

@ -528,5 +528,6 @@ test-pref(layout.css.sticky.enabled,true) load 949932.html
load 973701-1.xhtml
load 973701-2.xhtml
load 986899.html
load 1001233.html
load 1001258-1.html
load outline-on-frameset.xhtml

Просмотреть файл

@ -6832,18 +6832,26 @@ nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
// in the current writing mode. Then we subtract out the start
// border/padding and the bullet's width and margin to offset the position.
WritingMode wm = rs.GetWritingMode();
LogicalRect logicalFAS(wm, floatAvailSpace, floatAvailSpace.XMost());
nscoord containerWidth = floatAvailSpace.XMost();
LogicalRect logicalFAS(wm, floatAvailSpace, containerWidth);
// Get the bullet's margin, converted to our writing mode so that we can
// combine it with other logical values here.
WritingMode bulletWM = reflowState.GetWritingMode();
LogicalMargin bulletMargin =
reflowState.ComputedLogicalMargin().ConvertTo(wm, bulletWM);
nscoord iStart = logicalFAS.IStart(wm) -
rs.ComputedLogicalBorderPadding().IStart(wm)
- reflowState.ComputedLogicalMargin().IEnd(wm) - aMetrics.ISize();
rs.ComputedLogicalBorderPadding().IStart(wm) -
bulletMargin.IEnd(wm) -
aMetrics.ISize();
// Approximate the bullets position; vertical alignment will provide
// the final vertical location.
// the final vertical location. We pass our writing-mode here, because
// it may be different from the bullet frame's mode.
nscoord bStart = logicalFAS.BStart(wm);
aBulletFrame->SetRect(LogicalRect(wm, LogicalPoint(wm, iStart, bStart),
LogicalSize(wm, aMetrics.ISize(),
aMetrics.BSize())),
floatAvailSpace.XMost());
aBulletFrame->SetRect(wm, LogicalRect(wm, LogicalPoint(wm, iStart, bStart),
LogicalSize(wm, aMetrics.ISize(),
aMetrics.BSize())),
containerWidth);
aBulletFrame->DidReflow(aState.mPresContext, &aState.mReflowState,
nsDidReflowStatus::FINISHED);
}

Просмотреть файл

@ -1878,7 +1878,7 @@ void ScrollFrameHelper::MarkInactive()
return;
mScrollingActive = false;
mOuter->InvalidateFrameSubtree();
mOuter->SchedulePaint();
}
void ScrollFrameHelper::MarkActive()

Просмотреть файл

@ -1796,7 +1796,7 @@ fails == 942017.html 942017-ref.html # bug 942017
== 950436-1.html 950436-1-ref.html
== 957770-1.svg 957770-1-ref.svg
== 960277-1.html 960277-1-ref.html
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,10) == 966992-1.html 966992-1-ref.html
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,31) == 966992-1.html 966992-1-ref.html
skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed
skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above
== 978911-1.svg 978911-1-ref.svg

Просмотреть файл

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Scrolling the horizontal bar away shouldn't invalidate the green rectangle</title>
<style>
.wrapper {
transform: translateY(1px);
}
.content {
box-sizing: border-box;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.first {
height: 20px;
}
.second {
margin-left: auto;
width: 20px;
height: 200px;
}
.reftest-no-paint {
margin: -150px 100px 0;
height: 100px;
border-color: lime;
}
body {
margin: 0;
padding: 50px;
height: 3000px;
}
</style>
<div class="wrapper">
<div class="first content"></div>
<div class="second content"></div>
</div>
<div class="reftest-no-paint content"></div>
<script>
function doTest() {
document.documentElement.scrollTop = 100;
document.documentElement.removeAttribute("class");
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>

Просмотреть файл

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Scrolling the horizontal bar away shouldn't invalidate the green rectangle</title>
<style>
.wrapper {
transform: translateY(1px);
}
.content {
box-sizing: border-box;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.first {
height: 20px;
}
.second {
margin-left: auto;
width: 20px;
height: 200px;
}
.reftest-no-paint {
margin: -150px 100px 0;
height: 100px;
border-color: lime;
}
body {
margin: 0;
padding: 50px;
height: 3000px;
}
</style>
<div class="wrapper">
<div class="wrapper">
<div class="first content"></div>
<div class="second content"></div>
</div>
</div>
<div class="reftest-no-paint content"></div>
<script>
function doTest() {
document.documentElement.scrollTop = 100;
document.documentElement.removeAttribute("class");
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>

Просмотреть файл

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Different epsilons in NudeToInteger and FuzzyEqual cause invalidations</title>
<body>
<svg viewBox="0 0 700 3000" width="700px" height="3000px">
<g transform="translate(0, -220.999756)">
<rect x="100" y="400" height="50" width="50" fill="grey" class="reftest-no-paint"/>
</g>
</svg>
<script>
var scrollPositions = [0, 50];
if (location.search.contains("reverse")) {
scrollPositions.reverse();
}
document.documentElement.scrollTop = scrollPositions[0];
function doTest() {
document.documentElement.scrollTop = scrollPositions[1];
document.documentElement.removeAttribute("class");
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>

Просмотреть файл

@ -40,3 +40,9 @@ pref(layout.animated-image-layers.enabled,true) == test-animated-image-layers-ba
== filter-userspace-offset.svg?offsetContainer=rect&filter=matrix-fillPaint-userSpace-at100 filter-userspace-offset.svg
== scroll-inactive-layers.html scroll-inactive-layers.html
== scroll-inactive-layers-2.html scroll-inactive-layers-2.html
!= inactive-layertree-visible-region-1.html about:blank
!= inactive-layertree-visible-region-2.html about:blank
!= transform-floating-point-invalidation.html about:blank
!= transform-floating-point-invalidation.html?reverse about:blank
!= nudge-to-integer-invalidation.html about:blank
!= nudge-to-integer-invalidation.html?reverse about:blank

Просмотреть файл

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>Scrolling shouldn't invalidate the rect</title>
<body>
<svg width="824" height="1375" viewBox="0 0 660 1100">
<rect x="100" y="600" width="120" height="120" fill="#EEE"
transform="matrix(0,0.969665,-2.0321494,0,1828.58132,65.718239)"
class="reftest-no-paint"/>
</svg>
<script>
var scrollPositions = [81, 82];
if (location.search.contains("reverse")) {
scrollPositions.reverse();
}
document.documentElement.scrollTop = scrollPositions[0];
function doTest() {
document.documentElement.scrollTop = scrollPositions[1];
document.documentElement.removeAttribute("class");
}
document.addEventListener("MozReftestInvalidate", doTest, false);
</script>

Просмотреть файл

@ -1470,6 +1470,18 @@ PeerConnectionImpl::SetDtlsConnected(bool aPrivacyRequested)
return NS_OK;
}
#ifdef MOZILLA_INTERNAL_API
void
PeerConnectionImpl::PrincipalChanged(DOMMediaStream* aMediaStream) {
nsIDocument* doc = GetWindow()->GetExtantDoc();
if (doc) {
mMedia->UpdateSinkIdentity_m(doc->NodePrincipal(), mPeerIdentity);
} else {
CSFLogInfo(logTag, "Can't update sink principal; document gone");
}
}
#endif
nsresult
PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream,
const MediaConstraintsInternal& aConstraints)
@ -1511,6 +1523,8 @@ PeerConnectionImpl::AddStream(DOMMediaStream &aMediaStream,
return res;
}
aMediaStream.AddPrincipalChangeObserver(this);
// TODO(ekr@rtfm.com): these integers should be the track IDs
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
cc_media_constraints_t* cc_constraints = aConstraints.build();
@ -1539,6 +1553,8 @@ PeerConnectionImpl::RemoveStream(DOMMediaStream& aMediaStream) {
if (NS_FAILED(res))
return res;
aMediaStream.RemovePrincipalChangeObserver(this);
uint32_t hints = aMediaStream.GetHintContents();
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
@ -1751,6 +1767,12 @@ PeerConnectionImpl::ShutdownMedia()
return;
#ifdef MOZILLA_INTERNAL_API
// before we destroy references to local streams, detach from them
for(uint32_t i = 0; i < media()->LocalStreamsLength(); ++i) {
LocalSourceStreamInfo *info = media()->GetLocalStream(i);
info->GetMediaStream()->RemovePrincipalChangeObserver(this);
}
// End of call to be recorded in Telemetry
if (!mStartTime.IsNull()){
TimeDuration timeDelta = TimeStamp::Now() - mStartTime;

Просмотреть файл

@ -38,6 +38,9 @@
#include "mozilla/dom/RTCStatsReportBinding.h"
#include "nsIPrincipal.h"
#include "mozilla/PeerIdentity.h"
#ifndef USE_FAKE_MEDIA_STREAMS
#include "DOMMediaStream.h"
#endif
#endif
namespace test {
@ -197,6 +200,7 @@ class PeerConnectionImpl MOZ_FINAL : public nsISupports,
#ifdef MOZILLA_INTERNAL_API
public mozilla::DataChannelConnection::DataConnectionListener,
public nsNSSShutDownObject,
public DOMMediaStream::PrincipalChangeObserver,
#endif
public sigslot::has_slots<>
{
@ -552,6 +556,10 @@ public:
RTCStatsQuery *query);
static nsresult ExecuteStatsQuery_s(RTCStatsQuery *query);
// for monitoring changes in stream ownership
// PeerConnectionMedia can't do it because it doesn't know about principals
virtual void PrincipalChanged(DOMMediaStream* aMediaStream) MOZ_OVERRIDE;
#endif
private:

Просмотреть файл

@ -244,6 +244,14 @@ public:
void SetTrackEnabled(mozilla::TrackID aTrackID, bool aEnabled) {}
class PrincipalChangeObserver
{
public:
virtual void PrincipalChanged(Fake_DOMMediaStream* aMediaStream) = 0;
};
void AddPrincipalChangeObserver(void* ignoredObserver) {}
void RemovePrincipalChangeObserver(void* ignoredObserver) {}
private:
nsRefPtr<Fake_MediaStream> mMediaStream;

Просмотреть файл

@ -31,6 +31,15 @@ add_task(function test_AndroidLog() {
do_check_eq(48, AndroidLog.w.bind(null, "AndroidLogTest")("This is a warning message."));
do_check_eq(47, AndroidLog.e.bind(null, "AndroidLogTest")("This is an error message."));
// Ensure the functions work when the tag length is greater than the maximum
// tag length.
let tag = "X".repeat(AndroidLog.MAX_TAG_LENGTH + 1);
do_check_eq(AndroidLog.MAX_TAG_LENGTH + 54, AndroidLog.v(tag, "This is a verbose message with a too-long tag."));
do_check_eq(AndroidLog.MAX_TAG_LENGTH + 52, AndroidLog.d(tag, "This is a debug message with a too-long tag."));
do_check_eq(AndroidLog.MAX_TAG_LENGTH + 52, AndroidLog.i(tag, "This is an info message with a too-long tag."));
do_check_eq(AndroidLog.MAX_TAG_LENGTH + 54, AndroidLog.w(tag, "This is a warning message with a too-long tag."));
do_check_eq(AndroidLog.MAX_TAG_LENGTH + 53, AndroidLog.e(tag, "This is an error message with a too-long tag."));
// We should also ensure that the module is accessible from a ChromeWorker,
// but there doesn't seem to be a way to load a ChromeWorker from this test.
});

Просмотреть файл

@ -29,7 +29,8 @@
* debug("This is a debug message.");
*
* Note: the module automatically prepends "Gecko" to the tag you specify,
* since all tags used by Fennec code should start with that string.
* since all tags used by Fennec code should start with that string; and it
* truncates tags longer than MAX_TAG_LENGTH characters (not including "Gecko").
*/
if (typeof Components != "undefined") {
@ -45,6 +46,12 @@ const ANDROID_LOG_INFO = 4;
const ANDROID_LOG_WARN = 5;
const ANDROID_LOG_ERROR = 6;
// android.util.Log.isLoggable throws IllegalArgumentException if a tag length
// exceeds 23 characters, and we prepend five characters ("Gecko") to every tag,
// so we truncate tags exceeding 18 characters (although __android_log_write
// itself and other android.util.Log methods don't seem to mind longer tags).
const MAX_TAG_LENGTH = 18;
let liblog = ctypes.open("liblog.so"); // /system/lib/liblog.so
let __android_log_write = liblog.declare("__android_log_write",
ctypes.default_abi,
@ -54,11 +61,12 @@ let __android_log_write = liblog.declare("__android_log_write",
ctypes.char.ptr); // message
let AndroidLog = {
v: (tag, msg) => __android_log_write(ANDROID_LOG_VERBOSE, "Gecko" + tag, msg),
d: (tag, msg) => __android_log_write(ANDROID_LOG_DEBUG, "Gecko" + tag, msg),
i: (tag, msg) => __android_log_write(ANDROID_LOG_INFO, "Gecko" + tag, msg),
w: (tag, msg) => __android_log_write(ANDROID_LOG_WARN, "Gecko" + tag, msg),
e: (tag, msg) => __android_log_write(ANDROID_LOG_ERROR, "Gecko" + tag, msg),
MAX_TAG_LENGTH: MAX_TAG_LENGTH,
v: (tag, msg) => __android_log_write(ANDROID_LOG_VERBOSE, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
d: (tag, msg) => __android_log_write(ANDROID_LOG_DEBUG, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
i: (tag, msg) => __android_log_write(ANDROID_LOG_INFO, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
w: (tag, msg) => __android_log_write(ANDROID_LOG_WARN, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
e: (tag, msg) => __android_log_write(ANDROID_LOG_ERROR, "Gecko" + tag.substring(0, MAX_TAG_LENGTH), msg),
};
if (typeof Components == "undefined") {

Просмотреть файл

@ -760,6 +760,8 @@ pref("dom.webapps.useCurrentProfile", false);
pref("dom.cycle_collector.incremental", true);
pref("dom.window_experimental_bindings", false);
// Parsing perf prefs. For now just mimic what the old code did.
#ifndef XP_WIN
pref("content.sink.pending_event_mode", 0);
@ -1940,6 +1942,13 @@ pref("layout.display-list.dump", false);
// heavily loaded.
pref("layout.frame_rate.precise", false);
// Is support for the Web Animations API enabled?
#ifdef RELEASE_BUILD
pref("dom.animations-api.core.enabled", false);
#else
pref("dom.animations-api.core.enabled", true);
#endif
// pref to permit users to make verified SOAP calls by default
pref("capability.policy.default.SOAPCall.invokeVerifySourceHeader", "allAccess");

Просмотреть файл

@ -74,10 +74,9 @@ nsTemporaryFileInputStream::ReadSegments(nsWriteSegmentFun writer,
nsresult rv = writer(this, closure, buf,
count - remainBufCount, bufCount, &write_result);
remainBufCount -= bufCount;
if (NS_SUCCEEDED(rv)) {
NS_ASSERTION(write_result <= bufCount,
"writer should not write more than we asked it to write");
}
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(write_result <= bufCount,
"writer should not write more than we asked it to write");
mStartPos += bufCount;
}
*result = count;

Просмотреть файл

@ -626,7 +626,6 @@ nsHttpConnectionMgr::ReportSpdyConnection(nsHttpConnection *conn,
if (!ent->mCoalescingKey.IsEmpty()) {
mSpdyPreferredHash.Put(ent->mCoalescingKey, ent);
ent->mSpdyPreferred = true;
preferred = ent;
}
} else if ((preferred != ent) &&
(joinedConnection = GetSpdyPreferredEnt(ent)) &&

Просмотреть файл

@ -715,7 +715,9 @@ DataChannelConnection::SctpDtlsOutput(void *addr, void *buffer, size_t length,
} else {
unsigned char *data = new unsigned char[length];
memcpy(data, buffer, length);
res = -1;
// Commented out since we have to Dispatch SendPacket to avoid deadlock"
// res = -1;
// XXX It might be worthwhile to add an assertion against the thread
// somehow getting into the DataChannel/SCTP code again, as
// DISPATCH_SYNC is not fully blocking. This may be tricky, as it

Просмотреть файл

@ -3171,7 +3171,6 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
uint32_t vrf_id;
lport = 0;
error = 0;
bindall = 1;
inp = (struct sctp_inpcb *)so->so_pcb;
#if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)

Просмотреть файл

@ -206,7 +206,6 @@ sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsign
ptr, number_left);
ctx->how_many_in_block += number_left;
ctx->running_total += number_left;
number_left = 0;
break;
} else {
/* block is now full, process it */

Просмотреть файл

@ -2782,7 +2782,6 @@ sctp_userspace_ip_output(int *result, struct mbuf *o_pak,
int use_udp_tunneling;
*result = 0;
send_count = 0;
m = SCTP_HEADER_TO_CHAIN(o_pak);
m_orig = m;
@ -2938,7 +2937,6 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
int use_udp_tunneling;
*result = 0;
send_count = 0;
m = SCTP_HEADER_TO_CHAIN(o_pak);
m_orig = m;

Просмотреть файл

@ -132,16 +132,10 @@ index_guess(const xtd_seq_num_t *local,
uint32_t local_roc = (uint32_t)(*local >> 16);
uint16_t local_seq = (uint16_t) *local;
#endif
#ifdef NO_64BIT_MATH
uint32_t guess_roc = ((high32(*guess) << 16) |
(low32(*guess) >> 16));
uint16_t guess_seq = (uint16_t) (low32(*guess));
#else
uint32_t guess_roc = (uint32_t)(*guess >> 16);
uint16_t guess_seq = (uint16_t) *guess;
#endif
uint32_t guess_roc;
uint16_t guess_seq;
int difference;
if (local_seq < seq_num_median) {
if (s - local_seq > seq_num_median) {
guess_roc = local_roc - 1;
@ -160,7 +154,7 @@ index_guess(const xtd_seq_num_t *local,
}
}
guess_seq = s;
/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
#ifdef NO_64BIT_MATH
*guess = make64(guess_roc >> 16,

Просмотреть файл

@ -166,7 +166,6 @@ srtp_stream_init_from_ekt(srtp_stream_t stream,
err_status_t err;
const uint8_t *master_key;
srtp_policy_t srtp_policy;
unsigned master_key_len;
uint32_t roc;
/*
@ -178,7 +177,6 @@ srtp_stream_init_from_ekt(srtp_stream_t stream,
if (stream->ekt->data->ekt_cipher_type != EKT_CIPHER_AES_128_ECB)
return err_status_bad_param;
master_key_len = 16;
/* decrypt the Encrypted Master Key field */
master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);

Просмотреть файл

@ -319,6 +319,11 @@ function _getBinaryUtil(binaryUtilName) {
utilBin.append("bin");
utilBin.append(binaryUtilName + (gIsWindows ? ".exe" : ""));
}
// But maybe we're on Android or B2G, where binaries are in /data/local/xpcb.
if (!utilBin.exists()) {
utilBin.initWithPath("/data/local/xpcb/");
utilBin.append(binaryUtilName);
}
do_check_true(utilBin.exists());
return utilBin;
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше