merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-02-19 12:02:26 +01:00
Родитель b845cb4d06 d4303cccdf
Коммит fd2c2d9b1a
329 изменённых файлов: 5324 добавлений и 3426 удалений

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

@ -52,7 +52,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHangingChildDocuments)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentInsertions)
for (auto it = tmp->mContentInsertions.ConstIter(); !it.Done(); it.Next()) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContentInsertions key");
cb.NoteXPCOMChild(it.Key());
nsTArray<nsCOMPtr<nsIContent>>* list = it.UserData();
for (uint32_t i = 0; i < list->Length(); i++) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
"mContentInsertions value item");
cb.NoteXPCOMChild(list->ElementAt(i));
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvents)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelocations)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -103,10 +112,23 @@ NotificationController::ScheduleContentInsertion(Accessible* aContainer,
nsIContent* aStartChildNode,
nsIContent* aEndChildNode)
{
RefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
aContainer);
if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
mContentInsertions.AppendElement(insertion)) {
nsTArray<nsCOMPtr<nsIContent>>* list =
mContentInsertions.LookupOrAdd(aContainer);
bool needsProcessing = false;
nsIContent* node = aStartChildNode;
while (node != aEndChildNode) {
// Notification triggers for content insertion even if no content was
// actually inserted, check if the given content has a frame to discard
// this case early.
if (node->GetPrimaryFrame()) {
if (list->AppendElement(node))
needsProcessing = true;
}
node = node->GetNextSibling();
}
if (needsProcessing) {
ScheduleProcessing();
}
}
@ -130,7 +152,7 @@ NotificationController::IsUpdatePending()
{
return mPresShell->IsLayoutFlushObserver() ||
mObservingState == eRefreshProcessingForUpdate ||
mContentInsertions.Length() != 0 || mNotifications.Length() != 0 ||
mContentInsertions.Count() != 0 || mNotifications.Length() != 0 ||
mTextHash.Count() != 0 ||
!mDocument->HasLoadState(DocAccessible::eTreeConstructed);
}
@ -178,7 +200,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mDocument->DoInitialUpdate();
NS_ASSERTION(mContentInsertions.Length() == 0,
NS_ASSERTION(mContentInsertions.Count() == 0,
"Pending content insertions while initial accessible tree isn't created!");
}
@ -196,15 +218,13 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
// document accessible.
// Process only currently queued content inserted notifications.
nsTArray<RefPtr<ContentInsertion> > contentInsertions;
contentInsertions.SwapElements(mContentInsertions);
uint32_t insertionCount = contentInsertions.Length();
for (uint32_t idx = 0; idx < insertionCount; idx++) {
contentInsertions[idx]->Process();
if (!mDocument)
for (auto iter = mContentInsertions.ConstIter(); !iter.Done(); iter.Next()) {
mDocument->ProcessContentInserted(iter.Key(), iter.UserData());
if (!mDocument) {
return;
}
}
mContentInsertions.Clear();
// Process rendered text change notifications.
for (auto iter = mTextHash.Iter(); !iter.Done(); iter.Next()) {
@ -403,7 +423,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
// Stop further processing if there are no new notifications of any kind or
// events and document load is processed.
if (mContentInsertions.IsEmpty() && mNotifications.IsEmpty() &&
if (mContentInsertions.Count() == 0 && mNotifications.IsEmpty() &&
mEvents.IsEmpty() && mTextHash.Count() == 0 &&
mHangingChildDocuments.IsEmpty() &&
mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
@ -411,53 +431,3 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mObservingState = eNotObservingRefresh;
}
}
////////////////////////////////////////////////////////////////////////////////
// NotificationController: content inserted notification
NotificationController::ContentInsertion::
ContentInsertion(DocAccessible* aDocument, Accessible* aContainer) :
mDocument(aDocument), mContainer(aContainer)
{
}
bool
NotificationController::ContentInsertion::
InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode)
{
bool haveToUpdate = false;
nsIContent* node = aStartChildNode;
while (node != aEndChildNode) {
// Notification triggers for content insertion even if no content was
// actually inserted, check if the given content has a frame to discard
// this case early.
if (node->GetPrimaryFrame()) {
if (mInsertedContent.AppendElement(node))
haveToUpdate = true;
}
node = node->GetNextSibling();
}
return haveToUpdate;
}
NS_IMPL_CYCLE_COLLECTION(NotificationController::ContentInsertion,
mContainer)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController::ContentInsertion,
AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController::ContentInsertion,
Release)
void
NotificationController::ContentInsertion::Process()
{
mDocument->ProcessContentInserted(mContainer, &mInsertedContent);
mDocument = nullptr;
mContainer = nullptr;
mInsertedContent.Clear();
}

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

@ -247,44 +247,10 @@ private:
nsTArray<RefPtr<DocAccessible> > mHangingChildDocuments;
/**
* Storage for content inserted notification information.
* Pending accessible tree update notifications for content insertions.
*/
class ContentInsertion
{
public:
ContentInsertion(DocAccessible* aDocument, Accessible* aContainer);
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ContentInsertion)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ContentInsertion)
bool InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode);
void Process();
protected:
virtual ~ContentInsertion() { mDocument = nullptr; }
private:
ContentInsertion();
ContentInsertion(const ContentInsertion&);
ContentInsertion& operator = (const ContentInsertion&);
// The document used to process content insertion, matched to document of
// the notification controller that this notification belongs to, therefore
// it's ok to keep it as weak ref.
DocAccessible* mDocument;
// The container accessible that content insertion occurs within.
RefPtr<Accessible> mContainer;
// Array of inserted contents.
nsTArray<nsCOMPtr<nsIContent> > mInsertedContent;
};
/**
* A pending accessible tree update notifications for content insertions.
* Don't make this an AutoTArray; we use SwapElements() on it.
*/
nsTArray<RefPtr<ContentInsertion> > mContentInsertions;
nsClassHashtable<nsRefPtrHashKey<Accessible>,
nsTArray<nsCOMPtr<nsIContent>>> mContentInsertions;
template<class T>
class nsCOMPtrHashKey : public PLDHashEntryHdr
@ -311,7 +277,7 @@ private:
};
/**
* A pending accessible tree update notifications for rendered text changes.
* Pending accessible tree update notifications for rendered text changes.
*/
nsTHashtable<nsCOMPtrHashKey<nsIContent> > mTextHash;

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

@ -46,7 +46,7 @@ TreeWalker::~TreeWalker()
// TreeWalker: private
Accessible*
TreeWalker::NextChild()
TreeWalker::Next()
{
if (mStateStack.IsEmpty())
return nullptr;
@ -82,7 +82,7 @@ TreeWalker::NextChild()
top = PushState(parent);
if (top->mDOMIter.Seek(mAnchorNode)) {
mAnchorNode = parent;
return NextChild();
return Next();
}
// XXX We really should never get here, it means we're trying to find an

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

@ -44,13 +44,13 @@ public:
~TreeWalker();
/**
* Return the next child accessible.
* Return the next accessible.
*
* @note Returned accessible is bound to the document, if the accessible is
* rejected during tree creation then the caller should be unbind it
* from the document.
*/
Accessible* NextChild();
Accessible* Next();
private:
TreeWalker();

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

@ -596,7 +596,7 @@ nsAccessibilityService::ContentRemoved(nsIPresShell* aPresShell,
Accessible* container = document->GetContainerAccessible(aChildNode);
a11y::TreeWalker walker(container ? container : document, aChildNode,
a11y::TreeWalker::eWalkCache);
child = walker.NextChild();
child = walker.Next();
}
if (child) {

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

@ -2508,7 +2508,7 @@ Accessible::CacheChildren()
TreeWalker walker(this, mContent);
Accessible* child = nullptr;
while ((child = walker.NextChild()) && AppendChild(child));
while ((child = walker.Next()) && AppendChild(child));
}
void

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

@ -1433,7 +1433,7 @@ DocAccessible::CacheChildren()
// Ignore last HTML:br, copied from HyperTextAccessible.
TreeWalker walker(this, rootElm);
Accessible* lastChild = nullptr;
while (Accessible* child = walker.NextChild()) {
while (Accessible* child = walker.Next()) {
if (lastChild)
AppendChild(lastChild);

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

@ -284,7 +284,7 @@ HyperTextAccessible::DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
if (container) {
TreeWalker walker(container, findNode->AsContent(),
TreeWalker::eWalkContextTree);
descendant = walker.NextChild();
descendant = walker.Next();
if (!descendant)
descendant = container;
}
@ -1945,7 +1945,7 @@ HyperTextAccessible::CacheChildren()
TreeWalker walker(this, mContent);
Accessible* child = nullptr;
Accessible* lastChild = nullptr;
while ((child = walker.NextChild())) {
while ((child = walker.Next())) {
if (lastChild)
AppendChild(lastChild);

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

@ -403,10 +403,10 @@ HTMLTableAccessible::CacheChildren()
TreeWalker walker(this, mContent);
Accessible* child = nullptr;
while ((child = walker.NextChild())) {
while ((child = walker.Next())) {
if (child->Role() == roles::CAPTION) {
InsertChildAt(0, child);
while ((child = walker.NextChild()) && AppendChild(child));
while ((child = walker.Next()) && AppendChild(child));
break;
}
AppendChild(child);

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

@ -1878,44 +1878,3 @@ var BookmarkingUI = {
Ci.nsINavBookmarkObserver
])
};
var AutoShowBookmarksToolbar = {
init() {
PlacesUtils.addLazyBookmarkObserver(this, false);
},
uninit() {
PlacesUtils.removeLazyBookmarkObserver(this);
},
onItemAdded(aItemId, aParentId, aIndex, aItemType, aURI, aTitle, aDateAdded,
aGuid, aParentGuid) {
this._autoshow(aParentGuid);
},
onBeginUpdateBatch() {},
onEndUpdateBatch() {},
onItemRemoved() {},
onItemChanged() {},
onItemVisited() {},
onItemMoved(aItemId, aOldParent, aOldIndex, aNewParent, aNewIndex, aItemType,
aGuid, aOldParentGuid, aNewParentGuid) {
this._autoshow(aNewParentGuid);
},
_autoshow(aParentGuid) {
if (aParentGuid != PlacesUtils.bookmarks.toolbarGuid)
return;
let toolbar = document.getElementById("PersonalToolbar");
if (!toolbar.collapsed)
return;
let placement = CustomizableUI.getPlacementOfWidget("personal-bookmarks");
let area = placement && placement.area;
if (area != CustomizableUI.AREA_BOOKMARKS)
return;
setToolbarVisibility(toolbar, true);
}
};

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

@ -1200,7 +1200,6 @@ var gBrowserInit = {
gBrowser.tabContainer.updateVisibility();
BookmarkingUI.init();
AutoShowBookmarksToolbar.init();
gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false);
@ -1504,7 +1503,6 @@ var gBrowserInit = {
IndexedDBPromptHelper.uninit();
LightweightThemeListener.uninit();
PanelUI.uninit();
AutoShowBookmarksToolbar.uninit();
}
// Final window teardown, do this last.
@ -4715,7 +4713,8 @@ nsBrowserAccess.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow, Ci.nsISupports]),
_openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
aIsExternal, aForceNotRemote=false) {
aIsExternal, aForceNotRemote=false,
aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID) {
let win, needToFocusWin;
// try the current window. if we're in a popup, fall back on the most recent browser window
@ -4742,6 +4741,7 @@ nsBrowserAccess.prototype = {
let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
referrerURI: aReferrer,
referrerPolicy: aReferrerPolicy,
userContextId: aUserContextId,
fromExternal: aIsExternal,
inBackground: loadInBackground,
forceNotRemote: aForceNotRemote});
@ -4814,9 +4814,12 @@ nsBrowserAccess.prototype = {
// will do the job of shuttling off the newly opened browser to run in
// the right process once it starts loading a URI.
let forceNotRemote = !!aOpener;
let userContextId = aOpener && aOpener.document
? aOpener.document.nodePrincipal.originAttributes.userContextId
: Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID;
let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
isPrivate, isExternal,
forceNotRemote);
forceNotRemote, userContextId);
if (browser)
newWindow = browser.contentWindow;
break;
@ -4845,9 +4848,17 @@ nsBrowserAccess.prototype = {
}
var isExternal = (aContext == Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
var userContextId = aParams.openerOriginAttributes &&
("userContextId" in aParams.openerOriginAttributes)
? aParams.openerOriginAttributes.userContextId
: Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID
let browser = this._openURIInNewTab(aURI, aParams.referrer,
aParams.referrerPolicy,
aParams.isPrivate, isExternal);
aParams.isPrivate,
isExternal, false,
userContextId);
if (browser)
return browser.QueryInterface(Ci.nsIFrameLoaderOwner);

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

@ -90,11 +90,17 @@ def HostStdCppCompat():
@template
def HostProgram(name):
def HostProgram(name, c_only=False):
'''Template for build tools executables.'''
HOST_PROGRAM = name
HostStdCppCompat()
# With context-based templates, this won't be needed anymore, and will
# work better than relying on the caller setting it, but at the moment,
# this is the best we have. And it doesn't matter /that/ much, so there's
# really only one place using this, where it does matter to avoid the
# extra dependency (because it creates a circular one).
if not c_only:
HostStdCppCompat()
@template

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

@ -24,7 +24,10 @@ if CONFIG['HOST_OS_ARCH'] != 'WINNT':
'nsinstall.c',
'pathsub.c',
]
HostProgram('nsinstall_real')
# stdc++compat depends on config/export, so avoid a circular
# dependency added by HostProgram depending on stdc++compat,
# while the program here is in C.
HostProgram('nsinstall_real', c_only=True)
if CONFIG['MOZ_SHARED_ICU']:
DEFINES['MOZ_SHARED_ICU'] = True

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

@ -152,7 +152,7 @@ widget/android/bindings/export: build/annotationProcessors/export
mobile/android/tests/browser/robocop/roboextender/tools: mobile/android/tests/javaaddons/tools
ifdef ENABLE_CLANG_PLUGIN
$(filter-out build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target
$(filter-out config/host build/unix/stdc++compat/% build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target
build/clang-plugin/tests/target: build/clang-plugin/target
endif
@ -176,3 +176,6 @@ endif
# happen at the same time (bug #1146738)
js/src/target: js/src/host
endif
# Most things are built during compile (target/host), but some things happen during export
# Those need to depend on config/export for system wrappers.
$(addprefix build/unix/stdc++compat/,target host) build/clang-plugin/target: config/export

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

@ -863,9 +863,6 @@ endif # WINNT && !GCC
ifdef ENABLE_STRIP
$(STRIP) $(STRIP_FLAGS) $@
endif
ifdef MOZ_POST_DSO_LIB_COMMAND
$(MOZ_POST_DSO_LIB_COMMAND) $@
endif
ifeq ($(SOLARIS_SUNPRO_CC),1)
_MDDEPFILE = $(MDDEPDIR)/$(@F).pp

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

@ -8475,7 +8475,6 @@ AC_SUBST(USE_DEPENDENT_LIBS)
AC_SUBST(MOZ_BUILD_ROOT)
AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
AC_SUBST(MOZ_LINKER_EXTRACT)

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

@ -5814,6 +5814,15 @@ nsDocShell::SetPosition(int32_t aX, int32_t aY)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetPositionDesktopPix(int32_t aX, int32_t aY)
{
// Added to nsIBaseWindow in bug 1247335;
// implement if a use-case is found.
NS_ASSERTION(false, "implement me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocShell::GetPosition(int32_t* aX, int32_t* aY)
{

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

@ -1107,7 +1107,7 @@ Animation::PostUpdate()
}
Element* targetElement;
nsCSSPseudoElements::Type targetPseudoType;
CSSPseudoElementType targetPseudoType;
mEffect->GetTarget(targetElement, targetPseudoType);
if (!targetElement) {
return;
@ -1204,8 +1204,7 @@ Animation::EffectEnd() const
return StickyTimeDuration(0);
}
return mEffect->SpecifiedTiming().mDelay
+ mEffect->GetComputedTiming().mActiveDuration;
return mEffect->GetComputedTiming().mEndTime;
}
nsIDocument*

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

@ -17,13 +17,13 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CSSPseudoElement, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CSSPseudoElement, Release)
CSSPseudoElement::CSSPseudoElement(Element* aElement,
nsCSSPseudoElements::Type aType)
CSSPseudoElementType aType)
: mParentElement(aElement)
, mPseudoType(aType)
{
MOZ_ASSERT(aElement);
MOZ_ASSERT(aType == nsCSSPseudoElements::ePseudo_after ||
aType == nsCSSPseudoElements::ePseudo_before,
MOZ_ASSERT(aType == CSSPseudoElementType::after ||
aType == CSSPseudoElementType::before,
"Unexpected Pseudo Type");
}
@ -69,7 +69,7 @@ CSSPseudoElement::Animate(
/* static */ already_AddRefed<CSSPseudoElement>
CSSPseudoElement::GetCSSPseudoElement(Element* aElement,
nsCSSPseudoElements::Type aType)
CSSPseudoElementType aType)
{
if (!aElement) {
return nullptr;
@ -96,14 +96,13 @@ CSSPseudoElement::GetCSSPseudoElement(Element* aElement,
}
/* static */ nsIAtom*
CSSPseudoElement::GetCSSPseudoElementPropertyAtom(
nsCSSPseudoElements::Type aType)
CSSPseudoElement::GetCSSPseudoElementPropertyAtom(CSSPseudoElementType aType)
{
switch (aType) {
case nsCSSPseudoElements::ePseudo_before:
case CSSPseudoElementType::before:
return nsGkAtoms::cssPseudoElementBeforeProperty;
case nsCSSPseudoElements::ePseudo_after:
case CSSPseudoElementType::after:
return nsGkAtoms::cssPseudoElementAfterProperty;
default:

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

@ -38,7 +38,7 @@ public:
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
nsCSSPseudoElements::Type GetType() const { return mPseudoType; }
CSSPseudoElementType GetType() const { return mPseudoType; }
void GetType(nsString& aRetVal) const
{
MOZ_ASSERT(nsCSSPseudoElements::GetPseudoAtom(mPseudoType),
@ -64,20 +64,19 @@ public:
// pseudo-type on element, a new CSSPseudoElement will be created and stored
// on the element.
static already_AddRefed<CSSPseudoElement>
GetCSSPseudoElement(Element* aElement, nsCSSPseudoElements::Type aType);
GetCSSPseudoElement(Element* aElement, CSSPseudoElementType aType);
private:
// Only ::before and ::after are supported.
CSSPseudoElement(Element* aElement, nsCSSPseudoElements::Type aType);
CSSPseudoElement(Element* aElement, CSSPseudoElementType aType);
static nsIAtom*
GetCSSPseudoElementPropertyAtom(nsCSSPseudoElements::Type aType);
static nsIAtom* GetCSSPseudoElementPropertyAtom(CSSPseudoElementType aType);
// mParentElement needs to be an owning reference since if script is holding
// on to the pseudo-element, it needs to continue to be able to refer to
// the parent element.
RefPtr<Element> mParentElement;
nsCSSPseudoElements::Type mPseudoType;
CSSPseudoElementType mPseudoType;
};
} // namespace dom

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

@ -16,6 +16,7 @@
#include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetPresShellForContent
#include "nsCSSPropertySet.h"
#include "nsCSSProps.h"
#include "nsCSSPseudoElements.h"
#include "nsIPresShell.h"
#include "nsLayoutUtils.h"
#include "nsRuleNode.h" // For nsRuleNode::ComputePropertiesOverridingAnimation
@ -80,7 +81,7 @@ FindAnimationsForCompositor(const nsIFrame* aFrame,
// Those cases are probably not important but just to be safe, let's make
// sure the cascade is up to date since if it *is* up to date, this is
// basically a no-op.
Maybe<Pair<dom::Element*, nsCSSPseudoElements::Type>> pseudoElement =
Maybe<Pair<dom::Element*, CSSPseudoElementType>> pseudoElement =
EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame);
if (pseudoElement) {
EffectCompositor::MaybeUpdateCascadeResults(pseudoElement->first(),
@ -131,7 +132,7 @@ FindAnimationsForCompositor(const nsIFrame* aFrame,
void
EffectCompositor::RequestRestyle(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
RestyleType aRestyleType,
CascadeLevel aCascadeLevel)
{
@ -171,7 +172,7 @@ EffectCompositor::RequestRestyle(dom::Element* aElement,
void
EffectCompositor::PostRestyleForAnimation(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel)
{
if (!mPresContext) {
@ -212,8 +213,7 @@ EffectCompositor::PostRestyleForThrottledAnimations()
void
EffectCompositor::MaybeUpdateAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type
aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel)
{
// First update cascade results since that may cause some elements to
@ -235,7 +235,7 @@ EffectCompositor::MaybeUpdateAnimationRule(dom::Element* aElement,
nsIStyleRule*
EffectCompositor::GetAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel)
{
// NOTE: We need to be careful about early returns in this method where
@ -281,9 +281,9 @@ EffectCompositor::GetAnimationRule(dom::Element* aElement,
/* static */ dom::Element*
EffectCompositor::GetElementToRestyle(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType)
CSSPseudoElementType aPseudoType)
{
if (aPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement) {
if (aPseudoType == CSSPseudoElementType::NotPseudo) {
return aElement;
}
@ -292,9 +292,9 @@ EffectCompositor::GetElementToRestyle(dom::Element* aElement,
return nullptr;
}
nsIFrame* pseudoFrame;
if (aPseudoType == nsCSSPseudoElements::ePseudo_before) {
if (aPseudoType == CSSPseudoElementType::before) {
pseudoFrame = nsLayoutUtils::GetBeforeFrame(primaryFrame);
} else if (aPseudoType == nsCSSPseudoElements::ePseudo_after) {
} else if (aPseudoType == CSSPseudoElementType::after) {
pseudoFrame = nsLayoutUtils::GetAfterFrame(primaryFrame);
} else {
NS_NOTREACHED("Should not try to get the element to restyle for a pseudo "
@ -417,8 +417,7 @@ EffectCompositor::ClearIsRunningOnCompositor(const nsIFrame *aFrame,
/* static */ void
EffectCompositor::MaybeUpdateCascadeResults(Element* aElement,
nsCSSPseudoElements::Type
aPseudoType,
CSSPseudoElementType aPseudoType,
nsStyleContext* aStyleContext)
{
EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
@ -433,8 +432,7 @@ EffectCompositor::MaybeUpdateCascadeResults(Element* aElement,
/* static */ void
EffectCompositor::MaybeUpdateCascadeResults(Element* aElement,
nsCSSPseudoElements::Type
aPseudoType)
CSSPseudoElementType aPseudoType)
{
nsStyleContext* styleContext = nullptr;
{
@ -474,7 +472,7 @@ namespace {
/* static */ void
EffectCompositor::UpdateCascadeResults(Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
nsStyleContext* aStyleContext)
{
EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
@ -485,19 +483,18 @@ EffectCompositor::UpdateCascadeResults(Element* aElement,
UpdateCascadeResults(*effects, aElement, aPseudoType, aStyleContext);
}
/* static */ Maybe<Pair<Element*, nsCSSPseudoElements::Type>>
/* static */ Maybe<Pair<Element*, CSSPseudoElementType>>
EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame)
{
// Always return the same object to benefit from return-value optimization.
Maybe<Pair<Element*, nsCSSPseudoElements::Type>> result;
Maybe<Pair<Element*, CSSPseudoElementType>> result;
nsIContent* content = aFrame->GetContent();
if (!content) {
return result;
}
nsCSSPseudoElements::Type pseudoType =
nsCSSPseudoElements::ePseudo_NotPseudoElement;
CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
if (aFrame->IsGeneratedContentFrame()) {
nsIFrame* parent = aFrame->GetParent();
@ -506,9 +503,9 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame)
}
nsIAtom* name = content->NodeInfo()->NameAtom();
if (name == nsGkAtoms::mozgeneratedcontentbefore) {
pseudoType = nsCSSPseudoElements::ePseudo_before;
pseudoType = CSSPseudoElementType::before;
} else if (name == nsGkAtoms::mozgeneratedcontentafter) {
pseudoType = nsCSSPseudoElements::ePseudo_after;
pseudoType = CSSPseudoElementType::after;
} else {
return result;
}
@ -534,7 +531,7 @@ EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame)
/* static */ void
EffectCompositor::ComposeAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel,
TimeStamp aRefreshTime)
{
@ -615,7 +612,7 @@ EffectCompositor::GetOverriddenProperties(nsStyleContext* aStyleContext,
/* static */ void
EffectCompositor::UpdateCascadeResults(EffectSet& aEffectSet,
Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
nsStyleContext* aStyleContext)
{
MOZ_ASSERT(EffectSet::GetEffectSet(aElement, aPseudoType) == &aEffectSet,
@ -763,7 +760,7 @@ EffectCompositor::AnimationStyleRuleProcessor::RulesMatching(
{
nsIStyleRule *rule =
mCompositor->GetAnimationRule(aData->mElement,
nsCSSPseudoElements::ePseudo_NotPseudoElement,
CSSPseudoElementType::NotPseudo,
mCascadeLevel);
if (rule) {
aData->mRuleWalker->Forward(rule);
@ -775,8 +772,8 @@ void
EffectCompositor::AnimationStyleRuleProcessor::RulesMatching(
PseudoElementRuleProcessorData* aData)
{
if (aData->mPseudoType != nsCSSPseudoElements::ePseudo_before &&
aData->mPseudoType != nsCSSPseudoElements::ePseudo_after) {
if (aData->mPseudoType != CSSPseudoElementType::before &&
aData->mPseudoType != CSSPseudoElementType::after) {
return;
}

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

@ -14,7 +14,6 @@
#include "mozilla/PseudoElementHashEntry.h"
#include "mozilla/RefPtr.h"
#include "nsCSSProperty.h"
#include "nsCSSPseudoElements.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDataHashtable.h"
#include "nsIStyleRuleProcessor.h"
@ -30,6 +29,7 @@ namespace mozilla {
class EffectSet;
class RestyleTracker;
enum class CSSPseudoElementType : uint8_t;
namespace dom {
class Animation;
@ -94,7 +94,7 @@ public:
// The specified steps taken to update the animation rule depend on
// |aRestyleType| whose values are described above.
void RequestRestyle(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
RestyleType aRestyleType,
CascadeLevel aCascadeLevel);
@ -103,7 +103,7 @@ public:
// need to perform this step when triggering transitions *without* also
// invalidating the animation style rule (which RequestRestyle would do).
void PostRestyleForAnimation(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel);
// Posts an animation restyle for any elements whose animation style rule
@ -116,11 +116,11 @@ public:
// If the animation rule is not marked as needing an update,
// no work is done.
void MaybeUpdateAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel);
nsIStyleRule* GetAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel);
bool HasPendingStyleUpdates() const;
@ -155,14 +155,14 @@ public:
// animation level of the cascade have changed.
static void
MaybeUpdateCascadeResults(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
nsStyleContext* aStyleContext);
// An overload of MaybeUpdateCascadeResults that uses the style context
// of the primary frame of the specified (pseudo-)element, when available.
static void
MaybeUpdateCascadeResults(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
CSSPseudoElementType aPseudoType);
// Update the mWinsInCascade member for each property in effects targetting
// the specified (pseudo-)element.
@ -172,7 +172,7 @@ public:
// other cases we should call MaybeUpdateCascadeResults.
static void
UpdateCascadeResults(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
nsStyleContext* aStyleContext);
// Helper to fetch the corresponding element and pseudo-type from a frame.
@ -184,7 +184,7 @@ public:
// Returns an empty result when a suitable element cannot be found including
// when the frame represents a pseudo-element on which we do not support
// animations.
static Maybe<Pair<dom::Element*, nsCSSPseudoElements::Type>>
static Maybe<Pair<dom::Element*, CSSPseudoElementType>>
GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame);
private:
@ -193,12 +193,12 @@ private:
// Rebuilds the animation rule corresponding to |aCascadeLevel| on the
// EffectSet associated with the specified (pseudo-)element.
static void ComposeAnimationRule(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
CascadeLevel aCascadeLevel,
TimeStamp aRefreshTime);
static dom::Element* GetElementToRestyle(dom::Element* aElement,
nsCSSPseudoElements::Type
CSSPseudoElementType
aPseudoType);
// Get the properties in |aEffectSet| that we are able to animate on the
@ -212,7 +212,7 @@ private:
static void
UpdateCascadeResults(EffectSet& aEffectSet,
dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
nsStyleContext* aStyleContext);
static nsPresContext* GetPresContext(dom::Element* aElement);

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

@ -7,6 +7,7 @@
#include "EffectSet.h"
#include "mozilla/dom/Element.h" // For Element
#include "RestyleManager.h"
#include "nsCSSPseudoElements.h" // For CSSPseudoElementType
#include "nsCycleCollectionNoteChild.h" // For CycleCollectionNoteChild
#include "nsPresContext.h"
#include "nsLayoutUtils.h"
@ -38,7 +39,7 @@ EffectSet::Traverse(nsCycleCollectionTraversalCallback& aCallback)
/* static */ EffectSet*
EffectSet::GetEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType)
CSSPseudoElementType aPseudoType)
{
nsIAtom* propName = GetEffectSetPropertyAtom(aPseudoType);
return static_cast<EffectSet*>(aElement->GetProperty(propName));
@ -87,7 +88,7 @@ EffectSet::GetEffectSet(const nsIFrame* aFrame)
/* static */ EffectSet*
EffectSet::GetOrCreateEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType)
CSSPseudoElementType aPseudoType)
{
EffectSet* effectSet = GetEffectSet(aElement, aPseudoType);
if (effectSet) {
@ -114,7 +115,7 @@ EffectSet::GetOrCreateEffectSet(dom::Element* aElement,
/* static */ void
EffectSet::DestroyEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType)
CSSPseudoElementType aPseudoType)
{
nsIAtom* propName = GetEffectSetPropertyAtom(aPseudoType);
EffectSet* effectSet =
@ -152,16 +153,16 @@ EffectSet::GetEffectSetPropertyAtoms()
}
/* static */ nsIAtom*
EffectSet::GetEffectSetPropertyAtom(nsCSSPseudoElements::Type aPseudoType)
EffectSet::GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType)
{
switch (aPseudoType) {
case nsCSSPseudoElements::ePseudo_NotPseudoElement:
case CSSPseudoElementType::NotPseudo:
return nsGkAtoms::animationEffectsProperty;
case nsCSSPseudoElements::ePseudo_before:
case CSSPseudoElementType::before:
return nsGkAtoms::animationEffectsForBeforeProperty;
case nsCSSPseudoElements::ePseudo_after:
case CSSPseudoElementType::after:
return nsGkAtoms::animationEffectsForAfterProperty;
default:

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

@ -12,7 +12,6 @@
#include "mozilla/EffectCompositor.h"
#include "mozilla/EnumeratedArray.h"
#include "mozilla/TimeStamp.h"
#include "nsCSSPseudoElements.h" // For nsCSSPseudoElements::Type
#include "nsHashKeys.h" // For nsPtrHashKey
#include "nsTHashtable.h" // For nsTHashtable
@ -25,6 +24,8 @@ class Element;
class KeyframeEffectReadOnly;
} // namespace dom
enum class CSSPseudoElementType : uint8_t;
// A wrapper around a hashset of AnimationEffect objects to handle
// storing the set as a property of an element.
class EffectSet
@ -57,12 +58,12 @@ public:
void Traverse(nsCycleCollectionTraversalCallback& aCallback);
static EffectSet* GetEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
CSSPseudoElementType aPseudoType);
static EffectSet* GetEffectSet(const nsIFrame* aFrame);
static EffectSet* GetOrCreateEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
CSSPseudoElementType aPseudoType);
static void DestroyEffectSet(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
CSSPseudoElementType aPseudoType);
void AddEffect(dom::KeyframeEffectReadOnly& aEffect);
void RemoveEffect(dom::KeyframeEffectReadOnly& aEffect);
@ -182,8 +183,7 @@ public:
static nsIAtom** GetEffectSetPropertyAtoms();
private:
static nsIAtom* GetEffectSetPropertyAtom(nsCSSPseudoElements::Type
aPseudoType);
static nsIAtom* GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType);
OwningEffectSet mEffects;

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

@ -17,6 +17,7 @@
#include "nsCSSParser.h"
#include "nsCSSPropertySet.h"
#include "nsCSSProps.h" // For nsCSSProps::PropHasFlags
#include "nsCSSPseudoElements.h"
#include "nsCSSValue.h"
#include "nsStyleUtil.h"
#include <algorithm> // For std::max
@ -40,8 +41,7 @@ GetComputedTimingDictionary(const ComputedTiming& aComputedTiming,
// ComputedTimingProperties
aRetVal.mActiveDuration = aComputedTiming.mActiveDuration.ToMilliseconds();
aRetVal.mEndTime
= std::max(aRetVal.mDelay + aRetVal.mActiveDuration + aRetVal.mEndDelay, 0.0);
aRetVal.mEndTime = aComputedTiming.mEndTime.ToMilliseconds();
aRetVal.mLocalTime = AnimationUtils::TimeDurationToDouble(aLocalTime);
aRetVal.mProgress = aComputedTiming.mProgress;
if (!aRetVal.mProgress.IsNull()) {
@ -74,7 +74,7 @@ NS_IMPL_RELEASE_INHERITED(KeyframeEffectReadOnly, AnimationEffectReadOnly)
KeyframeEffectReadOnly::KeyframeEffectReadOnly(
nsIDocument* aDocument,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
const TimingParams& aTiming)
: KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType,
new AnimationEffectTimingReadOnly(aTiming))
@ -84,7 +84,7 @@ KeyframeEffectReadOnly::KeyframeEffectReadOnly(
KeyframeEffectReadOnly::KeyframeEffectReadOnly(
nsIDocument* aDocument,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
AnimationEffectTimingReadOnly* aTiming)
: AnimationEffectReadOnly(aDocument)
, mTarget(aTarget)
@ -244,6 +244,8 @@ KeyframeEffectReadOnly::GetComputedTimingAt(
1.0f :
aTiming.mIterations;
result.mActiveDuration = ActiveDuration(result.mDuration, result.mIterations);
// Bug 1244635: Add endDelay to the end time calculation
result.mEndTime = aTiming.mDelay + result.mActiveDuration;
result.mFill = aTiming.mFill == dom::FillMode::Auto ?
dom::FillMode::None :
aTiming.mFill;
@ -366,18 +368,19 @@ KeyframeEffectReadOnly::GetComputedTimingAt(
}
StickyTimeDuration
KeyframeEffectReadOnly::ActiveDuration(const StickyTimeDuration& aIterationDuration,
double aIterationCount)
KeyframeEffectReadOnly::ActiveDuration(
const StickyTimeDuration& aIterationDuration,
double aIterationCount)
{
if (IsInfinite(aIterationCount)) {
// An animation that repeats forever has an infinite active duration
// unless its iteration duration is zero, in which case it has a zero
// active duration.
const StickyTimeDuration zeroDuration;
return aIterationDuration == zeroDuration ?
zeroDuration :
StickyTimeDuration::Forever();
// If either the iteration duration or iteration count is zero,
// Web Animations says that the active duration is zero. This is to
// ensure that the result is defined when the other argument is Infinity.
const StickyTimeDuration zeroDuration;
if (aIterationDuration == zeroDuration ||
aIterationCount == 0.0) {
return zeroDuration;
}
return aIterationDuration.MultDouble(aIterationCount);
}
@ -624,8 +627,7 @@ KeyframeEffectReadOnly::ConstructKeyframeEffect(const GlobalObject& aGlobal,
"Uninitialized target");
RefPtr<Element> targetElement;
nsCSSPseudoElements::Type pseudoType =
nsCSSPseudoElements::ePseudo_NotPseudoElement;
CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
if (target.IsElement()) {
targetElement = &target.GetAsElement();
} else {
@ -1230,7 +1232,7 @@ ApplyDistributeSpacing(nsTArray<OffsetIndexedKeyframe>& aKeyframes)
*/
static void
GenerateValueEntries(Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
nsTArray<OffsetIndexedKeyframe>& aKeyframes,
nsTArray<KeyframeValueEntry>& aResult,
ErrorResult& aRv)
@ -1434,7 +1436,7 @@ static void
BuildAnimationPropertyListFromKeyframeSequence(
JSContext* aCx,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
JS::ForOfIterator& aIterator,
nsTArray<AnimationProperty>& aResult,
ErrorResult& aRv)
@ -1492,7 +1494,7 @@ static void
BuildAnimationPropertyListFromPropertyIndexedKeyframes(
JSContext* aCx,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
JS::Handle<JS::Value> aValue,
InfallibleTArray<AnimationProperty>& aResult,
ErrorResult& aRv)
@ -1667,7 +1669,7 @@ BuildAnimationPropertyListFromPropertyIndexedKeyframes(
KeyframeEffectReadOnly::BuildAnimationPropertyList(
JSContext* aCx,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
JS::Handle<JSObject*> aFrames,
InfallibleTArray<AnimationProperty>& aResult,
ErrorResult& aRv)
@ -1721,13 +1723,13 @@ KeyframeEffectReadOnly::GetTarget(
}
switch (mPseudoType) {
case nsCSSPseudoElements::ePseudo_before:
case nsCSSPseudoElements::ePseudo_after:
case CSSPseudoElementType::before:
case CSSPseudoElementType::after:
aRv.SetValue().SetAsCSSPseudoElement() =
CSSPseudoElement::GetCSSPseudoElement(mTarget, mPseudoType);
break;
case nsCSSPseudoElements::ePseudo_NotPseudoElement:
case CSSPseudoElementType::NotPseudo:
aRv.SetValue().SetAsElement() = mTarget;
break;
@ -1975,12 +1977,12 @@ KeyframeEffectReadOnly::GetAnimationFrame() const
return nullptr;
}
if (mPseudoType == nsCSSPseudoElements::ePseudo_before) {
if (mPseudoType == CSSPseudoElementType::before) {
frame = nsLayoutUtils::GetBeforeFrame(frame);
} else if (mPseudoType == nsCSSPseudoElements::ePseudo_after) {
} else if (mPseudoType == CSSPseudoElementType::after) {
frame = nsLayoutUtils::GetAfterFrame(frame);
} else {
MOZ_ASSERT(mPseudoType == nsCSSPseudoElements::ePseudo_NotPseudoElement,
MOZ_ASSERT(mPseudoType == CSSPseudoElementType::NotPseudo,
"unknown mPseudoType");
}
if (!frame) {
@ -2126,7 +2128,7 @@ KeyframeEffectReadOnly::ShouldBlockCompositorAnimations(const nsIFrame*
KeyframeEffect::KeyframeEffect(nsIDocument* aDocument,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
const TimingParams& aTiming)
: KeyframeEffectReadOnly(aDocument, aTarget, aPseudoType,
new AnimationEffectTiming(aTiming))

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

@ -9,7 +9,6 @@
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsCSSPseudoElements.h"
#include "nsIDocument.h"
#include "nsWrapperCache.h"
#include "mozilla/Attributes.h"
@ -38,6 +37,7 @@ namespace mozilla {
struct AnimationCollection;
class AnimValuesStyleRule;
enum class CSSPseudoElementType : uint8_t;
namespace dom {
class ElementOrCSSPseudoElement;
@ -57,6 +57,10 @@ struct ComputedTiming
// Will equal StickyTimeDuration::Forever() if the animation repeats
// indefinitely.
StickyTimeDuration mActiveDuration;
// The effect end time in local time (i.e. an offset from the effect's
// start time). Will equal StickyTimeDuration::Forever() if the animation
// plays indefinitely.
StickyTimeDuration mEndTime;
// Progress towards the end of the current iteration. If the effect is
// being sampled backwards, this will go from 1.0 to 0.0.
// Will be null if the animation is neither animating nor
@ -172,7 +176,7 @@ class KeyframeEffectReadOnly : public AnimationEffectReadOnly
public:
KeyframeEffectReadOnly(nsIDocument* aDocument,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
const TimingParams& aTiming);
NS_DECL_ISUPPORTS_INHERITED
@ -209,7 +213,7 @@ public:
// Temporary workaround to return both the target element and pseudo-type
// until we implement PseudoElement (bug 1174575).
void GetTarget(Element*& aTarget,
nsCSSPseudoElements::Type& aPseudoType) const {
CSSPseudoElementType& aPseudoType) const {
aTarget = mTarget;
aPseudoType = mPseudoType;
}
@ -322,7 +326,7 @@ public:
protected:
KeyframeEffectReadOnly(nsIDocument* aDocument,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
AnimationEffectTimingReadOnly* aTiming);
virtual ~KeyframeEffectReadOnly();
@ -351,7 +355,7 @@ protected:
static void BuildAnimationPropertyList(
JSContext* aCx,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
JS::Handle<JSObject*> aFrames,
InfallibleTArray<AnimationProperty>& aResult,
ErrorResult& aRv);
@ -360,7 +364,7 @@ protected:
RefPtr<Animation> mAnimation;
OwningNonNull<AnimationEffectTimingReadOnly> mTiming;
nsCSSPseudoElements::Type mPseudoType;
CSSPseudoElementType mPseudoType;
InfallibleTArray<AnimationProperty> mProperties;
@ -395,7 +399,7 @@ class KeyframeEffect : public KeyframeEffectReadOnly
public:
KeyframeEffect(nsIDocument* aDocument,
Element* aTarget,
nsCSSPseudoElements::Type aPseudoType,
CSSPseudoElementType aPseudoType,
const TimingParams& aTiming);
JSObject* WrapObject(JSContext* aCx,

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

@ -9,18 +9,19 @@
#include "mozilla/dom/Element.h"
#include "mozilla/HashFunctions.h"
#include "nsCSSPseudoElements.h"
#include "PLDHashTable.h"
namespace mozilla {
enum class CSSPseudoElementType : uint8_t;
struct PseudoElementHashKey
{
dom::Element* mElement;
nsCSSPseudoElements::Type mPseudoType;
CSSPseudoElementType mPseudoType;
};
// A hash entry that uses a RefPtr<dom::Element>, nsCSSPseudoElements::Type pair
// A hash entry that uses a RefPtr<dom::Element>, CSSPseudoElementType pair
class PseudoElementHashEntry : public PLDHashEntryHdr
{
public:
@ -47,12 +48,14 @@ public:
if (!aKey)
return 0;
return mozilla::HashGeneric(aKey->mElement, aKey->mPseudoType);
// Convert the scoped enum into an integer while adding it to hash.
return mozilla::HashGeneric(aKey->mElement,
static_cast<uint8_t>(aKey->mPseudoType));
}
enum { ALLOW_MEMMOVE = true };
RefPtr<dom::Element> mElement;
nsCSSPseudoElements::Type mPseudoType;
CSSPseudoElementType mPseudoType;
};
} // namespace mozilla

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

@ -188,11 +188,11 @@ test(function(t) {
}, 'endTime of an infinitely repeating zero-duration animation');
test(function(t) {
// Fill forwards so div.getAnimations()[0] wouldn't return
// Fill forwards so div.getAnimations()[0] won't return an
// undefined value.
var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
var effect = div.getAnimations()[0].effect;
assert_equals(effect.getComputedTiming().endTime, 0,
assert_equals(effect.getComputedTiming().endTime, -90000,
'Initial value of endTime');
}, 'endTime of an animation that finishes before its startTime');

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

@ -3368,7 +3368,7 @@ void
Element::GetAnimationsUnsorted(nsTArray<RefPtr<Animation>>& aAnimations)
{
EffectSet* effects = EffectSet::GetEffectSet(this,
nsCSSPseudoElements::ePseudo_NotPseudoElement);
CSSPseudoElementType::NotPseudo);
if (!effects) {
return;
}

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

@ -2523,6 +2523,9 @@ public:
bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
// We don't call WorkerRunnable::PreDispatch because it would assert the
// wrong thing about which thread we're on.
AssertIsOnMainThread();
return true;
}
@ -2530,6 +2533,9 @@ public:
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
// We don't call WorkerRunnable::PostDispatch because it would assert the
// wrong thing about which thread we're on.
AssertIsOnMainThread();
}
private:
@ -2696,6 +2702,10 @@ public:
bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
// We don't call WorkerRunnable::PreDispatch because it would assert the
// wrong thing about which thread we're on. We're on whichever thread the
// channel implementation is running on (probably the main thread or socket
// transport thread).
return true;
}
@ -2703,6 +2713,10 @@ public:
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
// We don't call WorkerRunnable::PreDispatch because it would assert the
// wrong thing about which thread we're on. We're on whichever thread the
// channel implementation is running on (probably the main thread or socket
// transport thread).
}
private:

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

@ -389,7 +389,7 @@ nsAnimationReceiver::RecordAnimationMutation(Animation* aAnimation,
}
mozilla::dom::Element* animationTarget;
nsCSSPseudoElements::Type pseudoType;
CSSPseudoElementType pseudoType;
effect->GetTarget(animationTarget, pseudoType);
if (!animationTarget) {
return;

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

@ -101,6 +101,7 @@
#include "nsIDOMStyleSheet.h"
#include "nsIStyleSheetService.h"
#include "nsContentPermissionHelper.h"
#include "nsCSSPseudoElements.h" // for CSSPseudoElementType
#include "nsNetUtil.h"
#include "nsDocument.h"
#include "HTMLImageElement.h"
@ -2247,13 +2248,12 @@ ComputeAnimationValue(nsCSSProperty aProperty,
StyleAnimationValue& aOutput)
{
if (!StyleAnimationValue::ComputeValue(
aProperty,
aElement,
nsCSSPseudoElements::ePseudo_NotPseudoElement,
aInput,
false,
aOutput)) {
if (!StyleAnimationValue::ComputeValue(aProperty,
aElement,
CSSPseudoElementType::NotPseudo,
aInput,
false,
aOutput)) {
return false;
}

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

@ -5002,6 +5002,8 @@ nsGlobalWindow::SetOuterSize(int32_t aLengthCSSPixels, bool aIsWidth,
height = lengthDevPixels;
}
aError = treeOwnerAsWin->SetSize(width, height, true);
CheckForDPIChange();
}
void
@ -5323,6 +5325,8 @@ nsGlobalWindow::SetScreenXOuter(int32_t aScreenX, ErrorResult& aError, bool aCal
x = CSSToDevIntPixels(aScreenX);
aError = treeOwnerAsWin->SetPosition(x, y);
CheckForDPIChange();
}
void
@ -5383,6 +5387,8 @@ nsGlobalWindow::SetScreenYOuter(int32_t aScreenY, ErrorResult& aError, bool aCal
y = CSSToDevIntPixels(aScreenY);
aError = treeOwnerAsWin->SetPosition(x, y);
CheckForDPIChange();
}
void
@ -7063,8 +7069,11 @@ nsGlobalWindow::MoveToOuter(int32_t aXPos, int32_t aYPos, ErrorResult& aError, b
getter_AddRefs(screen));
}
LayoutDevicePoint devPos;
if (screen) {
// On secondary displays, the "CSS px" coordinates are offset so that they
// share their origin with global desktop pixels, to avoid ambiguities in
// the coordinate space when there are displays with different DPIs.
// (See the corresponding code in GetScreenXY() above.)
int32_t screenLeftDeskPx, screenTopDeskPx, w, h;
screen->GetRectDisplayPix(&screenLeftDeskPx, &screenTopDeskPx, &w, &h);
CSSIntPoint cssPos(aXPos - screenLeftDeskPx, aYPos - screenTopDeskPx);
@ -7072,20 +7081,21 @@ nsGlobalWindow::MoveToOuter(int32_t aXPos, int32_t aYPos, ErrorResult& aError, b
double scale;
screen->GetDefaultCSSScaleFactor(&scale);
devPos = cssPos * CSSToLayoutDeviceScale(scale);
LayoutDevicePoint devPos = cssPos * CSSToLayoutDeviceScale(scale);
int32_t screenLeftDevPx, screenTopDevPx;
screen->GetRect(&screenLeftDevPx, &screenTopDevPx, &w, &h);
devPos.x += screenLeftDevPx;
devPos.y += screenTopDevPx;
screen->GetContentsScaleFactor(&scale);
DesktopPoint deskPos = devPos / DesktopToLayoutDeviceScale(scale);
aError = treeOwnerAsWin->SetPositionDesktopPix(screenLeftDeskPx + deskPos.x,
screenTopDeskPx + deskPos.y);
} else {
// We couldn't find a screen? Just assume a 1:1 mapping.
CSSIntPoint cssPos(aXPos, aXPos);
CheckSecurityLeftAndTop(&cssPos.x, &cssPos.y, aCallerIsChrome);
devPos = cssPos * CSSToLayoutDeviceScale(1.0);
LayoutDevicePoint devPos = cssPos * CSSToLayoutDeviceScale(1.0);
aError = treeOwnerAsWin->SetPosition(devPos.x, devPos.y);
}
aError = treeOwnerAsWin->SetPosition(devPos.x, devPos.y);
CheckForDPIChange();
}
void
@ -7135,6 +7145,8 @@ nsGlobalWindow::MoveByOuter(int32_t aXDif, int32_t aYDif, ErrorResult& aError, b
nsIntSize newDevPos(CSSToDevIntPixels(cssPos));
aError = treeOwnerAsWin->SetPosition(newDevPos.width, newDevPos.height);
CheckForDPIChange();
}
void
@ -7193,6 +7205,8 @@ nsGlobalWindow::ResizeToOuter(int32_t aWidth, int32_t aHeight, ErrorResult& aErr
nsIntSize devSz(CSSToDevIntPixels(cssSize));
aError = treeOwnerAsWin->SetSize(devSz.width, devSz.height, true);
CheckForDPIChange();
}
void
@ -7262,6 +7276,8 @@ nsGlobalWindow::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
nsIntSize newDevSize(CSSToDevIntPixels(cssSize));
aError = treeOwnerAsWin->SetSize(newDevSize.width, newDevSize.height, true);
CheckForDPIChange();
}
void
@ -13958,6 +13974,23 @@ nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage,
return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
}
// Helper called by methods that move/resize the window,
// to ensure the presContext (if any) is aware of resolution
// change that may happen in multi-monitor configuration.
void
nsGlobalWindow::CheckForDPIChange()
{
if (mDocShell) {
RefPtr<nsPresContext> presContext;
mDocShell->GetPresContext(getter_AddRefs(presContext));
if (presContext) {
if (presContext->DeviceContext()->CheckDPIChange()) {
presContext->UIResolutionChanged();
}
}
}
}
template class nsPIDOMWindow<mozIDOMWindowProxy>;
template class nsPIDOMWindow<mozIDOMWindow>;
template class nsPIDOMWindow<nsISupports>;

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

@ -1652,6 +1652,10 @@ protected:
// show, in that case we show a separate dialog to ask this question.
bool ConfirmDialogIfNeeded();
// Helper called after moving/resizing, to update docShell's presContext
// if we have caused a resolution change by moving across monitors.
void CheckForDPIChange();
private:
// Fire the JS engine's onNewGlobalObject hook. Only used on inner windows.
void FireOnNewGlobalObject();

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

@ -178,6 +178,7 @@ static uint32_t sForgetSkippableBeforeCC = 0;
static uint32_t sPreviousSuspectedCount = 0;
static uint32_t sCleanupsSinceLastGC = UINT32_MAX;
static bool sNeedsFullCC = false;
static bool sNeedsFullGC = false;
static bool sNeedsGCAfterCC = false;
static bool sIncrementalCC = false;
static bool sDidPaintAfterPreviousICCSlice = false;
@ -1312,7 +1313,14 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
}
JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL;
JS::PrepareForFullGC(sRuntime);
if (sNeedsFullGC || aReason != JS::gcreason::CC_WAITING) {
sNeedsFullGC = false;
JS::PrepareForFullGC(sRuntime);
} else {
CycleCollectedJSRuntime::Get()->PrepareWaitingZonesForGC();
}
if (aIncremental == IncrementalGC) {
JS::StartIncrementalGC(sRuntime, gckind, aReason, aSliceMillis);
} else {
@ -2009,6 +2017,8 @@ nsJSContext::RunNextCollectorTimer()
void
nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay)
{
sNeedsFullGC = sNeedsFullGC || aReason != JS::gcreason::CC_WAITING;
if (sGCTimer || sInterSliceGCTimer || sShuttingDown) {
// There's already a timer for GC'ing, just return
return;
@ -2278,13 +2288,10 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescrip
}
} else {
nsJSContext::KillFullGCTimer();
}
// Avoid shrinking during heavy activity, which is suggested by
// compartment GC. We don't need to shrink after a shrinking GC as this
// happens automatically in this case.
if (aDesc.invocationKind_ == GC_NORMAL) {
nsJSContext::PokeShrinkGCBuffers();
}
if (aDesc.invocationKind_ == GC_NORMAL) {
nsJSContext::PokeShrinkGCBuffers();
}
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
@ -2380,6 +2387,7 @@ mozilla::dom::StartupJSEnvironment()
sLikelyShortLivingObjectsNeedingGC = 0;
sPostGCEventsToConsole = false;
sNeedsFullCC = false;
sNeedsFullGC = false;
sNeedsGCAfterCC = false;
gNameSpaceManager = nullptr;
sRuntime = nullptr;

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

@ -6,6 +6,7 @@
#include "nsNodeUtils.h"
#include "nsContentUtils.h"
#include "nsCSSPseudoElements.h"
#include "nsINode.h"
#include "nsIContent.h"
#include "mozilla/dom/Element.h"
@ -235,13 +236,13 @@ nsNodeUtils::GetTargetForAnimation(const Animation* aAnimation)
}
Element* target;
nsCSSPseudoElements::Type pseudoType;
CSSPseudoElementType pseudoType;
effect->GetTarget(target, pseudoType);
// If the animation targets a pseudo-element, we don't dispatch
// notifications for it. (In the future we will have PseudoElement
// objects we can use as the target of the notifications.)
if (pseudoType != nsCSSPseudoElements::ePseudo_NotPseudoElement) {
if (pseudoType != CSSPseudoElementType::NotPseudo) {
return nullptr;
}

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

@ -5,11 +5,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsOpenURIInFrameParams.h"
#include "mozilla/BasePrincipal.h"
NS_IMPL_ISUPPORTS(nsOpenURIInFrameParams, nsIOpenURIInFrameParams)
nsOpenURIInFrameParams::nsOpenURIInFrameParams() :
mIsPrivate(false)
nsOpenURIInFrameParams::nsOpenURIInFrameParams(const mozilla::DocShellOriginAttributes& aOriginAttributes)
: mOpenerOriginAttributes(aOriginAttributes)
, mIsPrivate(false)
{
}
@ -22,6 +24,7 @@ nsOpenURIInFrameParams::GetReferrer(nsAString& aReferrer)
aReferrer = mReferrer;
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::SetReferrer(const nsAString& aReferrer)
{
@ -36,9 +39,19 @@ nsOpenURIInFrameParams::GetIsPrivate(bool* aIsPrivate)
*aIsPrivate = mIsPrivate;
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::SetIsPrivate(bool aIsPrivate)
{
mIsPrivate = aIsPrivate;
return NS_OK;
}
NS_IMETHODIMP
nsOpenURIInFrameParams::GetOpenerOriginAttributes(JSContext* aCx,
JS::MutableHandle<JS::Value> aValue)
{
bool ok = ToJSValue(aCx, mOpenerOriginAttributes, aValue);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
return NS_OK;
}

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

@ -7,16 +7,22 @@
#include "nsIBrowserDOMWindow.h"
#include "nsString.h"
namespace mozilla {
class DocShellOriginAttributes;
}
class nsOpenURIInFrameParams final : public nsIOpenURIInFrameParams
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOPENURIINFRAMEPARAMS
nsOpenURIInFrameParams();
explicit nsOpenURIInFrameParams(const mozilla::DocShellOriginAttributes& aOriginAttributes);
private:
~nsOpenURIInFrameParams();
mozilla::DocShellOriginAttributes mOpenerOriginAttributes;
nsString mReferrer;
bool mIsPrivate;
};

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

@ -70,6 +70,10 @@
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
#ifdef MOZ_WIDGET_COCOA
#include "nsCocoaFeatures.h"
#endif
// Generated
#include "mozilla/dom/WebGLRenderingContextBinding.h"
@ -109,6 +113,7 @@ WebGLContext::WebGLContext()
, mNeedsFakeNoAlpha(false)
, mNeedsFakeNoDepth(false)
, mNeedsFakeNoStencil(false)
, mNeedsEmulatedLoneDepthStencil(false)
{
mGeneration = 0;
mInvalidated = false;
@ -891,6 +896,14 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
if (!mOptions.stencil && gl->Caps().stencil)
mNeedsFakeNoStencil = true;
#ifdef MOZ_WIDGET_COCOA
if (!nsCocoaFeatures::IsAtLeastVersion(10, 12) &&
gl->Vendor() == GLVendor::Intel)
{
mNeedsEmulatedLoneDepthStencil = true;
}
#endif
}
// Update mOptions.
@ -1847,10 +1860,19 @@ WebGLContext::ScopedMaskWorkaround::~ScopedMaskWorkaround()
mWebGL.gl->fEnable(LOCAL_GL_DEPTH_TEST);
}
if (mFakeNoStencil) {
MOZ_ASSERT(mWebGL.mStencilTestEnabled);
mWebGL.gl->fEnable(LOCAL_GL_STENCIL_TEST);
}
}
/*static*/ bool
WebGLContext::ScopedMaskWorkaround::HasDepthButNoStencil(const WebGLFramebuffer* fb)
{
const auto& depth = fb->DepthAttachment();
const auto& stencil = fb->StencilAttachment();
return depth.IsDefined() && !stencil.IsDefined();
}
////////////////////////////////////////
ScopedUnpackReset::ScopedUnpackReset(WebGLContext* webgl)

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

@ -1505,6 +1505,7 @@ protected:
bool mNeedsFakeNoAlpha;
bool mNeedsFakeNoDepth;
bool mNeedsFakeNoStencil;
bool mNeedsEmulatedLoneDepthStencil;
struct ScopedMaskWorkaround {
WebGLContext& mWebGL;
@ -1527,11 +1528,32 @@ protected:
webgl.mDepthTestEnabled;
}
static bool HasDepthButNoStencil(const WebGLFramebuffer* fb);
static bool ShouldFakeNoStencil(WebGLContext& webgl) {
// We should only be doing this if we're about to draw to the backbuffer.
return !webgl.mBoundDrawFramebuffer &&
webgl.mNeedsFakeNoStencil &&
webgl.mStencilTestEnabled;
if (!webgl.mStencilTestEnabled)
return false;
if (!webgl.mBoundDrawFramebuffer) {
if (webgl.mNeedsFakeNoStencil)
return true;
if (webgl.mNeedsEmulatedLoneDepthStencil &&
webgl.mOptions.depth && !webgl.mOptions.stencil)
{
return true;
}
return false;
}
if (webgl.mNeedsEmulatedLoneDepthStencil &&
HasDepthButNoStencil(webgl.mBoundDrawFramebuffer))
{
return true;
}
return false;
}
explicit ScopedMaskWorkaround(WebGLContext& webgl);

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

@ -7,7 +7,7 @@
TEST_DIRS += ['compiledtest']
# Number changes to this file to avoid bug 1081323 (clobber after changing a manifest):
# 5
# 11
MOCHITEST_MANIFESTS += [
'test/crossorigin/mochitest.ini',

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

@ -117,7 +117,6 @@ function GetExpectedTestFailSet() {
failSet['conformance/glsl/functions/glsl-function-sin.html'] = true;
failSet['conformance/misc/object-deletion-behaviour.html'] = true;
failSet['conformance/textures/tex-image-with-format-and-type.html'] = true;
failSet['conformance/textures/texture-mips.html'] = true;
failSet['conformance/textures/texture-npot.html'] = true;
failSet['conformance/textures/texture-size-cube-maps.html'] = true;
} else if (DriverInfo.getOSVersion() >= OS_VERSION_ANDROID_ICS) {
@ -135,7 +134,6 @@ function GetExpectedTestFailSet() {
failSet['conformance/state/gl-get-calls.html'] = true;
failSet['conformance/textures/tex-image-with-format-and-type.html'] = true;
failSet['conformance/textures/tex-sub-image-2d.html'] = true;
failSet['conformance/textures/texture-mips.html'] = true;
failSet['conformance/textures/texture-size-cube-maps.html'] = true;
} else {
// Android 2.3 slaves.
@ -144,7 +142,6 @@ function GetExpectedTestFailSet() {
failSet['conformance/misc/object-deletion-behaviour.html'] = true;
failSet['conformance/programs/program-test.html'] = true;
failSet['conformance/textures/tex-image-and-sub-image-2d-with-video.html'] = true;
failSet['conformance/textures/texture-mips.html'] = true;
failSet['conformance/textures/texture-npot.html'] = true;
}
break;
@ -158,7 +155,6 @@ function GetExpectedTestFailSet() {
failSet['conformance/misc/object-deletion-behaviour.html'] = true;
failSet['conformance/programs/get-active-test.html'] = true;
failSet['conformance/textures/tex-input-validation.html'] = true;
failSet['conformance/textures/texture-mips.html'] = true;
failSet['conformance/textures/texture-npot.html'] = true;
failSet['conformance/textures/texture-size-cube-maps.html'] = true;
failSet['conformance/textures/texture-size.html'] = true;

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

@ -15,11 +15,11 @@ fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_EXT_color_buffer_half_float.html]
fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_EXT_disjoint_timer_query.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
fail-if = (os == 'android') || (os == 'mac') || (os == 'win')
[webgl-mochitest/ensure-exts/test_EXT_frag_depth.html]
fail-if = (os == 'android')
[webgl-mochitest/ensure-exts/test_EXT_sRGB.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac' && os_version == '10.6') || (os == 'win')
fail-if = (os == 'android') || (os == 'mac' && os_version == '10.6') || (os == 'win')
[webgl-mochitest/ensure-exts/test_EXT_shader_texture_lod.html]
fail-if = (os == 'android') || (os == 'linux') || (os == 'mac')
[webgl-mochitest/ensure-exts/test_EXT_texture_filter_anisotropic.html]
@ -60,6 +60,8 @@ support-files = captureStream_common.js
[webgl-mochitest/test_fb_param_crash.html]
[webgl-mochitest/test_hidden_alpha.html]
skip-if = (os == 'b2g') || buildapp == 'mulet' # Mulet - bug 1093639 (crashes in libLLVM-3.0.so)
[webgl-mochitest/test_hidden_depth_stencil.html]
fail-if = (os == 'win' && (os_version == '5.1' || os_version == '6.1'))
[webgl-mochitest/test_implicit_color_buffer_float.html]
[webgl-mochitest/test_highp_fs.html]
[webgl-mochitest/test_no_arr_points.html]

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

@ -0,0 +1,159 @@
<!DOCTYPE HTML>
<title>WebGL test: Hidden depth/stencil passes without a depth/stencil buffer respectively</title>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='webgl-util.js'></script>
<body>
<script id='vs' type='x-shader/x-vertex'>
void main(void) {
gl_PointSize = 1.0; // Note that this is undefined if we don't write to it!
gl_Position = vec4(vec3(0), 1);
}
</script>
<script id='fs' type='x-shader/x-fragment'>
precision mediump float;
void main(void) {
gl_FragColor = vec4(0, 1, 0, 1);
}
</script>
<script>
function ColorString(arr) {
return '[' + arr[0] + ', ' + arr[1] + ', ' + arr[2] + ', ' + arr[3] + ']';
}
function DrawAndCheck(gl, infoPrefix, refColorStr) {
gl.viewport(0, 0, 1, 1);
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, 1);
var pixel = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
var pixelStr = ColorString(pixel);
ok(pixelStr == refColorStr, infoPrefix + pixelStr + ' should be ' + refColorStr);
}
function TestCurrent(gl, attribs, infoPrefix) {
infoPrefix = infoPrefix + JSON.stringify(attribs) + ': ';
var CLEAR_COLOR = ColorString([255, 0, 0, 255]);
var DRAW_COLOR = ColorString([0, 255, 0, 255]);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
DrawAndCheck(gl, infoPrefix + 'initial: ', DRAW_COLOR);
if (!attribs.depth) {
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.NEVER);
gl.disable(gl.STENCIL_TEST);
// Depth test is enabled, and should pass NEVER.
// Since there is no depth buffer, the depth test is not run.
// Stencil test is disabled.
DrawAndCheck(gl, infoPrefix + 'no-depth: ', DRAW_COLOR);
}
if (!attribs.stencil) {
gl.disable(gl.DEPTH_TEST);
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(gl.NEVER, 0, 0);
// Depth test is disabled.
// Stencil test is enabled, and should pass NEVER.
// Since there is no stencil buffer, the stencil test is not run.
DrawAndCheck(gl, infoPrefix + 'no-stencil: ', DRAW_COLOR);
}
}
function TestBackbuffer(requestedAttribs) {
var canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
var gl = canvas.getContext('experimental-webgl', requestedAttribs);
if (!gl) {
ok(true, 'WebGL doesn\'t work, skipping test.');
return;
}
ok(gl.drawingBufferWidth == 1 && gl.drawingBufferHeight == 1,
'backbuffer should be 1x1');
var prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs');
gl.useProgram(prog);
var attribs = {
depth: gl.getContextAttributes().depth,
stencil: gl.getContextAttributes().stencil,
};
TestCurrent(gl, attribs, 'Backbuffer: ');
}
function TestUserFB() {
var canvas = document.createElement('canvas');
var gl = canvas.getContext('experimental-webgl');
if (!gl) {
ok(true, 'WebGL doesn\'t work, skipping test.');
return;
}
var prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs');
gl.useProgram(prog);
var rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 1, 1);
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
var depthRB = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthRB);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
var stencilRB = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, stencilRB);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, 1, 1);
do {
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRB);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, null);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
ok(true, 'Depth-only user FB is incomplete. This is allowed.');
break;
}
TestCurrent(gl, {depth: true, stencil: false}, 'Depth-only user FB');
} while (false);
do {
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, stencilRB);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
ok(true, 'Stencil-only user FB is incomplete. This is allowed.');
break;
}
TestCurrent(gl, {depth: false, stencil: true}, 'Stencil-only user FB');
} while (false);
}
(function(){
TestBackbuffer({depth: true, stencil: false});
TestBackbuffer({depth: false, stencil: true});
TestUserFB();
})();
</script>
</body>

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

@ -82,6 +82,20 @@ HTMLSourceElement::WouldMatchMediaForDocument(const nsAString& aMedia,
return pctx && mediaList->Matches(pctx, nullptr);
}
void
HTMLSourceElement::UpdateMediaList(const nsAttrValue* aValue)
{
mMediaList = nullptr;
nsString mediaStr;
if (!aValue || (mediaStr = aValue->GetStringValue()).IsEmpty()) {
return;
}
nsCSSParser cssParser;
mMediaList = new nsMediaList();
cssParser.ParseMediaList(mediaStr, nullptr, 0, mMediaList, false);
}
nsresult
HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify)
@ -105,23 +119,17 @@ HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
img->PictureSourceSrcsetChanged(AsContent(), strVal, aNotify);
} else if (aName == nsGkAtoms::sizes) {
img->PictureSourceSizesChanged(AsContent(), strVal, aNotify);
} else if (aName == nsGkAtoms::media ||
aName == nsGkAtoms::type) {
} else if (aName == nsGkAtoms::media) {
UpdateMediaList(aValue);
img->PictureSourceMediaOrTypeChanged(AsContent(), aNotify);
} else if (aName == nsGkAtoms::type) {
img->PictureSourceMediaOrTypeChanged(AsContent(), aNotify);
}
}
}
} else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::media) {
mMediaList = nullptr;
if (aValue) {
nsString mediaStr = aValue->GetStringValue();
if (!mediaStr.IsEmpty()) {
nsCSSParser cssParser;
mMediaList = new nsMediaList();
cssParser.ParseMediaList(mediaStr, nullptr, 0, mMediaList, false);
}
}
UpdateMediaList(aValue);
} else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
mSrcMediaSource = nullptr;
if (aValue) {

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

@ -13,6 +13,7 @@
#include "mozilla/dom/HTMLMediaElement.h"
class nsMediaList;
class nsAttrValue;
namespace mozilla {
namespace dom {
@ -118,6 +119,9 @@ protected:
private:
RefPtr<nsMediaList> mMediaList;
RefPtr<MediaSource> mSrcMediaSource;
// Generates a new nsMediaList using the given input
void UpdateMediaList(const nsAttrValue* aValue);
};
} // namespace dom

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

@ -127,8 +127,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_blob_archive.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_blob_file_backed.html]
# This test can only run in the main process.
skip-if = buildapp == 'b2g' || e10s
skip-if = buildapp == 'b2g'
[test_blob_simple.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_blob_worker_crash.html]

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

@ -9,10 +9,6 @@ var testGenerator = testSteps();
function testSteps()
{
const fileIOFlags = 0x02 | // PR_WRONLY
0x08 | // PR_CREATEFILE
0x20; // PR_TRUNCATE
const filePerms = 0o664;
const fileData = "abcdefghijklmnopqrstuvwxyz";
const fileType = "text/plain";
@ -23,22 +19,12 @@ function testSteps()
info("Creating temp file");
let dirSvc =
SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
let testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.createUnique(SpecialPowers.Ci.nsIFile.NORMAL_FILE_TYPE, filePerms);
SpecialPowers.createFiles([{data:fileData, options:{type:fileType}}], function (files) {
testGenerator.next(files[0]);
});
info("Writing temp file");
let file = yield undefined;
let outStream =
SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, fileIOFlags, filePerms, 0);
outStream.write(fileData, fileData.length);
outStream.close();
let file = SpecialPowers.createDOMFile(testFile.path, { type: fileType });
ok(file instanceof File, "Got a File object");
is(file.size, fileData.length, "Correct size");
is(file.type, fileType, "Correct type");
@ -67,7 +53,6 @@ function testSteps()
db = event.target.result;
file = null;
testFile.remove(false);
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
objectStore.get(objectStoreKey).onsuccess = grabEventAndContinueHandler;

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

@ -18,11 +18,11 @@ function is(a, b, msg) {
}
function ok(cond, msg) {
do_check_true(!!cond, Components.stack.caller);
do_check_true(!!cond, Components.stack.caller);
}
function isnot(a, b, msg) {
do_check_neq(a, b, Components.stack.caller);
do_check_neq(a, b, Components.stack.caller);
}
function executeSoon(fun) {
@ -69,6 +69,8 @@ function finishTest()
"free");
}
SpecialPowers.removeFiles();
do_execute_soon(function(){
testGenerator.close();
do_test_finished();
@ -150,12 +152,12 @@ function compareKeys(k1, k2) {
if (!(k2 instanceof Array) ||
k1.length != k2.length)
return false;
for (let i = 0; i < k1.length; ++i) {
if (!compareKeys(k1[i], k2[i]))
return false;
}
return true;
}
@ -484,7 +486,46 @@ var SpecialPowers = {
return Cu;
},
createDOMFile: function(file, options) {
return new File(file, options);
// Based on SpecialPowersObserver.prototype.receiveMessage
createFiles: function(requests, callback) {
let dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
let filePaths = new Array;
if (!this._createdFiles) {
this._createdFiles = new Array;
}
let createdFiles = this._createdFiles;
requests.forEach(function(request) {
const filePerms = 0o666;
let testFile = dirSvc.get("ProfD", Ci.nsIFile);
if (request.name) {
testFile.append(request.name);
} else {
testFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, filePerms);
}
let outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE
filePerms, 0);
if (request.data) {
outStream.write(request.data, request.data.length);
outStream.close();
}
filePaths.push(new File(testFile.path, request.options));
createdFiles.push(testFile);
});
setTimeout(function () {
callback(filePaths);
}, 0);
},
removeFiles: function() {
if (this._createdFiles) {
this._createdFiles.forEach(function (testFile) {
try {
testFile.remove(false);
} catch (e) {}
});
this._createdFiles = null;
}
},
};

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

@ -11,11 +11,13 @@ interface nsIURI;
interface nsIFrameLoaderOwner;
[scriptable, uuid(e774db14-79ac-4156-a7a3-aa3fd0a22c10)]
interface nsIOpenURIInFrameParams : nsISupports
{
attribute DOMString referrer;
attribute boolean isPrivate;
[implicit_jscontext]
readonly attribute jsval openerOriginAttributes;
};
[scriptable, uuid(9d17f3dd-672b-451e-afd2-b1115df780d5)]

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

@ -73,6 +73,7 @@
#include "mozilla/unused.h"
#include "mozInlineSpellChecker.h"
#include "nsDocShell.h"
#include "nsIConsoleListener.h"
#include "nsICycleCollectorListener.h"
#include "nsIDragService.h"
@ -872,12 +873,22 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
baseURI->GetSpec(baseURIString);
}
auto* opener = nsPIDOMWindowOuter::From(aParent);
nsIDocShell* openerShell;
RefPtr<nsDocShell> openerDocShell;
if (opener && (openerShell = opener->GetDocShell())) {
openerDocShell = static_cast<nsDocShell*>(openerShell);
}
nsresult rv;
if (!SendCreateWindow(aTabOpener, newChild,
aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified, url,
name, features,
baseURIString,
openerDocShell
? openerDocShell->GetOriginAttributes()
: DocShellOriginAttributes(),
&rv,
aWindowIsNew,
&frameScripts,

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

@ -5465,6 +5465,7 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
const nsString& aName,
const nsCString& aFeatures,
const nsCString& aBaseURI,
const DocShellOriginAttributes& aOpenerOriginAttributes,
nsresult* aResult,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
@ -5563,7 +5564,8 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
loadContext->GetUsePrivateBrowsing(&isPrivate);
}
nsCOMPtr<nsIOpenURIInFrameParams> params = new nsOpenURIInFrameParams();
nsCOMPtr<nsIOpenURIInFrameParams> params =
new nsOpenURIInFrameParams(aOpenerOriginAttributes);
params->SetReferrer(NS_ConvertUTF8toUTF16(aBaseURI));
params->SetIsPrivate(isPrivate);

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

@ -501,6 +501,7 @@ public:
const nsString& aName,
const nsCString& aFeatures,
const nsCString& aBaseURI,
const DocShellOriginAttributes& aOpenerOriginAttributes,
nsresult* aResult,
bool* aWindowIsNew,
InfallibleTArray<FrameScriptInfo>* aFrameScripts,

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

@ -94,6 +94,7 @@ using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
using mozilla::DataStorageType from "ipc/DataStorageIPCUtils.h";
using mozilla::DocShellOriginAttributes from "mozilla/ipc/BackgroundUtils.h";
union ChromeRegistryItem
{
@ -1172,7 +1173,8 @@ parent:
nsCString aURI,
nsString aName,
nsCString aFeatures,
nsCString aBaseURI)
nsCString aBaseURI,
DocShellOriginAttributes aOpenerOriginAttributes)
returns (nsresult rv,
bool windowOpened,
FrameScriptInfo[] frameScripts,

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

@ -273,6 +273,25 @@ OpenDumpFile(AudioStream* aStream)
return f;
}
template <typename T>
typename EnableIf<IsSame<T, int16_t>::value, void>::Type
WriteDumpFileHelper(T* aInput, size_t aSamples, FILE* aFile) {
fwrite(aInput, sizeof(T), aSamples, aFile);
}
template <typename T>
typename EnableIf<IsSame<T, float>::value, void>::Type
WriteDumpFileHelper(T* aInput, size_t aSamples, FILE* aFile) {
AutoTArray<uint8_t, 1024*2> buf;
buf.SetLength(aSamples*2);
uint8_t* output = buf.Elements();
for (uint32_t i = 0; i < aSamples; ++i) {
SetUint16LE(output + i*2, int16_t(aInput[i]*32767.0f));
}
fwrite(output, 2, aSamples, aFile);
fflush(aFile);
}
static void
WriteDumpFile(FILE* aDumpFile, AudioStream* aStream, uint32_t aFrames,
void* aBuffer)
@ -281,23 +300,21 @@ WriteDumpFile(FILE* aDumpFile, AudioStream* aStream, uint32_t aFrames,
return;
uint32_t samples = aStream->GetOutChannels()*aFrames;
if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
fwrite(aBuffer, 2, samples, aDumpFile);
return;
}
NS_ASSERTION(AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_FLOAT32, "bad format");
AutoTArray<uint8_t, 1024*2> buf;
buf.SetLength(samples*2);
float* input = static_cast<float*>(aBuffer);
uint8_t* output = buf.Elements();
for (uint32_t i = 0; i < samples; ++i) {
SetUint16LE(output + i*2, int16_t(input[i]*32767.0f));
}
fwrite(output, 2, samples, aDumpFile);
fflush(aDumpFile);
using SampleT = AudioSampleTraits<AUDIO_OUTPUT_FORMAT>::Type;
WriteDumpFileHelper(reinterpret_cast<SampleT*>(aBuffer), samples, aDumpFile);
}
template <AudioSampleFormat N>
struct ToCubebFormat {
static const cubeb_sample_format value = CUBEB_SAMPLE_FLOAT32NE;
};
template <>
struct ToCubebFormat<AUDIO_FORMAT_S16> {
static const cubeb_sample_format value = CUBEB_SAMPLE_S16NE;
};
nsresult
AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
const dom::AudioChannel aAudioChannel)
@ -333,12 +350,8 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
return NS_ERROR_INVALID_ARG;
}
#endif
if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
params.format = CUBEB_SAMPLE_S16NE;
} else {
params.format = CUBEB_SAMPLE_FLOAT32NE;
}
params.format = ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value;
mAudioClock.Init();
return OpenCubeb(params);

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

@ -134,8 +134,10 @@ static const char* const gWaveTypes[5] = {
nullptr
};
static char const *const gWaveCodecs[2] = {
static char const *const gWaveCodecs[4] = {
"1", // Microsoft PCM Format
"6", // aLaw Encoding
"7", // uLaw Encoding
nullptr
};

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

@ -104,7 +104,6 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttribute
, mEvictionOccurred(false)
, mMonitor("TrackBuffersManager")
, mAppendRunning(false)
, mSegmentParserLoopRunning(false)
{
MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread");
}
@ -301,7 +300,6 @@ void
TrackBuffersManager::CompleteResetParserState()
{
MOZ_ASSERT(OnTaskQueue());
MOZ_DIAGNOSTIC_ASSERT(!mSegmentParserLoopRunning);
MSE_DEBUG("");
for (auto& track : GetTracksList()) {
@ -437,7 +435,6 @@ bool
TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(!mSegmentParserLoopRunning, "Logic error: Append in progress");
MSE_DEBUG("From %.2fs to %.2f",
aInterval.mStart.ToSeconds(), aInterval.mEnd.ToSeconds());
@ -576,8 +573,6 @@ TrackBuffersManager::SegmentParserLoop()
{
MOZ_ASSERT(OnTaskQueue());
mSegmentParserLoopRunning = true;
while (true) {
// 1. If the input buffer is empty, then jump to the need more data step below.
if (!mInputBuffer || mInputBuffer->IsEmpty()) {
@ -702,7 +697,6 @@ TrackBuffersManager::NeedMoreData()
MSE_DEBUG("");
RestoreCachedVariables();
mAppendRunning = false;
mSegmentParserLoopRunning = false;
{
// Wake-up any pending Abort()
MonitorAutoLock mon(mMonitor);
@ -716,7 +710,6 @@ TrackBuffersManager::RejectAppend(nsresult aRejectValue, const char* aName)
{
MSE_DEBUG("rv=%d", aRejectValue);
mAppendRunning = false;
mSegmentParserLoopRunning = false;
{
// Wake-up any pending Abort()
MonitorAutoLock mon(mMonitor);

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

@ -350,11 +350,8 @@ private:
// Monitor to protect following objects accessed across multipple threads.
// mMonitor is also notified if the value of mAppendRunning becomes false.
mutable Monitor mMonitor;
// Set to true while SegmentParserLoop is running.
// Set to true while a BufferAppend is running or is pending.
Atomic<bool> mAppendRunning;
// Set to true while SegmentParserLoop is running.
// This is for diagnostic only. Only accessed on the task queue.
bool mSegmentParserLoopRunning;
// Stable audio and video track time ranges.
media::TimeIntervals mVideoBufferedRanges;
media::TimeIntervals mAudioBufferedRanges;

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

@ -155,6 +155,11 @@ EXPORTS.mozilla.media.webrtc += [
'webrtc/WebrtcGlobal.h',
]
if not CONFIG['MOZ_WEBRTC']:
EXPORTS.mtransport += [
'../../media/mtransport/runnable_utils.h',
]
IPDL_SOURCES += [
'webrtc/PWebrtcGlobal.ipdl'
]

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

@ -12,6 +12,39 @@ using mp4_demuxer::ByteReader;
namespace mozilla {
int16_t
DecodeALawSample(uint8_t aValue)
{
aValue = aValue ^ 0x55;
int8_t sign = (aValue & 0x80) ? -1 : 1;
uint8_t exponent = (aValue & 0x70) >> 4;
uint8_t mantissa = aValue & 0x0F;
int16_t sample = mantissa << 4;
switch (exponent) {
case 0:
sample += 8;
break;
case 1:
sample += 0x108;
break;
default:
sample += 0x108;
sample <<= exponent - 1;
}
return sign * sample;
}
int16_t
DecodeULawSample(uint8_t aValue)
{
aValue = aValue ^ 0xFF;
int8_t sign = (aValue & 0x80) ? -1 : 1;
uint8_t exponent = (aValue & 0x70) >> 4;
uint8_t mantissa = aValue & 0x0F;
int16_t sample = (33 + 2 * mantissa) * (2 << (exponent + 1)) - 33;
return sign * sample;
}
WaveDataDecoder::WaveDataDecoder(const AudioInfo& aConfig,
FlushableTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback)
@ -69,18 +102,30 @@ WaveDataDecoder::DoDecode(MediaRawData* aSample)
auto buffer = MakeUnique<AudioDataValue[]>(frames * mInfo.mChannels);
for (int i = 0; i < frames; ++i) {
for (unsigned int j = 0; j < mInfo.mChannels; ++j) {
if (mInfo.mBitDepth == 8) {
if (mInfo.mProfile == 6) { //ALAW Data
uint8_t v = aReader.ReadU8();
int16_t decoded = DecodeALawSample(v);
buffer[i * mInfo.mChannels + j] =
UInt8bitToAudioSample<AudioDataValue>(v);
} else if (mInfo.mBitDepth == 16) {
int16_t v = aReader.ReadLE16();
IntegerToAudioSample<AudioDataValue>(decoded);
} else if (mInfo.mProfile == 7) { //ULAW Data
uint8_t v = aReader.ReadU8();
int16_t decoded = DecodeULawSample(v);
buffer[i * mInfo.mChannels + j] =
IntegerToAudioSample<AudioDataValue>(v);
} else if (mInfo.mBitDepth == 24) {
int32_t v = aReader.ReadLE24();
buffer[i * mInfo.mChannels + j] =
Int24bitToAudioSample<AudioDataValue>(v);
IntegerToAudioSample<AudioDataValue>(decoded);
} else { //PCM Data
if (mInfo.mBitDepth == 8) {
uint8_t v = aReader.ReadU8();
buffer[i * mInfo.mChannels + j] =
UInt8bitToAudioSample<AudioDataValue>(v);
} else if (mInfo.mBitDepth == 16) {
int16_t v = aReader.ReadLE16();
buffer[i * mInfo.mChannels + j] =
IntegerToAudioSample<AudioDataValue>(v);
} else if (mInfo.mBitDepth == 24) {
int32_t v = aReader.ReadLE24();
buffer[i * mInfo.mChannels + j] =
Int24bitToAudioSample<AudioDataValue>(v);
}
}
}
}
@ -132,6 +177,8 @@ WaveDataDecoder::IsWave(const nsACString& aMimeType)
// WAVdemuxer uses "audio/wave; codecs=aNum".
return aMimeType.EqualsLiteral("audio/x-wav") ||
aMimeType.EqualsLiteral("audio/wave; codecs=1") ||
aMimeType.EqualsLiteral("audio/wave; codecs=6") ||
aMimeType.EqualsLiteral("audio/wave; codecs=7") ||
aMimeType.EqualsLiteral("audio/wave; codecs=65534");
}

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

@ -263,6 +263,8 @@ AndroidDecoderModule::SupportsMimeType(const nsACString& aMimeType) const
// To avoid this we check for wav types here.
if (aMimeType.EqualsLiteral("audio/x-wav") ||
aMimeType.EqualsLiteral("audio/wave; codecs=1") ||
aMimeType.EqualsLiteral("audio/wave; codecs=6") ||
aMimeType.EqualsLiteral("audio/wave; codecs=7") ||
aMimeType.EqualsLiteral("audio/wave; codecs=65534")) {
return false;
}

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

@ -474,13 +474,14 @@ void
Shutdown(void)
{
OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex());
if (!CamerasSingleton::Child()) {
CamerasChild* child = CamerasSingleton::Child();
if (!child) {
// We don't want to cause everything to get fired up if we're
// really already shut down.
LOG(("Shutdown when already shut down"));
return;
}
GetCamerasChild()->Shutdown();
child->ShutdownAll();
}
class ShutdownRunnable : public nsRunnable {
@ -505,14 +506,22 @@ private:
};
void
CamerasChild::Shutdown()
CamerasChild::ShutdownAll()
{
// Called with CamerasSingleton::Mutex() held
ShutdownParent();
ShutdownChild();
}
void
CamerasChild::ShutdownParent()
{
// Called with CamerasSingleton::Mutex() held
{
MonitorAutoLock monitor(mReplyMonitor);
mIPCIsAlive = false;
monitor.NotifyAll();
}
if (CamerasSingleton::Thread()) {
LOG(("Dispatching actor deletion"));
// Delete the parent actor.
@ -524,6 +533,16 @@ CamerasChild::Shutdown()
return NS_OK;
});
CamerasSingleton::Thread()->Dispatch(deleteRunnable, NS_DISPATCH_NORMAL);
} else {
LOG(("ShutdownParent called without PBackground thread"));
}
}
void
CamerasChild::ShutdownChild()
{
// Called with CamerasSingleton::Mutex() held
if (CamerasSingleton::Thread()) {
LOG(("PBackground thread exists, dispatching close"));
// Dispatch closing the IPC thread back to us when the
// BackgroundChild is closed.
@ -607,7 +626,11 @@ CamerasChild::~CamerasChild()
{
OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex());
Shutdown();
// In normal circumstances we've already shut down and the
// following does nothing. But on fatal IPC errors we will
// get destructed immediately, and should not try to reach
// the parent.
ShutdownChild();
}
MOZ_COUNT_DTOR(CamerasChild);

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

@ -192,13 +192,9 @@ public:
const unsigned int device_nameUTF8Length,
char* unique_idUTF8,
const unsigned int unique_idUTF8Length);
void Shutdown();
void ShutdownAll();
webrtc::ExternalRenderer* Callback(CaptureEngine aCapEngine, int capture_id);
void AddCallback(const CaptureEngine aCapEngine, const int capture_id,
webrtc::ExternalRenderer* render);
void RemoveCallback(const CaptureEngine aCapEngine, const int capture_id);
private:
CamerasChild();
@ -207,6 +203,11 @@ private:
// decidecated Cameras IPC/PBackground thread.
bool DispatchToParent(nsIRunnable* aRunnable,
MonitorAutoLock& aMonitor);
void AddCallback(const CaptureEngine aCapEngine, const int capture_id,
webrtc::ExternalRenderer* render);
void RemoveCallback(const CaptureEngine aCapEngine, const int capture_id);
void ShutdownParent();
void ShutdownChild();
nsTArray<CapturerElement> mCallbacks;
// Protects the callback arrays

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

@ -11,6 +11,8 @@ function check_wave(v, enabled) {
// Supported Wave codecs
check("audio/wave; codecs=1", "probably");
check("audio/wave; codecs=6", "probably");
check("audio/wave; codecs=7", "probably");
// "no codecs" should be supported, I guess
check("audio/wave; codecs=", "probably");
check("audio/wave; codecs=\"\"", "probably");

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

@ -158,6 +158,10 @@ var gPlayTests = [
{ name:"16bit_wave_extrametadata.wav", type:"audio/x-wav", duration:1.108 },
// 24-bit samples
{ name:"wavedata_s24.wav", type:"audio/x-wav", duration:1.0 },
// aLaw compressed wave file
{ name:"wavedata_alaw.wav", type:"audio/x-wav", duration:1.0 },
// uLaw compressed wave file
{ name:"wavedata_ulaw.wav", type:"audio/x-wav", duration:1.0 },
// Ogg stream without eof marker
{ name:"bug461281.ogg", type:"application/ogg", duration:2.208 },

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

@ -557,12 +557,16 @@ support-files =
wave_metadata_unknown_tag.wav^headers^
wave_metadata_utf8.wav
wave_metadata_utf8.wav^headers^
wavedata_alaw.wav
wavedata_alaw.wav^headers^
wavedata_s24.wav
wavedata_s24.wav^headers^
wavedata_s16.wav
wavedata_s16.wav^headers^
wavedata_u8.wav
wavedata_u8.wav^headers^
wavedata_ulaw.wav
wavedata_ulaw.wav^headers^
[test_access_control.html]
skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984

Двоичные данные
dom/media/test/wavedata_alaw.wav Normal file

Двоичный файл не отображается.

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

@ -0,0 +1 @@
Cache-Control: no-store

Двоичные данные
dom/media/test/wavedata_ulaw.wav Normal file

Двоичный файл не отображается.

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

@ -0,0 +1 @@
Cache-Control: no-store

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

@ -74,15 +74,6 @@
]);
test.chain.insertBefore('PC_LOCAL_CREATE_OFFER', [
// addTrack will not finish until GMP is initted, but addTrack doesn't
// give us a promise to wait on or a callback. We cannot do
// setParameters until addTrack is finished. So, we create a dummy
// offer, which _does_ give us a promise to wait on, and once that is
// done we know that addTrack is done too.
// TODO(bug 1241153): Remove the need for this hack.
function PC_LOCAL_CREATE_OFFER(test) {
return test.createOffer(test.pcLocal);
},
function PC_LOCAL_SET_RIDS(test) {
var senders = test.pcLocal._pc.getSenders();
is(senders.length, 1, "We have exactly one RTP sender");

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

@ -52,7 +52,10 @@ WaveDecoder::CanHandleMediaType(const nsACString& aType,
{
if (aType.EqualsASCII("audio/wave") || aType.EqualsASCII("audio/x-wav") ||
aType.EqualsASCII("audio/wav") || aType.EqualsASCII("audio/x-pn-wav")) {
return IsEnabled() && (aCodecs.IsEmpty() || aCodecs.EqualsASCII("1"));
return IsEnabled() && (aCodecs.IsEmpty() ||
aCodecs.EqualsASCII("1") ||
aCodecs.EqualsASCII("6") ||
aCodecs.EqualsASCII("7"));
}
return false;

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

@ -148,7 +148,8 @@ MediaEngineGonkVideoSource::NumCapabilities()
nsresult
MediaEngineGonkVideoSource::Allocate(const dom::MediaTrackConstraints& aConstraints,
const MediaEnginePrefs& aPrefs,
const nsString& aDeviceId)
const nsString& aDeviceId,
const nsACString& aOrigin)
{
LOG((__FUNCTION__));

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

@ -62,7 +62,8 @@ public:
nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
const MediaEnginePrefs &aPrefs,
const nsString& aDeviceId) override;
const nsString& aDeviceId,
const nsACString& aOrigin) override;
nsresult Deallocate() override;
nsresult Start(SourceMediaStream* aStream, TrackID aID) override;
nsresult Stop(SourceMediaStream* aSource, TrackID aID) override;

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

@ -41,8 +41,6 @@ if CONFIG['MOZ_WEBSPEECH']:
'test/nsFakeSynthServices.cpp'
]
DIRS = []
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DIRS += ['windows']

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

@ -375,6 +375,9 @@ protected:
bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
// We don't call WorkerRunnable::PreDispatch because it would assert the
// wrong thing about which thread we're on.
AssertIsOnMainThread();
return true;
}
@ -382,6 +385,9 @@ protected:
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult) override
{
// We don't call WorkerRunnable::PostDispatch because it would assert the
// wrong thing about which thread we're on.
AssertIsOnMainThread();
}
bool

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

@ -90,12 +90,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
switch(event.data.test) {
case "insecurePage_navigate_child":
ok((event.data.msg == "navigated to insecure iframe on insecure page"), "navigating to insecure iframe blocked on insecure page");
is(event.data.msg, "navigated to insecure iframe on insecure page", "navigating to insecure iframe blocked on insecure page");
testsToRunInsecure["insecurePage_navigate_child"] = true;
break;
case "insecurePage_navigate_grandchild":
ok((event.data.msg == "navigated to insecure grandchild iframe on insecure page"), "navigating to insecure grandchild iframe blocked on insecure page");
is(event.data.msg, "navigated to insecure grandchild iframe on insecure page", "navigating to insecure grandchild iframe blocked on insecure page");
testsToRunInsecure["insecurePage_navigate_grandchild"] = true;
break;
@ -105,7 +105,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
break;
case "blankTarget":
ok((event.data.msg == "opened an http link with target=_blank from a secure page"), "couldn't open an http link in a new window from a secure page");
is(event.data.msg, "opened an http link with target=_blank from a secure page", "couldn't open an http link in a new window from a secure page");
testsToRunSecure["blankTarget"] = true;
break;

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

@ -360,14 +360,13 @@ ValueFromStringHelper(nsCSSProperty aPropID,
}
}
nsDependentSubstring subString(aString, subStringBegin);
if (!StyleAnimationValue::ComputeValue(
aPropID,
aTargetElement,
nsCSSPseudoElements::ePseudo_NotPseudoElement,
subString,
true,
aStyleAnimValue,
aIsContextSensitive)) {
if (!StyleAnimationValue::ComputeValue(aPropID,
aTargetElement,
CSSPseudoElementType::NotPseudo,
subString,
true,
aStyleAnimValue,
aIsContextSensitive)) {
return false;
}
if (isNegative) {

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

@ -168,4 +168,5 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s
[test_bug1022869.html]
[test_bug1112040.html]
[test_bug1160342_marquee.html]
[test_bug1171215.html]

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

@ -0,0 +1,228 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1160342
-->
<head>
<title>Test for Bug 411103</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1160342">Mozilla Bug 1160342</a>
<p id="display"></p>
<div id="content">
<marquee id="a">marquee</marquee>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var x=document.getElementById('a');
SimpleTest.waitForExplicitFinish();
setTimeout(function() {
is(x.behavior, "scroll", "Wrong behavior value");
x.setAttribute('behavior', 'alternate');
is(x.behavior, "alternate", "Wrong behavior value");
x.setAttribute('behavior', 'invalid');
todo_is(x.behavior, "scroll", "Wrong behavior value");;
x.setAttribute('behavior', 'Scroll');
is(x.behavior, "scroll", "Wrong behavior value");
x.setAttribute('behavior', 'Slide');
is(x.behavior, "slide", "Wrong behavior value");
x.removeAttribute('behavior');
is(x.behavior, "scroll", "Wrong behavior value");
x.behavior = 'alternate';
is(x.behavior, "alternate", "Wrong behavior value");
try {
x.behavior = 'invalid';
todo_is(false, true, "marquee.behavior = 'invalid' should throw");
} catch(e) {
ok(true, "Exception was raised");
}
is(x.behavior, "alternate", "Wrong behavior value");
x.behavior = 'Slide';
is(x.behavior, "slide", "Wrong behavior value");
try {
x.behavior = 'invalid';
todo_is(false, true, "marquee.behavior = 'invalid' should throw");
} catch(e) {
ok(true, "Exception was raised");
}
is(x.behavior, "slide", "Wrong behavior value");
is(x.loop, -1, "Wrong loop value");
x.setAttribute('loop', '1');
is(x.loop, 1, "Wrong loop value");
x.setAttribute('loop', 'invalid');
todo_is(x.loop, -1, "Wrong loop value");
x.setAttribute('loop', '1000');
is(x.loop, 1000, "Wrong loop value");
x.setAttribute('loop', '-1');
is(x.loop, -1, "Wrong loop value");
x.setAttribute('loop', '1000');
is(x.loop, 1000, "Wrong loop value");
x.removeAttribute('loop');
is(x.loop, -1, "Wrong loop value");
x.loop = 1;
is(x.loop, 1, "Wrong loop value");
try {
x.loop = -2;
todo_is(false, true, "marquee.loop = -2 should throw");
} catch(e) {
ok(true, "Exception was raised");
}
todo_is(x.loop, 1, "Wrong loop value");
try {
x.loop = 'invalid';
todo_is(false, true, ".loop = 'invalid' should throw");
} catch(e) {
ok(true, "Exception was raised");
}
todo_is(x.loop, 1, "Wrong loop value");
try {
x.loop = null;
todo_is(false, true, "marquee.loop = null should throw");
} catch(e) {
ok(true, "Exception was raised");
}
todo_is(x.loop, 1, "Wrong loop value");
x.loop = -1;
is(x.loop, -1, "Wrong loop value");
x.loop = '100';
is(x.loop, 100, "Wrong loop value");
is(x.scrollAmount, 6, "Wrong scrollAmount value");
x.setAttribute('scrollAmount', '1');
is(x.scrollAmount, 1, "Wrong scrollAmount value");
x.setAttribute('scrollAmount', 'invalid');
todo_is(x.scrollAmount, 6, "Wrong scrollAmount value");
x.setAttribute('scrollAmount', '1000');
is(x.scrollAmount, 1000, "Wrong scrollAmount value");
x.setAttribute('scrollAmount', '-1');
is(x.scrollAmount, 1000, "Wrong scrollAmount value");
x.setAttribute('scrollAmount', '999');
is(x.scrollAmount, 999, "Wrong scrollAmount value");
x.removeAttribute('scrollAmount');
is(x.scrollAmount, 6, "Wrong scrollAmount value");
x.scrollAmount = 1;
is(x.scrollAmount, 1, "Wrong scrollAmount value");
try {
x.scrollAmount = -2;
todo_is(false, true, "marquee.scrollAmount = -2 should throw");
} catch(e) {
ok(true, "Exception was raised");
}
is(x.scrollAmount, 1, "Wrong scrollAmount value");
x.scrollAmount = 'invalid';
todo_is(x.scrollAmount, 0, "Wrong scrollAmount value");
x.scrollAmount = 1;
x.scrollAmount = null;
todo_is(x.scrollAmount, 0, "Wrong scrollAmount value");
x.scrollAmount = '2';
is(x.scrollAmount, 2, "Wrong scrollAmount value");
is(x.scrollDelay, 85, "Wrong scrollDelay value");
x.setAttribute('scrollDelay', '1');
is(x.scrollDelay, 1, "Wrong scrollDelay value");
x.setAttribute('scrollDelay', 'invalid');
todo_is(x.scrollDelay, 85, "Wrong scrollDelay value");
x.setAttribute('scrollDelay', '70');
is(x.scrollDelay, 70, "Wrong scrollDelay value");
x.setAttribute('scrollDelay', '59');
is(x.scrollDelay, 59, "Wrong scrollDelay value");
x.setAttribute('scrollDelay', '1000');
is(x.scrollDelay, 1000, "Wrong scrollDelay value");
x.setAttribute('scrollDelay', '-1');
is(x.scrollDelay, 1000, "Wrong scrollDelay value");
x.removeAttribute('scrollDelay');
is(x.scrollDelay, 85, "Wrong scrollDelay value");
x.scrollDelay = 100;
is(x.scrollDelay, 100, "Wrong scrollDelay value");
try {
x.scrollDelay = -2;
todo_is(false, true, "marquee.scrollDelay = -2 should throw");
} catch(e) {
ok(true, "Exception was raised");
}
is(x.scrollDelay, 100, "Wrong scrollDelay value");
try {
x.scrollDelay = 'invalid';
todo_is(false, true, "marquee.scrollDelay = 'invalid' should throw");
} catch(e) {
ok(true, "Exception was raised");
}
is(x.scrollDelay, 100, "Wrong scrollDelay value");
try {
x.scrollDelay = null;
todo_is(false, true, "marquee.scrollDelay = null should throw");
} catch(e) {
ok(true, "Exception was raised");
}
is(x.scrollDelay, 100, "Wrong scrollDelay value");
try {
x.scrollDelay = -1;
todo_is(false, true, "marquee.scrollDelay = -1 should throw");
} catch(e) {
ok(true, "Exception was raised");
}
is(x.scrollDelay, 100, "Wrong scrollDelay value");
x.scrollDelay = '50';
is(x.scrollDelay, 50, "Wrong scrollDelay value");
is(x.trueSpeed, false, "Wrong trueSpeed value");
x.setAttribute('trueSpeed', '1');
is(x.trueSpeed, true, "Wrong trueSpeed value");
x.setAttribute('trueSpeed', 'false');
is(x.trueSpeed, true, "Wrong trueSpeed value");
x.removeAttribute('trueSpeed');
is(x.trueSpeed, false, "Wrong trueSpeed value");
x.trueSpeed = 1;
is(x.trueSpeed, true, "Wrong trueSpeed value");
x.trueSpeed = -2;
is(x.trueSpeed, true, "Wrong trueSpeed value");
x.trueSpeed = null;
is(x.trueSpeed, false, "Wrong trueSpeed value");
x.trueSpeed = '100';
is(x.trueSpeed, true, "Wrong trueSpeed value");
todo_is(x.direction, "left", "Wrong direction value");
x.setAttribute('direction', 'right');
is(x.direction, "right", "Wrong direction value");
x.setAttribute('direction', 'invalid');
todo_is(x.direction, "left", "Wrong direction value");
x.setAttribute('direction', 'RIGHT');
todo_is(x.direction, "right", "Wrong direction value");
x.removeAttribute('direction');
todo_is(x.direction, "left", "Wrong direction value");
x.direction = 'right';
is(x.direction, "right", "Wrong direction value");
try {
x.direction = 1;
todo_is(false, true, "marquee.direction = 1 should throw");
} catch(e) {
ok(true, "Exception was raised");
}
todo_is(x.direction, "right", "Wrong direction value");
try {
x.direction = null;
todo_is(false, true, "marquee.direction = null should throw");
} catch(e) {
ok(true, "Exception was raised");
}
todo_is(x.direction, "right", "Wrong direction value");
SimpleTest.finish();
}, 0);
</script>
</pre>
</body>
</html>

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

@ -165,7 +165,6 @@
expectEvents(1, 0, function() {
is(img.currentSrc, testPNG50, "Should have switched to testPNG50");
Math.sin(90);
// Now add a source *also* wanting that DPI *just before* the
// selected source. Properly re-running the algorithm should
@ -231,7 +230,7 @@ Math.sin(90);
is(img.currentSrc, testPNG100, "Should still have testPNG100");
// And a valid MQ
source1.media = "(min-resolution: 3dppx)";
source1.media = "(min-resolution: 1dppx)";
expectEvents(1, 0, function() {
// And a valid type...
source1.type = "image/png";

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

@ -319,6 +319,8 @@ public:
nsCOMPtr<nsIRunnable> runnable =
new RegistrationUpdateRunnable(mRegistration, true /* time check */);
NS_DispatchToMainThread(runnable.forget());
ExtendableEventWorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult);
}
};

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

@ -182,6 +182,7 @@ ServiceWorkerRegistrar::RegisterServiceWorker(
bool found = false;
for (uint32_t i = 0, len = mData.Length(); i < len; ++i) {
if (Equivalent(aData, mData[i])) {
mData[i] = aData;
found = true;
break;
}

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

@ -610,9 +610,7 @@ private:
WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult);
// Match the busy count increase from NotifyRunnable.
if (!aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false)) {
JS_ReportPendingException(aCx);
}
aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false);
aWorkerPrivate->CloseHandlerFinished();
}

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

@ -223,9 +223,7 @@ WorkerRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
#endif
if (mBehavior == WorkerThreadModifyBusyCount) {
if (!aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false)) {
aRunResult = false;
}
aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false);
}
if (!aRunResult) {
@ -350,10 +348,44 @@ WorkerRunnable::Run()
cx = jsapi.cx();
}
// If we're not on the worker thread we'll either be in our parent's
// compartment or the null compartment, so we need to enter our own.
// Note that we can't assert anything about mWorkerPrivate->GetWrapper()
// existing, since it may in fact have been GCed (and we may be one of the
// runnables cleaning up the worker as a result).
// If we are on the parent thread and that thread is not the main thread,
// then we must be a dedicated worker (because there are no
// Shared/ServiceWorkers whose parent is itself a worker) and then we
// definitely have a globalObject. If it _is_ the main thread, globalObject
// can be null for workers started from JSMs or other non-window contexts,
// sadly.
MOZ_ASSERT_IF(!targetIsWorkerThread && !isMainThread,
mWorkerPrivate->IsDedicatedWorker() && globalObject);
// If we're on the parent thread we might be in a null compartment in the
// situation described above when globalObject is null. Make sure to enter
// the compartment of the worker's reflector if there is one. There might
// not be one if we're just starting to compile the script for this worker.
Maybe<JSAutoCompartment> ac;
if (!targetIsWorkerThread && mWorkerPrivate->GetWrapper()) {
// If we're on the parent thread and have a reflector and a globalObject,
// then the compartments of cx, globalObject, and the worker's reflector
// should all match.
MOZ_ASSERT_IF(globalObject,
js::GetObjectCompartment(mWorkerPrivate->GetWrapper()) ==
js::GetContextCompartment(cx));
MOZ_ASSERT_IF(globalObject,
js::GetObjectCompartment(mWorkerPrivate->GetWrapper()) ==
js::GetObjectCompartment(globalObject->GetGlobalJSObject()));
// If we're on the parent thread and have a reflector, then our
// JSContext had better be either in the null compartment (and hence
// have no globalObject) or in the compartment of our reflector.
MOZ_ASSERT(!js::GetContextCompartment(cx) ||
js::GetObjectCompartment(mWorkerPrivate->GetWrapper()) ==
js::GetContextCompartment(cx),
"Must either be in the null compartment or in our reflector "
"compartment");
ac.emplace(cx, mWorkerPrivate->GetWrapper());
}
@ -610,6 +642,9 @@ bool
WorkerSameThreadRunnable::PreDispatch(JSContext* aCx,
WorkerPrivate* aWorkerPrivate)
{
// We don't call WorkerRunnable::PreDispatch, because we're using
// WorkerThreadModifyBusyCount for mBehavior, and WorkerRunnable will assert
// that PreDispatch is on the parent thread in that case.
aWorkerPrivate->AssertIsOnWorkerThread();
return true;
}
@ -619,6 +654,9 @@ WorkerSameThreadRunnable::PostDispatch(JSContext* aCx,
WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
// We don't call WorkerRunnable::PostDispatch, because we're using
// WorkerThreadModifyBusyCount for mBehavior, and WorkerRunnable will assert
// that PostDispatch is on the parent thread in that case.
aWorkerPrivate->AssertIsOnWorkerThread();
if (aDispatchResult) {
DebugOnly<bool> willIncrement = aWorkerPrivate->ModifyBusyCountFromWorker(aCx, true);
@ -627,21 +665,3 @@ WorkerSameThreadRunnable::PostDispatch(JSContext* aCx,
MOZ_ASSERT(willIncrement);
}
}
void
WorkerSameThreadRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aRunResult)
{
MOZ_ASSERT(aCx);
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
DebugOnly<bool> willDecrement = aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false);
MOZ_ASSERT(willDecrement);
if (!aRunResult) {
JS_ReportPendingException(aCx);
}
}

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

@ -115,26 +115,45 @@ protected:
// By default asserts that Dispatch() is being called on the right thread
// (ParentThread if |mTarget| is WorkerThread, or WorkerThread otherwise).
// Also increments the busy count of |mWorkerPrivate| if targeting the
// WorkerThread.
// WorkerThread. The JSContext passed in here is the one that was passed to
// Dispatch().
virtual bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
// By default asserts that Dispatch() is being called on the right thread
// (ParentThread if |mTarget| is WorkerThread, or WorkerThread otherwise).
// Also reports any Dispatch() failures as an exception on |aCx|, and
// busy count if targeting the WorkerThread and Dispatch() failed.
// Also reports any Dispatch() failures as an exception on |aCx|, and busy
// count if targeting the WorkerThread and Dispatch() failed. The JSContext
// passed in here is the one that was passed to Dispatch().
virtual void
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult);
// Must be implemented by subclasses. Called on the target thread.
// Must be implemented by subclasses. Called on the target thread. The return
// value will be passed to PostRun(). The JSContext passed in here comes from
// an AutoJSAPI (or AutoEntryScript) that we set up on the stack. If
// mBehavior is ParentThreadUnchangedBusyCount, it is in the compartment of
// mWorkerPrivate's reflector (i.e. the worker object in the parent thread),
// unless that reflector is null, in which case it's in the compartment of the
// parent global (which is the compartment reflector would have been in), or
// in the null compartment if there is no parent global. For other mBehavior
// values, we're running on the worker thread and aCx is in whatever
// compartment GetCurrentThreadJSContext() was in when nsIRunnable::Run() got
// called (XXXbz: Why is this a sane thing to be doing now that we have
// multiple globals per worker???). If it wasn't in a compartment, aCx will
// be in either the debugger global's compartment or the worker's global's
// compartment depending on whether IsDebuggerRunnable() is true.
virtual bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
// By default asserts that Run() (and WorkerRun()) were called on the correct
// thread. Any failures (false return from WorkerRun) are reported on |aCx|.
// Also sends an asynchronous message to the ParentThread if the busy
// count was previously modified in PreDispatch().
// thread. Also sends an asynchronous message to the ParentThread if the
// busy count was previously modified in PreDispatch().
//
// The aCx passed here is the same one as was passed to WorkerRun and is
// still in the same compartment. If aRunResult is false, any failures on
// aCx are reported. Otherwise failures are left to linger on the JSContext
// and maim later code (XXXbz: Aiming to fix that in bug 1072144).
virtual void
PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult);
@ -386,9 +405,8 @@ protected:
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult) override;
virtual void
PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aRunResult) override;
// We just delegate PostRun to WorkerRunnable, since it does exactly
// what we want.
};
// Base class for the runnable objects, which makes a synchronous call to

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

@ -294,6 +294,8 @@ SuspendWorkersForWindow(nsPIDOMWindowInner* aWindow);
void
ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow);
// A class that can be used with WorkerCrossThreadDispatcher to run a
// bit of C++ code on the worker thread.
class WorkerTask
{
protected:
@ -306,6 +308,8 @@ protected:
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerTask)
// The return value here has the same semantics as the return value
// of WorkerRunnable::WorkerRun.
virtual bool
RunTask(JSContext* aCx) = 0;
};

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

@ -570,6 +570,15 @@ nsDocShellTreeOwner::GetDevicePixelsPerDesktopPixel(double* aScale)
return NS_OK;
}
NS_IMETHODIMP
nsDocShellTreeOwner::SetPositionDesktopPix(int32_t aX, int32_t aY)
{
// Added to nsIBaseWindow in bug 1247335;
// implement if a use-case is found.
NS_ASSERTION(false, "implement me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocShellTreeOwner::SetPosition(int32_t aX, int32_t aY)
{

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

@ -1302,6 +1302,15 @@ nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale)
return NS_OK;
}
NS_IMETHODIMP
nsWebBrowser::SetPositionDesktopPix(int32_t aX, int32_t aY)
{
// Added to nsIBaseWindow in bug 1247335;
// implement if a use-case is found.
NS_ASSERTION(false, "implement me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsWebBrowser::SetPosition(int32_t aX, int32_t aY)
{

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

@ -554,6 +554,8 @@ DrawTargetSkia::ShouldLCDRenderText(FontType aFontType, AntialiasMode aAntialias
if (aAntialiasMode == AntialiasMode::DEFAULT) {
switch (aFontType) {
case FontType::MAC:
case FontType::GDI:
case FontType::DWRITE:
return true;
default:
// TODO: Figure out what to do for the other platforms.

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

@ -31,7 +31,6 @@
#include "TextureGarbageBin.h"
#include "gfx2DGlue.h"
#include "gfxPrefs.h"
#include "DriverCrashGuard.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "OGLShaderProgram.h" // for ShaderProgramType
@ -476,11 +475,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
return true;
}
GLContextCrashGuard crashGuard;
if (crashGuard.Crashed()) {
return false;
}
mWorkAroundDriverBugs = gfxPrefs::WorkAroundDriverBugs();
SymLoadStruct symbols[] = {

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

@ -1117,7 +1117,8 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData)
mMayHaveReadbackChild(false),
mChildrenChanged(false),
mEventRegionsOverride(EventRegionsOverride::NoOverride),
mVRDeviceID(0)
mVRDeviceID(0),
mInputFrameID(0)
{
MOZ_COUNT_CTOR(ContainerLayer);
mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT
@ -1279,7 +1280,8 @@ ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
mInheritedXScale, mInheritedYScale,
mPresShellResolution, mScaleToResolution,
mEventRegionsOverride,
mVRDeviceID);
mVRDeviceID,
mInputFrameID);
}
bool
@ -2146,7 +2148,7 @@ ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
aStream << " [force-ehr]";
}
if (mVRDeviceID) {
aStream << nsPrintfCString(" [hmd=%lu]", mVRDeviceID).get();
aStream << nsPrintfCString(" [hmd=%lu] [hmdframe=%l]", mVRDeviceID, mInputFrameID).get();
}
}

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

@ -2143,10 +2143,18 @@ public:
*/
void SetVRDeviceID(uint32_t aVRDeviceID) {
mVRDeviceID = aVRDeviceID;
Mutated();
}
uint32_t GetVRDeviceID() {
return mVRDeviceID;
}
void SetInputFrameID(int32_t aInputFrameID) {
mInputFrameID = aInputFrameID;
Mutated();
}
int32_t GetInputFrameID() {
return mInputFrameID;
}
/**
* Replace the current effective transform with the given one,
@ -2223,6 +2231,7 @@ protected:
bool mChildrenChanged;
EventRegionsOverride mEventRegionsOverride;
uint32_t mVRDeviceID;
int32_t mInputFrameID;
};
/**

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

@ -153,6 +153,32 @@ BasicCompositor::CreateRenderTargetFromSource(const IntRect &aRect,
return nullptr;
}
already_AddRefed<CompositingRenderTarget>
BasicCompositor::CreateRenderTargetForWindow(const IntRect& aRect, SurfaceInitMode aInit, BufferMode aBufferMode)
{
if (aBufferMode != BufferMode::BUFFER_NONE) {
return CreateRenderTarget(aRect, aInit);
}
MOZ_ASSERT(aRect.width != 0 && aRect.height != 0, "Trying to create a render target of invalid size");
if (aRect.width * aRect.height == 0) {
return nullptr;
}
MOZ_ASSERT(mDrawTarget);
// Adjust bounds rect to account for new origin at (0, 0).
IntRect rect(0, 0, aRect.XMost(), aRect.YMost());
RefPtr<BasicCompositingRenderTarget> rt = new BasicCompositingRenderTarget(mDrawTarget, rect);
if (aInit == INIT_MODE_CLEAR) {
mDrawTarget->ClearRect(gfx::Rect(aRect));
}
return rt.forget();
}
already_AddRefed<DataTextureSource>
BasicCompositor::CreateDataTextureSource(TextureFlags aFlags)
{
@ -557,13 +583,14 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
*aRenderBoundsOut = Rect();
}
BufferMode bufferMode = BufferMode::BUFFERED;
if (mTarget) {
// If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Use a dummy
// placeholder so that CreateRenderTarget() works.
mDrawTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
} else {
// StartRemoteDrawingInRegion can mutate mInvalidRegion.
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion);
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion, &bufferMode);
if (!mDrawTarget) {
return;
}
@ -581,7 +608,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
// Setup an intermediate render target to buffer all compositing. We will
// copy this into mDrawTarget (the widget), and/or mTarget in EndFrame()
RefPtr<CompositingRenderTarget> target =
CreateRenderTarget(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR);
CreateRenderTargetForWindow(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR, bufferMode);
if (!target) {
if (!mTarget) {
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
@ -592,8 +619,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
// We only allocate a surface sized to the invalidated region, so we need to
// translate future coordinates.
mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mInvalidRect.x,
-mInvalidRect.y));
mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mRenderTarget->GetOrigin()));
gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget,
mInvalidRegion.ToUnknownRegion());
@ -631,22 +657,25 @@ BasicCompositor::EndFrame()
// Pop aInvalidregion
mRenderTarget->mDrawTarget->PopClip();
// Note: Most platforms require us to buffer drawing to the widget surface.
// That's why we don't draw to mDrawTarget directly.
RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget);
if (mTarget || mRenderTarget->mDrawTarget != mDrawTarget) {
// Note: Most platforms require us to buffer drawing to the widget surface.
// That's why we don't draw to mDrawTarget directly.
RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget);
nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint();
nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint();
// The source DrawTarget is clipped to the invalidation region, so we have
// to copy the individual rectangles in the region or else we'll draw blank
// pixels.
for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
const LayoutDeviceIntRect& r = iter.Get();
dest->CopySurface(source,
IntRect(r.x - mInvalidRect.x, r.y - mInvalidRect.y, r.width, r.height),
IntPoint(r.x - offset.x, r.y - offset.y));
// The source DrawTarget is clipped to the invalidation region, so we have
// to copy the individual rectangles in the region or else we'll draw blank
// pixels.
for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
const LayoutDeviceIntRect& r = iter.Get();
dest->CopySurface(source,
IntRect(r.x, r.y, r.width, r.height) - mRenderTarget->GetOrigin(),
IntPoint(r.x, r.y) - offset);
}
}
if (!mTarget) {
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
}

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

@ -62,6 +62,11 @@ public:
const CompositingRenderTarget *aSource,
const gfx::IntPoint &aSourcePoint) override;
virtual already_AddRefed<CompositingRenderTarget>
CreateRenderTargetForWindow(const gfx::IntRect& aRect,
SurfaceInitMode aInit,
BufferMode aBufferMode);
virtual already_AddRefed<DataTextureSource>
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;

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

@ -25,6 +25,7 @@
#include "nsDebug.h" // for printf_stderr, NS_ASSERTION
#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
#include "TextureClientSharedSurface.h"
#include "VRManagerChild.h"
using namespace mozilla::gfx;
using namespace mozilla::gl;
@ -125,6 +126,7 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
t->mTextureClient = mBuffer;
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mBuffer->GetSize());
t->mFrameID = mFrameID;
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
GetForwarder()->UseTextures(this, textures);
mBuffer->SyncWithObject(GetForwarder()->GetSyncObject());
}
@ -481,6 +483,11 @@ CanvasClientSharedSurface::Updated()
t->mTextureClient = mFront;
t->mPictureRect = nsIntRect(nsIntPoint(0, 0), mFront->GetSize());
t->mFrameID = mFrameID;
// XXX TODO - This reference to VRManagerChild will be moved with the
// implementation of the WebVR 1.0 API, which will enable
// the inputFrameID to be passed through Javascript with
// the new VRDisplay API.
t->mInputFrameID = VRManagerChild::Get()->GetInputFrameID();
forwarder->UseTextures(this, textures);
}

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

@ -194,6 +194,7 @@ public:
gfx::IntRect mPictureRect;
int32_t mFrameID;
int32_t mProducerID;
int32_t mInputFrameID;
};
virtual void UseTextureHost(const nsTArray<TimedTexture>& aTextures);
virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
@ -235,6 +236,8 @@ public:
return nullptr;
}
virtual int32_t GetLastInputFrameID() const { return -1; }
protected:
TextureInfo mTextureInfo;
uint64_t mAsyncID;

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

@ -139,8 +139,11 @@ template<class ContainerT> void
ContainerRenderVR(ContainerT* aContainer,
LayerManagerComposite* aManager,
const gfx::IntRect& aClipRect,
RefPtr<gfx::VRHMDInfo> aHMD)
RefPtr<gfx::VRHMDInfo> aHMD,
int32_t aInputFrameID)
{
int32_t inputFrameID = -1;
RefPtr<CompositingRenderTarget> surface;
Compositor* compositor = aManager->GetCompositor();
@ -265,6 +268,14 @@ ContainerRenderVR(ContainerT* aContainer,
surfaceRect.width, surfaceRect.height));
layerToRender->RenderLayer(surfaceRect);
CompositableHost *ch = layerToRender->GetCompositableHost();
if (ch) {
int32_t compositableInputFrameID = ch->GetLastInputFrameID();
if (compositableInputFrameID != -1) {
inputFrameID = compositableInputFrameID;
}
}
if (restoreTransform) {
layer->ReplaceEffectiveTransform(childTransform);
}
@ -282,7 +293,7 @@ ContainerRenderVR(ContainerT* aContainer,
compositor->SetRenderTarget(previousTarget);
if (vrRendering) {
vrRendering->SubmitFrame(aContainer->mVRRenderTargetSet);
vrRendering->SubmitFrame(aContainer->mVRRenderTargetSet, inputFrameID);
DUMP("<<< ContainerRenderVR [used vrRendering] [%p]\n", aContainer);
if (!gfxPrefs::VRMirrorTextures()) {
return;
@ -696,7 +707,7 @@ ContainerRender(ContainerT* aContainer,
RefPtr<gfx::VRHMDInfo> hmdInfo = gfx::VRManager::Get()->GetDevice(aContainer->GetVRDeviceID());
if (hmdInfo && hmdInfo->GetConfiguration().IsValid()) {
ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo);
ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo, aContainer->GetInputFrameID());
aContainer->mPrepared = nullptr;
return;
}

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

@ -32,6 +32,7 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo)
, mImageContainer(nullptr)
, mLastFrameID(-1)
, mLastProducerID(-1)
, mLastInputFrameID(-1)
, mBias(BIAS_NONE)
, mLocked(false)
{}
@ -84,6 +85,7 @@ ImageHost::UseTextureHost(const nsTArray<TimedTexture>& aTextures)
img.mPictureRect = t.mPictureRect;
img.mFrameID = t.mFrameID;
img.mProducerID = t.mProducerID;
img.mInputFrameID = t.mInputFrameID;
}
// Recycle any leftover mTextureSources and call PrepareTextureSource on all
// images.
@ -357,6 +359,7 @@ ImageHost::Composite(LayerComposite* aLayer,
}
mLastFrameID = img->mFrameID;
mLastProducerID = img->mProducerID;
mLastInputFrameID = img->mInputFrameID;
}
aEffectChain.mPrimaryEffect = effect;
gfx::Rect pictureRect(0, 0, img->mPictureRect.width, img->mPictureRect.height);

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

@ -100,6 +100,7 @@ public:
int32_t GetLastFrameID() const { return mLastFrameID; }
int32_t GetLastProducerID() const { return mLastProducerID; }
virtual int32_t GetLastInputFrameID() const override { return mLastInputFrameID; }
enum Bias {
// Don't apply bias to frame times
@ -118,6 +119,7 @@ protected:
gfx::IntRect mPictureRect;
int32_t mFrameID;
int32_t mProducerID;
int32_t mInputFrameID;
};
/**
@ -135,6 +137,7 @@ protected:
ImageContainerParent* mImageContainer;
int32_t mLastFrameID;
int32_t mLastProducerID;
int32_t mLastInputFrameID;
/**
* Bias to apply to the next frame.
*/

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