merge mozilla-inbound to mozilla-central a=merge

--HG--
extra : amend_source : bc1a2d4e4f8ba9197da4e0e72ab01990885ce2b4
This commit is contained in:
Carsten "Tomcat" Book 2014-11-17 14:06:00 +01:00
Родитель 04f5663d05 85cf17a011
Коммит 5a3c5be60a
115 изменённых файлов: 1585 добавлений и 1022 удалений

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

@ -20,14 +20,6 @@ INSTALL_TARGETS += UA_UPDATE
# Make sure the standalone glue doesn't try to get libxpcom.so from b2g/app.
NSDISTMODE = copy
# Copy the Firefox OS fonts if available
ifdef MOZTTDIR
include $(MOZTTDIR)/fonts.mk
MOZTT_DEST = $(FINAL_TARGET)/fonts
MOZTT_FILES = $(patsubst external/moztt/%,$(MOZTTDIR)/%,$(filter external/moztt/%,$(subst :, ,$(PRODUCT_COPY_FILES))))
INSTALL_TARGETS += MOZTT
endif
include $(topsrcdir)/config/rules.mk
APP_ICON = b2g

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

@ -73,6 +73,14 @@ CLANG_RT_ASAN_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += CLANG_RT_ASAN
endif
ifdef MOZTTDIR
# Install the Firefox OS fonts.
include $(MOZTTDIR)/fonts.mk
MOZTT_DEST = $(FINAL_TARGET)/fonts
MOZTT_FILES = $(patsubst external/moztt/%,$(MOZTTDIR)/%,$(filter external/moztt/%,$(subst :, ,$(PRODUCT_COPY_FILES))))
INSTALL_TARGETS += MOZTT
endif
include $(topsrcdir)/config/rules.mk
TARGET_DEPTH = ..

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

@ -6,6 +6,10 @@
#include "AnimationPlayer.h"
#include "AnimationUtils.h"
#include "mozilla/dom/AnimationPlayerBinding.h"
#include "AnimationCommon.h" // For AnimationPlayerCollection,
// CommonAnimationManager
#include "nsIDocument.h" // For nsIDocument
#include "nsIPresShell.h" // For nsIPresShell
#include "nsLayoutUtils.h" // For PostRestyleEvent (remove after bug 1073336)
namespace mozilla {
@ -63,50 +67,17 @@ AnimationPlayer::PlayState() const
}
void
AnimationPlayer::Play(UpdateFlags aFlags)
AnimationPlayer::Play()
{
// FIXME: When we implement finishing behavior (bug 1074630) we should
// not return early if mIsPaused is false since we may still need to seek.
// (However, we will need to pass a flag so that when we start playing due to
// a change in animation-play-state we *don't* trigger finishing behavior.)
if (!mIsPaused) {
return;
}
mIsPaused = false;
Nullable<TimeDuration> timelineTime = mTimeline->GetCurrentTime();
if (timelineTime.IsNull()) {
// FIXME: We should just sit in the pending state in this case.
// We will introduce the pending state in Bug 927349.
return;
}
// Update start time to an appropriate offset from the current timeline time
MOZ_ASSERT(!mHoldTime.IsNull(), "Hold time should not be null when paused");
mStartTime.SetValue(timelineTime.Value() - mHoldTime.Value());
mHoldTime.SetNull();
if (aFlags == eUpdateStyle) {
MaybePostRestyle();
}
DoPlay();
PostUpdate();
}
void
AnimationPlayer::Pause(UpdateFlags aFlags)
AnimationPlayer::Pause()
{
if (mIsPaused) {
return;
}
mIsPaused = true;
mIsRunningOnCompositor = false;
// Bug 927349 - check for null result here and go to pending state
mHoldTime = GetCurrentTime();
mStartTime.SetNull();
if (aFlags == eUpdateStyle) {
MaybePostRestyle();
}
DoPause();
PostUpdate();
}
Nullable<double>
@ -115,40 +86,6 @@ AnimationPlayer::GetCurrentTimeAsDouble() const
return AnimationUtils::TimeDurationToDouble(GetCurrentTime());
}
AnimationPlayState
AnimationPlayer::PlayStateFromJS() const
{
// FIXME: Once we introduce CSSTransitionPlayer, this should move to an
// override of PlayStateFromJS in CSSAnimationPlayer and CSSTransitionPlayer
// and we should skip it in the general case.
FlushStyle();
return PlayState();
}
void
AnimationPlayer::PlayFromJS()
{
// Flush style to ensure that any properties controlling animation state
// (e.g. animation-play-state) are fully updated before we proceed.
//
// Note that this might trigger PlayFromStyle()/PauseFromStyle() on this
// object.
//
// FIXME: Once we introduce CSSTransitionPlayer, this should move to an
// override of PlayFromJS in CSSAnimationPlayer and CSSTransitionPlayer and
// we should skip it in the general case.
FlushStyle();
Play(eUpdateStyle);
}
void
AnimationPlayer::PauseFromJS()
{
Pause(eUpdateStyle);
}
void
AnimationPlayer::SetSource(Animation* aSource)
{
@ -224,45 +161,61 @@ AnimationPlayer::ComposeStyle(nsRefPtr<css::AnimValuesStyleRule>& aStyleRule,
mIsPreviousStateFinished = (playState == AnimationPlayState::Finished);
}
void
AnimationPlayer::DoPlay()
{
// FIXME: When we implement finishing behavior (bug 1074630) we should
// not return early if mIsPaused is false since we may still need to seek.
// (However, we will need to pass a flag so that when we start playing due to
// a change in animation-play-state we *don't* trigger finishing behavior.)
if (!mIsPaused) {
return;
}
mIsPaused = false;
Nullable<TimeDuration> timelineTime = mTimeline->GetCurrentTime();
if (timelineTime.IsNull()) {
// FIXME: We should just sit in the pending state in this case.
// We will introduce the pending state in Bug 927349.
return;
}
// Update start time to an appropriate offset from the current timeline time
MOZ_ASSERT(!mHoldTime.IsNull(), "Hold time should not be null when paused");
mStartTime.SetValue(timelineTime.Value() - mHoldTime.Value());
mHoldTime.SetNull();
}
void
AnimationPlayer::DoPause()
{
if (mIsPaused) {
return;
}
mIsPaused = true;
mIsRunningOnCompositor = false;
// Bug 927349 - check for null result here and go to pending state
mHoldTime = GetCurrentTime();
mStartTime.SetNull();
}
void
AnimationPlayer::FlushStyle() const
{
if (!mSource) {
return;
}
Element* targetElement;
nsCSSPseudoElements::Type pseudoType;
mSource->GetTarget(targetElement, pseudoType);
if (!targetElement) {
return;
}
nsIDocument* doc = targetElement->GetComposedDoc();
nsIDocument* doc = GetRenderedDocument();
if (doc) {
doc->FlushPendingNotifications(Flush_Style);
}
}
void
AnimationPlayer::MaybePostRestyle() const
AnimationPlayer::PostUpdate()
{
if (!mSource) {
return;
AnimationPlayerCollection* collection = GetCollection();
if (collection) {
collection->NotifyPlayerUpdated();
}
Element* targetElement;
nsCSSPseudoElements::Type pseudoType;
mSource->GetTarget(targetElement, pseudoType);
if (!targetElement) {
return;
}
// FIXME: This is a bit heavy-handed but in bug 1073336 we hope to
// introduce a better means for players to update style.
nsLayoutUtils::PostRestyleEvent(targetElement,
eRestyle_Self,
nsChangeHint_AllReflowHints);
}
StickyTimeDuration
@ -276,5 +229,54 @@ AnimationPlayer::SourceContentEnd() const
+ mSource->GetComputedTiming().mActiveDuration;
}
nsIDocument*
AnimationPlayer::GetRenderedDocument() const
{
if (!mSource) {
return nullptr;
}
Element* targetElement;
nsCSSPseudoElements::Type pseudoType;
mSource->GetTarget(targetElement, pseudoType);
if (!targetElement) {
return nullptr;
}
return targetElement->GetComposedDoc();
}
nsPresContext*
AnimationPlayer::GetPresContext() const
{
nsIDocument* doc = GetRenderedDocument();
if (!doc) {
return nullptr;
}
nsIPresShell* shell = doc->GetShell();
if (!shell) {
return nullptr;
}
return shell->GetPresContext();
}
AnimationPlayerCollection*
AnimationPlayer::GetCollection() const
{
css::CommonAnimationManager* manager = GetAnimationManager();
if (!manager) {
return nullptr;
}
MOZ_ASSERT(mSource, "A player with an animation manager must have a source");
Element* targetElement;
nsCSSPseudoElements::Type targetPseudoType;
mSource->GetTarget(targetElement, targetPseudoType);
MOZ_ASSERT(targetElement,
"A player with an animation manager must have a target");
return manager->GetAnimationPlayers(targetElement, targetPseudoType, false);
}
} // namespace dom
} // namespace mozilla

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

@ -22,13 +22,18 @@
struct JSContext;
class nsCSSPropertySet;
class nsIDocument;
class nsPresContext;
namespace mozilla {
struct AnimationPlayerCollection;
namespace css {
class AnimValuesStyleRule;
class CommonAnimationManager;
} // namespace css
class CSSAnimationPlayer;
class CSSTransitionPlayer;
namespace dom {
@ -53,13 +58,7 @@ public:
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual CSSAnimationPlayer* AsCSSAnimationPlayer() { return nullptr; }
// Temporary flags to control restyle behavior until bug 1073336
// provides a better solution.
enum UpdateFlags {
eNoUpdate,
eUpdateStyle
};
virtual CSSTransitionPlayer* AsCSSTransitionPlayer() { return nullptr; }
// AnimationPlayer methods
Animation* GetSource() const { return mSource; }
@ -67,18 +66,21 @@ public:
Nullable<double> GetStartTime() const;
Nullable<TimeDuration> GetCurrentTime() const;
AnimationPlayState PlayState() const;
virtual void Play(UpdateFlags aUpdateFlags);
virtual void Pause(UpdateFlags aUpdateFlags);
virtual void Play();
virtual void Pause();
bool IsRunningOnCompositor() const { return mIsRunningOnCompositor; }
// Wrapper functions for AnimationPlayer DOM methods when called
// from script. We often use the same methods internally and from
// script but when called from script we perform extra steps such
// as flushing style or converting the return type.
// script but when called from script we (or one of our subclasses) perform
// extra steps such as flushing style or converting the return type.
Nullable<double> GetCurrentTimeAsDouble() const;
AnimationPlayState PlayStateFromJS() const;
void PlayFromJS();
void PauseFromJS();
virtual AnimationPlayState PlayStateFromJS() const { return PlayState(); }
virtual void PlayFromJS() { Play(); }
// PauseFromJS is currently only here for symmetry with PlayFromJS but
// in future we will likely have to flush style in
// CSSAnimationPlayer::PauseFromJS so we leave it for now.
void PauseFromJS() { Pause(); }
void SetSource(Animation* aSource);
void Tick();
@ -120,10 +122,18 @@ public:
Nullable<TimeDuration> mStartTime; // Timeline timescale
protected:
void DoPlay();
void DoPause();
void FlushStyle() const;
void MaybePostRestyle() const;
void PostUpdate();
StickyTimeDuration SourceContentEnd() const;
nsIDocument* GetRenderedDocument() const;
nsPresContext* GetPresContext() const;
virtual css::CommonAnimationManager* GetAnimationManager() const = 0;
AnimationPlayerCollection* GetCollection() const;
nsRefPtr<AnimationTimeline> mTimeline;
nsRefPtr<Animation> mSource;
Nullable<TimeDuration> mHoldTime; // Player timescale

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

@ -42,17 +42,4 @@ test(function() {
div.remove();
}, 'Animation name with hex-escape');
test(function() {
var div = addDiv();
// Add a transition
div.style.left = '0px';
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'all 100s';
div.style.left = '100px';
assert_equals(div.getAnimationPlayers()[0].source.effect.name, '',
'Animation effects for transitions have an empty name');
div.remove();
}, 'Effect name for transitions');
</script>

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

@ -206,48 +206,4 @@ async_test(function(t) {
}, 'pause() applies pending changes to animation-play-state first');
// (Note that we can't actually test for this; see comment above, in test-body.)
/* Disabled until bug 1073336 lands */
if (false) {
async_test(function(t) {
var div = addDiv();
var cs = window.getComputedStyle(div);
div.style.marginLeft = '0px';
cs.marginLeft; // Flush style to set up transition start point
div.style.transition = 'margin-left 100s';
div.style.marginLeft = '10000px';
cs.marginLeft;
var player = div.getAnimationPlayers()[0];
assert_equals(getMarginLeft(cs), 0,
'Initial value of margin-left is zero');
var previousAnimVal = getMarginLeft(cs);
waitForFrame().then(function() {
t.step(function() {
assert_true(getMarginLeft(cs) > previousAnimVal,
'margin-left is initially increasing');
previousAnimVal = getMarginLeft(cs);
player.pause();
});
return waitForFrame();
}).then(function() {
t.step(function() {
assert_equals(getMarginLeft(cs), previousAnimVal,
'margin-left does not increase after calling pause()');
previousAnimVal = getMarginLeft(cs);
player.play();
});
return waitForFrame();
}).then(function() {
t.step(function() {
assert_true(getMarginLeft(cs) > previousAnimVal,
'margin-left increases after calling play()');
});
div.remove();
t.done();
});
}, 'pause() and play() a transition');
}
</script>

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

@ -0,0 +1,27 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<style>
@keyframes anim { }
</style>
<script>
'use strict';
function addDiv() {
var div = document.createElement('div');
document.body.appendChild(div);
return div;
}
test(function() {
var div = addDiv();
div.style.animation = 'anim 100s';
var players = div.getAnimationPlayers();
assert_equals(players[0].source.target, div,
'Animation.target is the animatable div');
div.remove();
}, 'Returned CSS animations have the correct Animation.target');
</script>

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

@ -73,41 +73,6 @@ test(function() {
div.remove();
}, 'getAnimationPlayers for multi-property animations');
async_test(function(t) {
var div = addDiv();
// Add a couple of transitions
div.style.left = '0px';
div.style.top = '0px';
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'all 100s';
div.style.left = '100px';
div.style.top = '100px';
var players = div.getAnimationPlayers();
assert_equals(players.length, 2,
'getAnimationPlayers() returns one player per transitioning property');
var startTime = players[0].startTime;
assert_true(startTime > 0 && startTime <= document.timeline.currentTime,
'CSS transitions have sensible start times');
assert_equals(players[0].startTime, players[1].startTime,
'CSS transitions started together have the same start time');
// Wait a moment then add a third transition
window.requestAnimationFrame(t.step_func(function() {
div.style.backgroundColor = 'green';
players = div.getAnimationPlayers();
assert_equals(players.length, 3,
'getAnimationPlayers returns players for all running CSS Transitions');
assert_true(players[1].startTime < players[2].startTime,
'Player for additional CSS transition starts after the original'
+ ' transitions and appears later in the list');
div.remove();
t.done();
}));
}, 'getAnimationPlayers for CSS Transitions');
async_test(function(t) {
var div = addDiv();
@ -166,26 +131,6 @@ async_test(function(t) {
}, 'getAnimationPlayers for CSS Animations that have finished but are'
+ ' forwards filling');
async_test(function(t) {
var div = addDiv();
// Set up event listener
div.addEventListener('transitionend', t.step_func(function() {
assert_equals(div.getAnimationPlayers().length, 0,
'getAnimationPlayers does not return finished CSS Transitions');
div.remove();
t.done();
}));
// Add a very short transition
div.style.left = '0px';
window.getComputedStyle(div).left;
div.style.transition = 'all 0.01s';
div.style.left = '100px';
window.getComputedStyle(div).left;
}, 'getAnimationPlayers for CSS Transitions that have finished');
test(function() {
var div = addDiv();
div.style.animation = 'none 100s';
@ -285,36 +230,6 @@ test(function() {
div.remove();
}, 'getAnimationPlayers for zero-duration CSS Animations');
test(function() {
var div = addDiv();
// Try to transition non-animatable property animation-duration
div.style.animationDuration = '10s';
window.getComputedStyle(div).animationDuration;
div.style.transition = 'all 100s';
div.style.animationDuration = '100s';
assert_equals(div.getAnimationPlayers().length, 0,
'getAnimationPlayers returns an empty sequence for a transition'
+ ' of a non-animatable property');
div.remove();
}, 'getAnimationPlayers for transition on non-animatable property');
test(function() {
var div = addDiv();
div.style.setProperty('-vendor-unsupported', '0px', '');
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'all 100s';
div.style.setProperty('-vendor-unsupported', '100px', '');
assert_equals(div.getAnimationPlayers().length, 0,
'getAnimationPlayers returns an empty sequence for a transition'
+ ' of an unsupported property');
div.remove();
}, 'getAnimationPlayers for transition on unsupported property');
test(function() {
var div = addDiv();
div.style.animation = 'anim1 100s';

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

@ -0,0 +1,24 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
test(function() {
var div = document.createElement('div');
document.body.appendChild(div);
// Add a transition
div.style.left = '0px';
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'all 100s';
div.style.left = '100px';
assert_equals(div.getAnimationPlayers()[0].source.effect.name, '',
'Animation effects for transitions have an empty name');
div.remove();
}, 'Effect name for transitions');
</script>

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

@ -0,0 +1,66 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
function addDiv() {
var div = document.createElement('div');
document.body.appendChild(div);
return div;
}
function waitForFrame() {
return new Promise(function(resolve, reject) {
window.requestAnimationFrame(resolve);
});
}
function getMarginLeft(cs) {
return parseFloat(cs.marginLeft);
}
async_test(function(t) {
var div = addDiv();
var cs = window.getComputedStyle(div);
div.style.marginLeft = '0px';
cs.marginLeft; // Flush style to set up transition start point
div.style.transition = 'margin-left 100s';
div.style.marginLeft = '10000px';
cs.marginLeft;
var player = div.getAnimationPlayers()[0];
assert_equals(getMarginLeft(cs), 0,
'Initial value of margin-left is zero');
var previousAnimVal = getMarginLeft(cs);
waitForFrame().then(function() {
t.step(function() {
assert_true(getMarginLeft(cs) > previousAnimVal,
'margin-left is initially increasing');
previousAnimVal = getMarginLeft(cs);
player.pause();
});
return waitForFrame();
}).then(function() {
t.step(function() {
assert_equals(getMarginLeft(cs), previousAnimVal,
'margin-left does not increase after calling pause()');
previousAnimVal = getMarginLeft(cs);
player.play();
});
return waitForFrame();
}).then(function() {
t.step(function() {
assert_true(getMarginLeft(cs) > previousAnimVal,
'margin-left increases after calling play()');
});
div.remove();
t.done();
});
}, 'pause() and play() a transition');
</script>

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

@ -3,29 +3,12 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<style>
@keyframes anim { }
</style>
<script>
'use strict';
function addDiv() {
test(function() {
var div = document.createElement('div');
document.body.appendChild(div);
return div;
}
test(function() {
var div = addDiv();
div.style.animation = 'anim 100s';
var players = div.getAnimationPlayers();
assert_equals(players[0].source.target, div,
'Animation.target is the animatable div');
div.remove();
}, 'Returned CSS animations have the correct Animation.target');
test(function() {
var div = addDiv();
div.style.left = '0px';
window.getComputedStyle(div).transitionProperty;

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

@ -0,0 +1,100 @@
<!doctype html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
'use strict';
function addDiv() {
var div = document.createElement('div');
document.body.appendChild(div);
return div;
}
async_test(function(t) {
var div = addDiv();
// Add a couple of transitions
div.style.left = '0px';
div.style.top = '0px';
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'all 100s';
div.style.left = '100px';
div.style.top = '100px';
var players = div.getAnimationPlayers();
assert_equals(players.length, 2,
'getAnimationPlayers() returns one player per transitioning property');
var startTime = players[0].startTime;
assert_true(startTime > 0 && startTime <= document.timeline.currentTime,
'CSS transitions have sensible start times');
assert_equals(players[0].startTime, players[1].startTime,
'CSS transitions started together have the same start time');
// Wait a moment then add a third transition
window.requestAnimationFrame(t.step_func(function() {
div.style.backgroundColor = 'green';
players = div.getAnimationPlayers();
assert_equals(players.length, 3,
'getAnimationPlayers returns players for all running CSS Transitions');
assert_true(players[1].startTime < players[2].startTime,
'Player for additional CSS transition starts after the original'
+ ' transitions and appears later in the list');
div.remove();
t.done();
}));
}, 'getAnimationPlayers for CSS Transitions');
async_test(function(t) {
var div = addDiv();
// Set up event listener
div.addEventListener('transitionend', t.step_func(function() {
assert_equals(div.getAnimationPlayers().length, 0,
'getAnimationPlayers does not return finished CSS Transitions');
div.remove();
t.done();
}));
// Add a very short transition
div.style.left = '0px';
window.getComputedStyle(div).left;
div.style.transition = 'all 0.01s';
div.style.left = '100px';
window.getComputedStyle(div).left;
}, 'getAnimationPlayers for CSS Transitions that have finished');
test(function() {
var div = addDiv();
// Try to transition non-animatable property animation-duration
div.style.animationDuration = '10s';
window.getComputedStyle(div).animationDuration;
div.style.transition = 'all 100s';
div.style.animationDuration = '100s';
assert_equals(div.getAnimationPlayers().length, 0,
'getAnimationPlayers returns an empty sequence for a transition'
+ ' of a non-animatable property');
div.remove();
}, 'getAnimationPlayers for transition on non-animatable property');
test(function() {
var div = addDiv();
div.style.setProperty('-vendor-unsupported', '0px', '');
window.getComputedStyle(div).transitionProperty;
div.style.transition = 'all 100s';
div.style.setProperty('-vendor-unsupported', '100px', '');
assert_equals(div.getAnimationPlayers().length, 0,
'getAnimationPlayers returns an empty sequence for a transition'
+ ' of an unsupported property');
div.remove();
}, 'getAnimationPlayers for transition on unsupported property');
</script>

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

@ -1,9 +1,14 @@
[animation-timeline/test_animation-timeline.html]
skip-if = buildapp == 'mulet'
[css-integration/test_element-get-animation-players.html]
[css-animations/test_animations-dynamic-changes.html]
[css-animations/test_animation-effect-name.html]
[css-animations/test_animation-pausing.html]
[css-animations/test_animation-player-playstate.html]
[css-animations/test_animation-target.html]
[css-animations/test_element-get-animation-players.html]
skip-if = buildapp == 'mulet'
[css-transitions/test_animation-effect-name.html]
[css-transitions/test_animation-pausing.html]
[css-transitions/test_animation-target.html]
[css-transitions/test_element-get-animation-players.html]
skip-if = buildapp == 'mulet'
[css-integration/test_animations-dynamic-changes.html]
[css-integration/test_animation-effect-name.html]
[css-integration/test_animation-pausing.html]
[css-integration/test_animation-player-playstate.html]
[css-integration/test_animation-target.html]

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

@ -3012,26 +3012,26 @@ class CGConstructorEnabled(CGAbstractMethod):
if not iface.isExposedInWindow():
exposedInWindowCheck = dedent(
"""
if (NS_IsMainThread()) {
return false;
}
MOZ_ASSERT(!NS_IsMainThread(), "Why did we even get called?");
""")
body.append(CGGeneric(exposedInWindowCheck))
if iface.isExposedInAnyWorker() and iface.isExposedOnlyInSomeWorkers():
if iface.isExposedInSomeButNotAllWorkers():
workerGlobals = sorted(iface.getWorkerExposureSet())
workerCondition = CGList((CGGeneric('strcmp(name, "%s")' % workerGlobal)
for workerGlobal in workerGlobals), " && ")
exposedInWorkerCheck = fill(
"""
if (!NS_IsMainThread()) {
const char* name = js::GetObjectClass(aObj)->name;
if (${workerCondition}) {
return false;
}
const char* name = js::GetObjectClass(aObj)->name;
if (${workerCondition}) {
return false;
}
""", workerCondition=workerCondition.define())
body.append(CGGeneric(exposedInWorkerCheck))
exposedInWorkerCheck = CGGeneric(exposedInWorkerCheck)
if iface.isExposedInWindow():
exposedInWorkerCheck = CGIfWrapper(exposedInWorkerCheck,
"!NS_IsMainThread()")
body.append(exposedInWorkerCheck)
pref = iface.getExtendedAttribute("Pref")
if pref:
@ -11958,6 +11958,7 @@ class CGRegisterProtos(CGAbstractMethod):
for desc in self.config.getDescriptors(hasInterfaceObject=True,
isExternal=False,
workers=False,
isExposedInWindow=True,
register=True):
lines.append("REGISTER_PROTO(%s, %s);\n" % (desc.name, getCheck(desc)))
lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);\n" % (n.identifier.name, desc.name, getCheck(desc))
@ -12226,10 +12227,6 @@ class CGBindingRoot(CGThing):
workers=True)) != 0
bindingHeaders["WorkerPrivate.h"] = hasWorkerStuff
def descriptorHasThreadChecks(desc):
return ((not desc.workers and not desc.interface.isExposedInWindow()) or
(desc.interface.isExposedInAnyWorker() and desc.interface.isExposedOnlyInSomeWorkers()))
hasThreadChecks = hasWorkerStuff or any(d.hasThreadChecks() for d in descriptors)
bindingHeaders["nsThreadUtils.h"] = hasThreadChecks
@ -14400,6 +14397,7 @@ class GlobalGenRoots():
defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(hasInterfaceObject=True,
workers=False,
isExposedInWindow=True,
register=True)]
defineIncludes.append('nsScriptNameSpaceManager.h')
defineIncludes.extend([CGHeaders.getDeclarationFilename(desc.interface)

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

@ -210,6 +210,9 @@ class Configuration:
elif key == 'isExposedInSystemGlobals':
getter = lambda x: (not x.interface.isExternal() and
x.interface.isExposedInSystemGlobals())
elif key == 'isExposedInWindow':
getter = lambda x: (not x.interface.isExternal() and
x.interface.isExposedInWindow())
else:
# Have to watch out: just closing over "key" is not enough,
# since we're about to mutate its value
@ -654,12 +657,13 @@ class Descriptor(DescriptorProvider):
in self.interface.members))
def hasThreadChecks(self):
return ((not self.workers and not self.interface.isExposedInWindow()) or
(self.interface.isExposedInAnyWorker() and
self.interface.isExposedOnlyInSomeWorkers()))
return ((self.isExposedConditionally() and
not self.interface.isExposedInWindow()) or
self.interface.isExposedInSomeButNotAllWorkers())
def isExposedConditionally(self):
return self.interface.isExposedConditionally() or self.hasThreadChecks()
return (self.interface.isExposedConditionally() or
self.interface.isExposedInSomeButNotAllWorkers())
def needsXrayResolveHooks(self):
"""

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

@ -1072,8 +1072,15 @@ class IDLInterface(IDLObjectWithScope):
def isExposedInSystemGlobals(self):
return 'BackstagePass' in self.exposureSet
def isExposedOnlyInSomeWorkers(self):
assert self.isExposedInAnyWorker()
def isExposedInSomeButNotAllWorkers(self):
"""
Returns true if the Exposed extended attribute for this interface
exposes it in some worker globals but not others. The return value does
not depend on whether the interface is exposed in Window or System
globals.
"""
if not self.isExposedInAnyWorker():
return False
workerScopes = self.parentScope.globalNameMapping["Worker"]
return len(workerScopes.difference(self.exposureSet)) > 0
@ -5695,6 +5702,7 @@ class Parser(Tokenizer):
# Builtin IDL defined by WebIDL
_builtins = """
typedef unsigned long long DOMTimeStamp;
typedef (ArrayBufferView or ArrayBuffer) BufferSource;
"""
def main():

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

@ -14,20 +14,16 @@
namespace mozilla {
/** Represents a GL name that can be bound to a target.
/** Represents a binding to a GL binding point
*/
template<typename T>
class WebGLBindableName
class WebGLBindable
{
public:
WebGLBindable() : mTarget(LOCAL_GL_NONE) { }
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
WebGLBindableName()
: mGLName(0)
, mTarget(LOCAL_GL_NONE)
{ }
void BindTo(T target)
{
void BindTo(T target) {
MOZ_ASSERT(target != LOCAL_GL_NONE, "Can't bind to GL_NONE.");
MOZ_ASSERT(!HasEverBeenBound() || mTarget == target, "Rebinding is illegal.");
@ -37,22 +33,38 @@ public:
OnTargetChanged();
}
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
GLuint GLName() const { return mGLName; }
T Target() const {
MOZ_ASSERT(HasEverBeenBound());
return mTarget;
}
protected:
//! Called after mTarget has been changed by BindTo(target).
virtual void OnTargetChanged() {}
GLuint mGLName;
T mTarget;
};
/** Represents a GL name that can be bound to a target.
*/
template<typename T>
class WebGLBindableName
: public WebGLBindable<T>
{
public:
WebGLBindableName(GLuint name)
: WebGLBindable<T>()
, mGLName(name)
{ }
GLuint GLName() const { return mGLName; }
protected:
const GLuint mGLName;
};
} // namespace mozilla
#endif // !WEBGLBINDABLENAME_H_

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

@ -12,13 +12,11 @@
using namespace mozilla;
WebGLBuffer::WebGLBuffer(WebGLContext *context)
: WebGLBindableName<BufferBinding>()
WebGLBuffer::WebGLBuffer(WebGLContext* context, GLuint buf)
: WebGLBindableName<BufferBinding>(buf)
, WebGLContextBoundObject(context)
, mByteLength(0)
{
mContext->MakeContextCurrent();
mContext->gl->fGenBuffers(1, &mGLName);
mContext->mBuffers.insertBack(this);
}

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

@ -27,7 +27,7 @@ class WebGLBuffer MOZ_FINAL
, public WebGLContextBoundObject
{
public:
explicit WebGLBuffer(WebGLContext* aContext);
explicit WebGLBuffer(WebGLContext* context, GLuint buf);
void Delete();

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

@ -361,7 +361,11 @@ WebGLContext::CreateBuffer()
if (IsContextLost())
return nullptr;
nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this);
GLuint buf = 0;
MakeContextCurrent();
gl->fGenBuffers(1, &buf);
nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this, buf);
return globj.forget();
}

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

@ -1372,7 +1372,12 @@ WebGLContext::CreateTexture()
{
if (IsContextLost())
return nullptr;
nsRefPtr<WebGLTexture> globj = new WebGLTexture(this);
GLuint tex = 0;
MakeContextCurrent();
gl->fGenTextures(1, &tex);
nsRefPtr<WebGLTexture> globj = new WebGLTexture(this, tex);
return globj.forget();
}
@ -3098,7 +3103,12 @@ WebGLContext::CreateFramebuffer()
{
if (IsContextLost())
return nullptr;
nsRefPtr<WebGLFramebuffer> globj = new WebGLFramebuffer(this);
GLuint fbo = 0;
MakeContextCurrent();
gl->fGenFramebuffers(1, &fbo);
nsRefPtr<WebGLFramebuffer> globj = new WebGLFramebuffer(this, fbo);
return globj.forget();
}

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

@ -26,16 +26,14 @@ WebGLFramebuffer::WrapObject(JSContext* cx)
return dom::WebGLFramebufferBinding::Wrap(cx, this);
}
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
: WebGLBindableName<FBTarget>()
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context, GLuint fbo)
: WebGLBindableName<FBTarget>(fbo)
, WebGLContextBoundObject(context)
, mStatus(0)
, mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
, mStencilAttachment(LOCAL_GL_STENCIL_ATTACHMENT)
, mDepthStencilAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
{
mContext->MakeContextCurrent();
mContext->gl->fGenFramebuffers(1, &mGLName);
mContext->mFramebuffers.insertBack(this);
mColorAttachments.SetLength(1);

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

@ -34,7 +34,7 @@ class WebGLFramebuffer MOZ_FINAL
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLFramebuffer)
explicit WebGLFramebuffer(WebGLContext* context);
explicit WebGLFramebuffer(WebGLContext* context, GLuint fbo);
struct Attachment
{

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

@ -42,8 +42,8 @@ WebGLRenderbuffer::WrapObject(JSContext *cx) {
return dom::WebGLRenderbufferBinding::Wrap(cx, this);
}
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext *context)
: WebGLBindableName<RBTarget>()
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* context)
: WebGLBindable<RBTarget>()
, WebGLContextBoundObject(context)
, mPrimaryRB(0)
, mSecondaryRB(0)

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

@ -18,7 +18,7 @@ namespace mozilla {
class WebGLRenderbuffer MOZ_FINAL
: public nsWrapperCache
, public WebGLBindableName<RBTarget>
, public WebGLBindable<RBTarget>
, public WebGLRefCountedObject<WebGLRenderbuffer>
, public LinkedListElement<WebGLRenderbuffer>
, public WebGLRectangleObject

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

@ -13,7 +13,8 @@
using namespace mozilla;
WebGLSampler::WebGLSampler(WebGLContext* context)
: WebGLContextBoundObject(context)
: WebGLBindableName<GLenum>(0),
WebGLContextBoundObject(context)
{
MOZ_CRASH("Not Implemented.");
}

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

@ -16,8 +16,8 @@
namespace mozilla {
class WebGLSampler MOZ_FINAL
: public WebGLBindableName<GLenum>
, public nsWrapperCache
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLSampler>
, public LinkedListElement<WebGLSampler>
, public WebGLContextBoundObject

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

@ -19,12 +19,12 @@
using namespace mozilla;
JSObject*
WebGLTexture::WrapObject(JSContext *cx) {
WebGLTexture::WrapObject(JSContext* cx) {
return dom::WebGLTextureBinding::Wrap(cx, this);
}
WebGLTexture::WebGLTexture(WebGLContext *context)
: WebGLBindableName<TexTarget>()
WebGLTexture::WebGLTexture(WebGLContext* context, GLuint tex)
: WebGLBindableName<TexTarget>(tex)
, WebGLContextBoundObject(context)
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
, mMagFilter(LOCAL_GL_LINEAR)
@ -38,8 +38,6 @@ WebGLTexture::WebGLTexture(WebGLContext *context)
, mMaxMipmapLevel(1000)
, mFakeBlackStatus(WebGLTextureFakeBlackStatus::IncompleteTexture)
{
mContext->MakeContextCurrent();
mContext->gl->fGenTextures(1, &mGLName);
mContext->mTextures.insertBack(this);
}

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

@ -38,7 +38,7 @@ class WebGLTexture MOZ_FINAL
, public WebGLFramebufferAttachable
{
public:
explicit WebGLTexture(WebGLContext* aContext);
explicit WebGLTexture(WebGLContext* aContext, GLuint tex);
void Delete();

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

@ -13,7 +13,8 @@
using namespace mozilla;
WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* context)
: WebGLContextBoundObject(context)
: WebGLBindableName<GLenum>(0)
, WebGLContextBoundObject(context)
{
MOZ_CRASH("Not Implemented.");
}

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

@ -16,8 +16,8 @@
namespace mozilla {
class WebGLTransformFeedback MOZ_FINAL
: public WebGLBindableName<GLenum>
, public nsWrapperCache
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLRefCountedObject<WebGLTransformFeedback>
, public LinkedListElement<WebGLTransformFeedback>
, public WebGLContextBoundObject

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

@ -20,8 +20,9 @@ WebGLVertexArray::WrapObject(JSContext *cx) {
}
WebGLVertexArray::WebGLVertexArray(WebGLContext* context)
: WebGLBindableName<VAOBinding>()
: WebGLBindable<VAOBinding>()
, WebGLContextBoundObject(context)
, mGLName(0)
{
context->mVertexArrays.insertBack(this);
}

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

@ -22,7 +22,7 @@ class WebGLVertexArrayFake;
class WebGLVertexArray
: public nsWrapperCache
, public WebGLBindableName<VAOBinding>
, public WebGLBindable<VAOBinding>
, public WebGLRefCountedObject<WebGLVertexArray>
, public LinkedListElement<WebGLVertexArray>
, public WebGLContextBoundObject
@ -61,6 +61,8 @@ public:
// -------------------------------------------------------------------------
// MEMBER FUNCTIONS
GLuint GLName() const { return mGLName; }
void EnsureAttrib(GLuint index);
bool HasAttrib(GLuint index) {
return index < mAttribs.Length();
@ -82,6 +84,7 @@ protected:
// -------------------------------------------------------------------------
// MEMBERS
GLuint mGLName;
nsTArray<WebGLVertexAttribData> mAttribs;
WebGLRefPtr<WebGLBuffer> mElementArrayBuffer;

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

@ -9,6 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=885996
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style> body { font-family: serif } </style>
<script type="application/javascript;version=1.8">
/** Test the behaviour of the <input type='color'> when clicking on it from

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

@ -9,6 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=885996
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style> body { font-family: serif } </style>
<script type="application/javascript;version=1.8">
/** Test that update() modifies the element value such as done() when it is

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

@ -1024,6 +1024,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
}
nsRefPtr<TabParent> tp(new TabParent(constructorSender, tabId,
aContext, chromeFlags));
tp->SetInitedByParent();
tp->SetOwnerElement(aFrameElement);
PBrowserParent* browser = constructorSender->SendPBrowserConstructor(
@ -1135,6 +1136,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
uint32_t chromeFlags = 0;
nsRefPtr<TabParent> tp = new TabParent(parent, tabId, aContext, chromeFlags);
tp->SetInitedByParent();
tp->SetOwnerElement(aFrameElement);
PBrowserParent* browser = parent->SendPBrowserConstructor(
// DeallocPBrowserParent() releases this ref.
@ -1934,6 +1936,13 @@ ContentParent::ContentParent(mozIApplication* aApp,
// PID along with the warning.
nsDebugImpl::SetMultiprocessMode("Parent");
#if defined(XP_WIN) && !defined(MOZ_B2G)
// Request Windows message deferral behavior on our side of the PContent
// channel. Generally only applies to the situation where we get caught in
// a deadlock with the plugin process when sending CPOWs.
GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
#endif
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
ChildPrivileges privs = aIsNuwaProcess
? base::PRIVILEGES_INHERIT

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

@ -85,6 +85,12 @@ both:
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows,
Principal aPrincipal);
/**
* Create a layout frame (encapsulating a remote layer tree) for
* the page that is currently loaded in the <browser>.
*/
PRenderFrame();
parent:
/*
* Creates a new remoted nsIWidget connection for windowed plugins
@ -317,16 +323,6 @@ parent:
*/
PIndexedDBPermissionRequest(Principal principal);
/**
* Create a layout frame (encapsulating a remote layer tree) for
* the page that is currently loaded in the <browser>.
*/
sync PRenderFrame()
returns (ScrollingBehavior scrolling,
TextureFactoryIdentifier textureFactoryIdentifier, uint64_t layersId,
bool success);
/**
* window.open from inside <iframe mozbrowser> is special. When the child
* process calls window.open, it creates a new PBrowser (in its own
@ -392,6 +388,11 @@ parent:
*/
async RemotePaintIsReady();
sync GetRenderFrameInfo(PRenderFrame aRenderFrame)
returns (ScrollingBehavior scrolling,
TextureFactoryIdentifier textureFactoryIdentifier,
uint64_t layersId);
child:
/**
* Notify the remote browser that it has been Show()n on this
@ -402,7 +403,11 @@ child:
* content processes always render to a virtual <0, 0> top-left
* point.
*/
Show(nsIntSize size);
Show(nsIntSize size,
ScrollingBehavior scrolling,
TextureFactoryIdentifier textureFactoryIdentifier,
uint64_t layersId,
nullable PRenderFrame renderFrame);
LoadURL(nsCString uri);

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

@ -1511,9 +1511,22 @@ TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
return NS_ERROR_ABORT;
}
ScrollingBehavior scrolling = DEFAULT_SCROLLING;
TextureFactoryIdentifier textureFactoryIdentifier;
uint64_t layersId = 0;
PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
newChild->SendGetRenderFrameInfo(renderFrame,
&scrolling,
&textureFactoryIdentifier,
&layersId);
if (layersId == 0) { // if renderFrame is invalid.
PRenderFrameChild::Send__delete__(renderFrame);
renderFrame = nullptr;
}
// Unfortunately we don't get a window unless we've shown the frame. That's
// pretty bogus; see bug 763602.
newChild->DoFakeShow();
newChild->DoFakeShow(scrolling, textureFactoryIdentifier, layersId, renderFrame);
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation());
win.forget(aReturn);
@ -1828,9 +1841,12 @@ TabChild::CancelCachedFileDescriptorCallback(
}
void
TabChild::DoFakeShow()
TabChild::DoFakeShow(const ScrollingBehavior& aScrolling,
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame)
{
RecvShow(nsIntSize(0, 0));
RecvShow(nsIntSize(0, 0), aScrolling, aTextureFactoryIdentifier, aLayersId, aRenderFrame);
mDidFakeShow = true;
}
@ -1893,8 +1909,13 @@ TabChild::MaybeRequestPreinitCamera()
#endif
bool
TabChild::RecvShow(const nsIntSize& size)
TabChild::RecvShow(const nsIntSize& aSize,
const ScrollingBehavior& aScrolling,
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame)
{
MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
if (mDidFakeShow) {
return true;
@ -1906,7 +1927,7 @@ TabChild::RecvShow(const nsIntSize& size)
return false;
}
if (!InitRenderingState()) {
if (!InitRenderingState(aScrolling, aTextureFactoryIdentifier, aLayersId, aRenderFrame)) {
// We can fail to initialize our widget if the <browser
// remote> has already been destroyed, and we couldn't hook
// into the parent-process's layer system. That's not a fatal
@ -2748,10 +2769,7 @@ TabChild::RecvSetIsDocShellActive(const bool& aIsActive)
}
PRenderFrameChild*
TabChild::AllocPRenderFrameChild(ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId,
bool* aSuccess)
TabChild::AllocPRenderFrameChild()
{
return new RenderFrameChild();
}
@ -2804,43 +2822,40 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
}
bool
TabChild::InitRenderingState()
TabChild::InitRenderingState(const ScrollingBehavior& aScrolling,
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame)
{
static_cast<PuppetWidget*>(mWidget.get())->InitIMEState();
uint64_t id;
bool success;
RenderFrameChild* remoteFrame =
static_cast<RenderFrameChild*>(SendPRenderFrameConstructor(
&mScrolling,
&mTextureFactoryIdentifier, &id,
&success));
RenderFrameChild* remoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
if (!remoteFrame) {
NS_WARNING("failed to construct RenderFrame");
return false;
}
if (!success) {
NS_WARNING("failed to construct RenderFrame");
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
}
MOZ_ASSERT(id != 0);
MOZ_ASSERT(aLayersId != 0);
mScrolling = aScrolling;
mTextureFactoryIdentifier = aTextureFactoryIdentifier;
// Pushing layers transactions directly to a separate
// compositor context.
PCompositorChild* compositorChild = CompositorChild::Get();
if (!compositorChild) {
NS_WARNING("failed to get CompositorChild instance");
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
}
nsTArray<LayersBackend> backends;
backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
bool success;
PLayerTransactionChild* shadowManager =
compositorChild->SendPLayerTransactionConstructor(backends,
id, &mTextureFactoryIdentifier, &success);
aLayersId, &mTextureFactoryIdentifier, &success);
if (!success) {
NS_WARNING("failed to properly allocate layer transaction");
PRenderFrameChild::Send__delete__(remoteFrame);
return false;
}
@ -2860,13 +2875,13 @@ TabChild::InitRenderingState()
ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
mRemoteFrame = remoteFrame;
if (id != 0) {
if (aLayersId != 0) {
if (!sTabChildren) {
sTabChildren = new TabChildMap;
}
MOZ_ASSERT(!sTabChildren->Get(id));
sTabChildren->Put(id, this);
mLayersId = id;
MOZ_ASSERT(!sTabChildren->Get(aLayersId));
sTabChildren->Put(aLayersId, this);
mLayersId = aLayersId;
}
nsCOMPtr<nsIObserverService> observerService =

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

@ -316,7 +316,11 @@ public:
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
const FileDescriptor& aFileDescriptor)
MOZ_OVERRIDE;
virtual bool RecvShow(const nsIntSize& size) MOZ_OVERRIDE;
virtual bool RecvShow(const nsIntSize& aSize,
const ScrollingBehavior& aScrolling,
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame) MOZ_OVERRIDE;
virtual bool RecvUpdateDimensions(const nsIntRect& rect,
const nsIntSize& size,
const ScreenOrientation& orientation) MOZ_OVERRIDE;
@ -491,10 +495,7 @@ public:
protected:
virtual ~TabChild();
virtual PRenderFrameChild* AllocPRenderFrameChild(ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId,
bool* aSuccess) MOZ_OVERRIDE;
virtual PRenderFrameChild* AllocPRenderFrameChild() MOZ_OVERRIDE;
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) MOZ_OVERRIDE;
virtual bool RecvDestroy() MOZ_OVERRIDE;
virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) MOZ_OVERRIDE;
@ -536,12 +537,18 @@ private:
enum FrameScriptLoading { DONT_LOAD_SCRIPTS, DEFAULT_LOAD_SCRIPTS };
bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
bool InitRenderingState();
bool InitRenderingState(const ScrollingBehavior& aScrolling,
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame);
void DestroyWindow();
void SetProcessNameToAppName();
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
void DoFakeShow();
void DoFakeShow(const ScrollingBehavior& aScrolling,
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame);
// These methods are used for tracking synthetic mouse events
// dispatched for compatibility. On each touch event, we

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

@ -248,6 +248,7 @@ TabParent::TabParent(nsIContentParent* aManager,
, mAppPackageFileDescriptorSent(false)
, mSendOfflineStatus(true)
, mChromeFlags(aChromeFlags)
, mInitedByParent(false)
, mTabId(aTabId)
{
MOZ_ASSERT(aManager);
@ -573,9 +574,33 @@ TabParent::Show(const nsIntSize& size)
// sigh
mShown = true;
mDimensions = size;
if (!mIsDestroyed) {
unused << SendShow(size);
if (mIsDestroyed) {
return;
}
ScrollingBehavior scrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
TextureFactoryIdentifier textureFactoryIdentifier;
uint64_t layersId = 0;
bool success = false;
RenderFrameParent* renderFrame = nullptr;
// If TabParent is initialized by parent side then the RenderFrame must also
// be created here. If TabParent is initialized by child side,
// child side will create RenderFrame.
MOZ_ASSERT(!GetRenderFrame());
if (IsInitedByParent()) {
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (frameLoader) {
renderFrame =
new RenderFrameParent(frameLoader,
scrolling,
&textureFactoryIdentifier,
&layersId,
&success);
MOZ_ASSERT(success);
unused << SendPRenderFrameConstructor(renderFrame);
}
}
unused << SendShow(size, scrolling, textureFactoryIdentifier, layersId, renderFrame);
}
void
@ -1911,18 +1936,26 @@ TabParent::DeallocPColorPickerParent(PColorPickerParent* actor)
}
PRenderFrameParent*
TabParent::AllocPRenderFrameParent(ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId, bool* aSuccess)
TabParent::AllocPRenderFrameParent()
{
MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
*aScrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
return new RenderFrameParent(frameLoader,
*aScrolling,
aTextureFactoryIdentifier, aLayersId,
aSuccess);
ScrollingBehavior scrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
TextureFactoryIdentifier textureFactoryIdentifier;
uint64_t layersId = 0;
bool success = false;
if(frameLoader) {
PRenderFrameParent* renderFrame =
new RenderFrameParent(frameLoader,
scrolling,
&textureFactoryIdentifier,
&layersId,
&success);
MOZ_ASSERT(success);
return renderFrame;
} else {
return nullptr;
}
}
bool
@ -1932,6 +1965,19 @@ TabParent::DeallocPRenderFrameParent(PRenderFrameParent* aFrame)
return true;
}
bool
TabParent::RecvGetRenderFrameInfo(PRenderFrameParent* aRenderFrame,
ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId)
{
RenderFrameParent* renderFrame = static_cast<RenderFrameParent*>(aRenderFrame);
*aScrolling = renderFrame->UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
renderFrame->GetTextureFactoryIdentifier(aTextureFactoryIdentifier);
*aLayersId = renderFrame->GetLayersId();
return true;
}
bool
TabParent::AllowContentIME()
{
@ -2021,16 +2067,6 @@ TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
return true;
}
bool
TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* aActor,
ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aFactoryIdentifier,
uint64_t* aLayersId,
bool* aSuccess)
{
return true;
}
bool
TabParent::RecvZoomToRect(const uint32_t& aPresShellId,
const ViewID& aViewId,

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

@ -128,11 +128,6 @@ public:
virtual bool RecvEvent(const RemoteDOMEvent& aEvent) MOZ_OVERRIDE;
virtual bool RecvReplyKeyEvent(const WidgetKeyboardEvent& event);
virtual bool RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& event);
virtual bool RecvPRenderFrameConstructor(PRenderFrameParent* aActor,
ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aFactoryIdentifier,
uint64_t* aLayersId,
bool* aSuccess) MOZ_OVERRIDE;
virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
const nsString& aURL,
const nsString& aName,
@ -341,6 +336,9 @@ public:
virtual PPluginWidgetParent* AllocPPluginWidgetParent() MOZ_OVERRIDE;
virtual bool DeallocPPluginWidgetParent(PPluginWidgetParent* aActor) MOZ_OVERRIDE;
void SetInitedByParent() { mInitedByParent = true; }
bool IsInitedByParent() const { return mInitedByParent; }
protected:
bool ReceiveMessage(const nsString& aMessage,
bool aSync,
@ -362,14 +360,16 @@ protected:
bool AllowContentIME();
virtual PRenderFrameParent* AllocPRenderFrameParent(ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId,
bool* aSuccess) MOZ_OVERRIDE;
virtual PRenderFrameParent* AllocPRenderFrameParent() MOZ_OVERRIDE;
virtual bool DeallocPRenderFrameParent(PRenderFrameParent* aFrame) MOZ_OVERRIDE;
virtual bool RecvRemotePaintIsReady() MOZ_OVERRIDE;
virtual bool RecvGetRenderFrameInfo(PRenderFrameParent* aRenderFrame,
ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId) MOZ_OVERRIDE;
bool SendCompositionChangeEvent(mozilla::WidgetCompositionEvent& event);
// IME
@ -445,6 +445,10 @@ private:
uint32_t mChromeFlags;
// When true, the TabParent is initialized without child side's request.
// When false, the TabParent is initialized by window.open() from child side.
bool mInitedByParent;
nsCOMPtr<nsILoadContext> mLoadContext;
TabId mTabId;

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

@ -92,7 +92,6 @@ FFmpegAudioDecoder<LIBAV_VER>::DecodePacket(MP4Sample* aSample)
aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE);
packet.data = aSample->data;
packet.size = aSample->size;
packet.pos = aSample->byte_offset;
if (!PrepareFrame()) {
NS_WARNING("FFmpeg audio decoder failed to allocate frame.");
@ -100,31 +99,50 @@ FFmpegAudioDecoder<LIBAV_VER>::DecodePacket(MP4Sample* aSample)
return;
}
int decoded;
int bytesConsumed =
avcodec_decode_audio4(mCodecContext, mFrame, &decoded, &packet);
int64_t samplePosition = aSample->byte_offset;
Microseconds pts = aSample->composition_timestamp;
if (bytesConsumed < 0 || !decoded) {
NS_WARNING("FFmpeg audio decoder error.");
mCallback->Error();
return;
while (packet.size > 0) {
int decoded;
int bytesConsumed =
avcodec_decode_audio4(mCodecContext, mFrame, &decoded, &packet);
if (bytesConsumed < 0) {
NS_WARNING("FFmpeg audio decoder error.");
mCallback->Error();
return;
}
if (decoded) {
uint32_t numChannels = mCodecContext->channels;
uint32_t samplingRate = mCodecContext->sample_rate;
nsAutoArrayPtr<AudioDataValue> audio(
CopyAndPackAudio(mFrame, numChannels, mFrame->nb_samples));
CheckedInt<Microseconds> duration =
FramesToUsecs(mFrame->nb_samples, samplingRate);
if (!duration.isValid()) {
NS_WARNING("Invalid count of accumulated audio samples");
mCallback->Error();
return;
}
AudioData* data = new AudioData(samplePosition,
pts,
duration.value(),
mFrame->nb_samples,
audio.forget(),
numChannels,
samplingRate);
mCallback->Output(data);
pts += duration.value();
}
packet.data += bytesConsumed;
packet.size -= bytesConsumed;
samplePosition += bytesConsumed;
}
NS_ASSERTION(bytesConsumed == (int)aSample->size,
"Only one audio packet should be received at a time.");
uint32_t numChannels = mCodecContext->channels;
uint32_t samplingRate = mCodecContext->sample_rate;
nsAutoArrayPtr<AudioDataValue> audio(
CopyAndPackAudio(mFrame, numChannels, mFrame->nb_samples));
nsAutoPtr<AudioData> data(
new AudioData(packet.pos, aSample->composition_timestamp, aSample->duration,
mFrame->nb_samples, audio.forget(), numChannels, samplingRate));
mCallback->Output(data.forget());
if (mTaskQueue->IsEmpty()) {
mCallback->InputExhausted();
}
@ -142,8 +160,9 @@ FFmpegAudioDecoder<LIBAV_VER>::Input(MP4Sample* aSample)
nsresult
FFmpegAudioDecoder<LIBAV_VER>::Drain()
{
mTaskQueue->AwaitIdle();
mCallback->DrainComplete();
return NS_OK;
return Flush();
}
AVCodecID

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

@ -329,15 +329,20 @@ GonkVideoDecoderManager::Output(int64_t aStreamOffset,
return NS_OK;
}
case android::INFO_FORMAT_CHANGED:
case android::INFO_OUTPUT_BUFFERS_CHANGED:
{
// If the format changed, update our cached info.
ALOG("Decoder format changed");
if (!SetVideoFormat()) {
return NS_ERROR_UNEXPECTED;
}
else
return Output(aStreamOffset, aOutData);
}
case android::INFO_OUTPUT_BUFFERS_CHANGED:
{
if (mDecoder->UpdateOutputBuffers()) {
return Output(aStreamOffset, aOutData);
}
return NS_ERROR_FAILURE;
}
case -EAGAIN:
{
@ -420,7 +425,6 @@ GonkVideoDecoderManager::codecReserved()
}
status_t err = mDecoder->configure(format, surface, nullptr, 0);
mDecoder->Prepare();
SetVideoFormat();
if (mHandler != nullptr) {
// post kNotifyCodecReserved to Looper thread.

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

@ -22,3 +22,5 @@ USE_STATIC_LIBS = True
NO_VISIBILITY_FLAGS = True
# Don't use STL wrappers; this isn't Gecko code
DISABLE_STL_WRAPPING = True
FAIL_ON_WARNINGS = True

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

@ -39,6 +39,8 @@ public:
virtual const uint16_t* ClearBytes() const = 0;
virtual const uint32_t* CipherBytes() const = 0;
virtual ~GMPEncryptedBufferMetadata() {}
};
class GMPBuffer {
@ -177,6 +179,8 @@ public:
// Returns decrypted buffer to Gecko, or reports failure.
virtual void Decrypted(GMPBuffer* aBuffer, GMPErr aResult) = 0;
virtual ~GMPDecryptorCallback() {}
};
// Host interface, passed to GetAPIFunc(), with "decrypt".
@ -187,6 +191,8 @@ public:
virtual void GetPluginVoucher(const uint8_t** aVoucher,
uint32_t* aVoucherLength) = 0;
virtual ~GMPDecryptorHost() {}
};
enum GMPSessionType {
@ -265,6 +271,7 @@ public:
// Do not call the GMPDecryptorCallback's functions after this is called.
virtual void DecryptingComplete() = 0;
virtual ~GMPDecryptor() {}
};
#endif // GMP_DECRYPTION_h_

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

@ -504,6 +504,21 @@ bool MediaCodecProxy::Prepare()
return true;
}
bool MediaCodecProxy::UpdateOutputBuffers()
{
if (mCodec == nullptr) {
ALOG("MediaCodec has not been inited from input!");
return false;
}
status_t err = getOutputBuffers(&mOutputBuffers);
if (err != OK){
ALOG("Couldn't update output buffers from MediaCodec");
return false;
}
return true;
}
status_t MediaCodecProxy::Input(const uint8_t* aData, uint32_t aDataSize,
int64_t aTimestampUsecs, uint64_t aflags)
{
@ -540,7 +555,6 @@ status_t MediaCodecProxy::Input(const uint8_t* aData, uint32_t aDataSize,
status_t MediaCodecProxy::Output(MediaBuffer** aBuffer, int64_t aTimeoutUs)
{
if (mCodec == nullptr) {
ALOG("MediaCodec has not been inited from output!");
return NO_INIT;

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

@ -132,6 +132,8 @@ public:
bool IsWaitingResources();
bool IsDormantNeeded();
void ReleaseMediaResources();
// This updates mOutputBuffer when receiving INFO_OUTPUT_BUFFERS_CHANGED event.
bool UpdateOutputBuffers();
void ReleaseMediaBuffer(MediaBuffer* abuffer);

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

@ -424,7 +424,7 @@ txCompileObserver::loadURI(const nsAString& aUri,
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
uri,
referrerPrincipal,
nullptr,
mLoaderDocument,
NS_LITERAL_CSTRING("application/xml"),
nullptr,
&shouldLoad);
@ -460,12 +460,14 @@ txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
}
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
aUri,
aReferrerPrincipal,
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_STYLESHEET,
loadGroup);
nsresult rv = NS_NewChannelWithTriggeringPrincipal(
getter_AddRefs(channel),
aUri,
mLoaderDocument,
aReferrerPrincipal, // triggeringPrincipal
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_XSLT,
loadGroup);
NS_ENSURE_SUCCESS(rv, rv);
@ -521,7 +523,7 @@ TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
aUri,
principal,
aProcessor->GetSourceContentModel(),
aLoaderDocument,
NS_LITERAL_CSTRING("application/xml"),
nullptr,
&shouldLoad);

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

@ -1003,6 +1003,7 @@ public:
virtual bool IsDualDrawTarget() const { return false; }
virtual bool IsTiledDrawTarget() const { return false; }
virtual bool SupportsRegionClipping() const { return true; }
void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
mUserData.Add(key, userData, destroy);

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

@ -131,6 +131,8 @@ public:
virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
virtual bool SupportsRegionClipping() const { return false; }
virtual void *GetNativeSurface(NativeSurfaceType aType);
bool Init(const IntSize &aSize, SurfaceFormat aFormat);

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

@ -122,6 +122,8 @@ public:
virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
virtual bool SupportsRegionClipping() const { return false; }
virtual void *GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
bool Init(const IntSize &aSize, SurfaceFormat aFormat);

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

@ -174,52 +174,6 @@ gfxFT2Font::~gfxFT2Font()
{
}
/**
* Look up the font in the gfxFont cache. If we don't find it, create one.
* In either case, add a ref, append it to the aFonts array, and return it ---
* except for OOM in which case we do nothing and return null.
*/
already_AddRefed<gfxFT2Font>
gfxFT2Font::GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle,
bool aNeedsBold)
{
#ifdef ANDROID
FT2FontEntry *fe = static_cast<FT2FontEntry*>
(gfxPlatformFontList::PlatformFontList()->
FindFontForFamily(aName, aStyle, aNeedsBold));
#else
FT2FontEntry *fe = static_cast<FT2FontEntry*>
(gfxToolkitPlatform::GetPlatform()->FindFontEntry(aName, *aStyle));
#endif
if (!fe) {
NS_WARNING("Failed to find font entry for font!");
return nullptr;
}
nsRefPtr<gfxFT2Font> font = GetOrMakeFont(fe, aStyle, aNeedsBold);
return font.forget();
}
already_AddRefed<gfxFT2Font>
gfxFT2Font::GetOrMakeFont(FT2FontEntry *aFontEntry, const gfxFontStyle *aStyle,
bool aNeedsBold)
{
nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aFontEntry, aStyle);
if (!font) {
cairo_scaled_font_t *scaledFont = aFontEntry->CreateScaledFont(aStyle);
if (!scaledFont) {
return nullptr;
}
font = new gfxFT2Font(scaledFont, aFontEntry, aStyle, aNeedsBold);
cairo_scaled_font_destroy(scaledFont);
if (!font) {
return nullptr;
}
gfxFontCache::GetCache()->AddNew(font);
}
return font.forget().downcast<gfxFT2Font>();
}
void
gfxFT2Font::FillGlyphDataForChar(uint32_t ch, CachedGlyphData *gd)
{

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

@ -27,14 +27,6 @@ public: // new functions
FT2FontEntry *GetFontEntry();
static already_AddRefed<gfxFT2Font>
GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle,
bool aNeedsBold = false);
static already_AddRefed<gfxFT2Font>
GetOrMakeFont(FT2FontEntry *aFontEntry, const gfxFontStyle *aStyle,
bool aNeedsBold = false);
struct CachedGlyphData {
CachedGlyphData()
: glyphIndex(0xffffffffU) { }

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

@ -9,7 +9,7 @@
#include "base/process.h"
#include "mozilla/Mutex.h"
#if defined(OS_POSIX)
#if defined(OS_LINUX) || defined(OS_MACOSX)
#include <pthread.h>
#include "SharedMemoryBasic.h"
#include "mozilla/Atomics.h"
@ -34,7 +34,7 @@ struct ParamTraits;
namespace mozilla {
#if defined(OS_WIN)
typedef HANDLE CrossProcessMutexHandle;
#elif defined(OS_POSIX)
#elif defined(OS_LINUX) || defined(OS_MACOSX)
typedef mozilla::ipc::SharedMemoryBasic::Handle CrossProcessMutexHandle;
#else
// Stub for other platforms. We can't use uintptr_t here since different
@ -100,7 +100,7 @@ private:
#if defined(OS_WIN)
HANDLE mMutex;
#elif defined(OS_POSIX)
#elif defined(OS_LINUX) || defined(OS_MACOSX)
nsRefPtr<mozilla::ipc::SharedMemoryBasic> mSharedBuffer;
pthread_mutex_t* mMutex;
mozilla::Atomic<int32_t>* mCount;

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

@ -321,7 +321,11 @@ enum { REG_EIP = 14 };
static uint8_t **
ContextToPC(CONTEXT *context)
{
return reinterpret_cast<uint8_t**>(&PC_sig(context));
#ifdef JS_CODEGEN_NONE
MOZ_CRASH();
#else
return reinterpret_cast<uint8_t**>(&PC_sig(context));
#endif
}
#if defined(JS_CODEGEN_X64)

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

@ -3358,7 +3358,7 @@ class FunctionCompiler
private:
void noteBasicBlockPosition(MBasicBlock *blk, ParseNode *pn)
{
#if defined(JS_ION_PERF)
#if defined(JS_ION_PERF) || defined(DEBUG)
if (pn) {
unsigned line = 0U, column = 0U;
m().tokenStream().srcCoords.lineNumAndColumnIndex(pn->pn_pos.begin, &line, &column);

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

@ -139,13 +139,14 @@ JS_TraceIncomingCCWs(JSTracer *trc, const JS::ZoneSet &zones)
// zones multiple times, and don't hold a strong reference.
if (key.kind == CrossCompartmentKey::StringWrapper)
continue;
JSObject *obj = static_cast<JSObject *>(key.wrapped);
// Ignore CCWs whose wrapped value doesn't live in our given set
// of zones.
if (!zones.has(static_cast<JSObject *>(key.wrapped)->zone()))
if (!zones.has(obj->zone()))
continue;
void *thing = key.wrapped;
trc->callback(trc, &thing, GetGCThingTraceKind(key.wrapped));
MarkObjectUnbarriered(trc, &obj, "cross-compartment wrapper");
MOZ_ASSERT(obj == key.wrapped);
}
}
}

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

@ -0,0 +1,13 @@
if (typeof TypedObject === "undefined")
quit();
var T = TypedObject;
var ObjectStruct = new T.StructType({f: T.Object});
var o = new ObjectStruct();
function testGC(o, p) {
for (var i = 0; i < 5; i++) {
minorgc();
o.f >>= p;
}
}
testGC(o, {});

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

@ -4103,8 +4103,22 @@ CodeGenerator::generateBody()
if (current->isTrivial())
continue;
JitSpew(JitSpew_Codegen, "# block%lu%s:", i,
#ifdef DEBUG
const char *filename = nullptr;
unsigned lineNumber = 0, columnNumber = 0;
if (current->mir()->info().script()) {
filename = current->mir()->info().script()->filename();
if (current->mir()->pc())
lineNumber = PCToLineNumber(current->mir()->info().script(), current->mir()->pc(),
&columnNumber);
} else {
lineNumber = current->mir()->lineno();
columnNumber = current->mir()->columnIndex();
}
JitSpew(JitSpew_Codegen, "# block%lu %s:%u:%u%s:", i,
filename ? filename : "?", lineNumber, columnNumber,
current->mir()->isLoopHeader() ? " (loop header)" : "");
#endif
masm.bind(current->label());

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

@ -11321,9 +11321,6 @@ IonBuilder::storeReferenceTypedObjectValue(MDefinition *typedObj,
ReferenceTypeDescr::Type type,
MDefinition *value)
{
if (NeedsPostBarrier(info(), value))
current->add(MPostWriteBarrier::New(alloc(), typedObj, value));
// Find location within the owner object.
MDefinition *elements, *scaledOffset;
size_t alignment = ReferenceTypeDescr::alignment(type);
@ -11332,12 +11329,20 @@ IonBuilder::storeReferenceTypedObjectValue(MDefinition *typedObj,
MInstruction *store;
switch (type) {
case ReferenceTypeDescr::TYPE_ANY:
if (NeedsPostBarrier(info(), value))
current->add(MPostWriteBarrier::New(alloc(), typedObj, value));
store = MStoreElement::New(alloc(), elements, scaledOffset, value, false);
break;
case ReferenceTypeDescr::TYPE_OBJECT:
store = MStoreUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, value);
// Note: We cannot necessarily tell at this point whether a post
// barrier is needed, because the type policy may insert ToObjectOrNull
// instructions later, and those may require a post barrier. Therefore,
// defer the insertion of post barriers to the type policy.
store = MStoreUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, value, typedObj);
break;
case ReferenceTypeDescr::TYPE_STRING:
// Strings are not nursery allocated, so these writes do not need post
// barriers.
store = MStoreUnboxedString::New(alloc(), elements, scaledOffset, value);
break;
}

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

@ -2456,7 +2456,8 @@ LIRGenerator::visitPostWriteBarrier(MPostWriteBarrier *ins)
{
#ifdef JSGC_GENERATIONAL
switch (ins->value()->type()) {
case MIRType_Object: {
case MIRType_Object:
case MIRType_ObjectOrNull: {
LDefinition tmp = needTempForPostBarrier() ? temp() : LDefinition::BogusTemp();
LPostWriteBarrierO *lir =
new(alloc()) LPostWriteBarrierO(useRegisterOrConstant(ins->object()),

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

@ -8004,15 +8004,18 @@ class MStoreElementHole
// Store an unboxed object or null pointer to a vector.
class MStoreUnboxedObjectOrNull
: public MAryInstruction<3>,
public ConvertToObjectOrNullPolicy<2>::Data
: public MAryInstruction<4>,
public StoreUnboxedObjectOrNullPolicy::Data
{
MStoreUnboxedObjectOrNull(MDefinition *elements, MDefinition *index, MDefinition *value) {
MStoreUnboxedObjectOrNull(MDefinition *elements, MDefinition *index,
MDefinition *value, MDefinition *typedObj) {
initOperand(0, elements);
initOperand(1, index);
initOperand(2, value);
initOperand(3, typedObj);
MOZ_ASSERT(elements->type() == MIRType_Elements);
MOZ_ASSERT(index->type() == MIRType_Int32);
MOZ_ASSERT(typedObj->type() == MIRType_Object);
}
public:
@ -8020,8 +8023,8 @@ class MStoreUnboxedObjectOrNull
static MStoreUnboxedObjectOrNull *New(TempAllocator &alloc,
MDefinition *elements, MDefinition *index,
MDefinition *value) {
return new(alloc) MStoreUnboxedObjectOrNull(elements, index, value);
MDefinition *value, MDefinition *typedObj) {
return new(alloc) MStoreUnboxedObjectOrNull(elements, index, value, typedObj);
}
MDefinition *elements() const {
return getOperand(0);
@ -8032,11 +8035,19 @@ class MStoreUnboxedObjectOrNull
MDefinition *value() const {
return getOperand(2);
}
MDefinition *typedObj() const {
return getOperand(3);
}
AliasSet getAliasSet() const {
// Use AliasSet::Element for reference typed object fields.
return AliasSet::Store(AliasSet::Element);
}
// For StoreUnboxedObjectOrNullPolicy.
void setValue(MDefinition *def) {
replaceOperand(2, def);
}
ALLOW_CLONE(MStoreUnboxedObjectOrNull)
};

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

@ -651,7 +651,7 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock>
const BytecodeSite *trackedSite_;
#if defined (JS_ION_PERF)
#if defined(JS_ION_PERF) || defined(DEBUG)
unsigned lineno_;
unsigned columnIndex_;

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

@ -192,7 +192,8 @@ RValueAllocation::layoutFromMode(Mode mode)
case UNTYPED_STACK_REG: {
static const RValueAllocation::Layout layout = {
PAYLOAD_STACK_OFFSET,
PAYLOAD_GPR
PAYLOAD_GPR,
"value"
};
return layout;
}

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

@ -407,31 +407,6 @@ template bool ConvertToStringPolicy<0>::staticAdjustInputs(TempAllocator &alloc,
template bool ConvertToStringPolicy<1>::staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
template bool ConvertToStringPolicy<2>::staticAdjustInputs(TempAllocator &alloc, MInstruction *ins);
template <unsigned Op>
bool
ConvertToObjectOrNullPolicy<Op>::staticAdjustInputs(TempAllocator &alloc, MInstruction *ins)
{
MDefinition *in = ins->getOperand(Op);
if (in->type() == MIRType_Object ||
in->type() == MIRType_Null ||
in->type() == MIRType_ObjectOrNull)
{
return true;
}
MToObjectOrNull *replace = MToObjectOrNull::New(alloc, in);
ins->block()->insertBefore(ins, replace);
ins->replaceOperand(Op, replace);
if (!BoxPolicy<0>::staticAdjustInputs(alloc, replace))
return false;
return true;
}
template bool ConvertToObjectOrNullPolicy<2>::staticAdjustInputs(TempAllocator &alloc,
MInstruction *ins);
template <unsigned Op>
bool
IntPolicy<Op>::staticAdjustInputs(TempAllocator &alloc, MInstruction *def)
@ -869,6 +844,39 @@ StoreTypedArrayElementStaticPolicy::adjustInputs(TempAllocator &alloc, MInstruct
adjustValueInput(alloc, ins, store->viewType(), store->value(), 1);
}
bool
StoreUnboxedObjectOrNullPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
// Change the value input to a ToObjectOrNull instruction if it might be
// a non-null primitive. Insert a post barrier for the instruction's object
// and whatever its new value is, unless the value is definitely null.
MStoreUnboxedObjectOrNull *store = ins->toStoreUnboxedObjectOrNull();
MDefinition *value = store->value();
if (value->type() == MIRType_Object ||
value->type() == MIRType_Null ||
value->type() == MIRType_ObjectOrNull)
{
if (value->type() != MIRType_Null) {
MInstruction *barrier = MPostWriteBarrier::New(alloc, store->typedObj(), value);
store->block()->insertBefore(store, barrier);
}
return true;
}
MToObjectOrNull *replace = MToObjectOrNull::New(alloc, value);
store->block()->insertBefore(store, replace);
store->setValue(replace);
if (!BoxPolicy<0>::staticAdjustInputs(alloc, replace))
return false;
MInstruction *barrier = MPostWriteBarrier::New(alloc, store->typedObj(), replace);
store->block()->insertBefore(store, barrier);
return true;
}
bool
ClampPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
{
@ -956,6 +964,7 @@ FilterTypeSetPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
_(StoreTypedArrayElementStaticPolicy) \
_(StoreTypedArrayHolePolicy) \
_(StoreTypedArrayPolicy) \
_(StoreUnboxedObjectOrNullPolicy) \
_(TestPolicy) \
_(ToDoublePolicy) \
_(ToInt32Policy) \
@ -968,7 +977,6 @@ FilterTypeSetPolicy::adjustInputs(TempAllocator &alloc, MInstruction *ins)
_(ConvertToInt32Policy<0>) \
_(ConvertToStringPolicy<0>) \
_(ConvertToStringPolicy<2>) \
_(ConvertToObjectOrNullPolicy<2>) \
_(DoublePolicy<0>) \
_(FloatingPointPolicy<0>) \
_(IntPolicy<0>) \

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

@ -148,19 +148,6 @@ class ConvertToStringPolicy : public TypePolicy
}
};
// Expect an object or null value for operand Op. Else a ToObjectOrNull
// instruction is inserted.
template <unsigned Op>
class ConvertToObjectOrNullPolicy : public TypePolicy
{
public:
EMPTY_DATA_;
static bool staticAdjustInputs(TempAllocator &alloc, MInstruction *def);
bool adjustInputs(TempAllocator &alloc, MInstruction *def) {
return staticAdjustInputs(alloc, def);
}
};
// Expect an Int for operand Op. If the input is a Value, it is unboxed.
template <unsigned Op>
class IntPolicy : public BoxInputsPolicy
@ -397,6 +384,13 @@ class StoreTypedArrayElementStaticPolicy : public StoreTypedArrayPolicy
bool adjustInputs(TempAllocator &alloc, MInstruction *ins);
};
class StoreUnboxedObjectOrNullPolicy : public TypePolicy
{
public:
EMPTY_DATA_;
bool adjustInputs(TempAllocator &alloc, MInstruction *def);
};
// Accepts integers and doubles. Everything else is boxed.
class ClampPolicy : public BoxInputsPolicy
{

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

@ -4407,7 +4407,7 @@ static bool ShouldDrawRectsSeparately(gfxContext* aContext, DrawRegionClip aClip
}
DrawTarget *dt = aContext->GetDrawTarget();
return dt->GetBackendType() == BackendType::DIRECT2D;
return !dt->SupportsRegionClipping();
}
static void DrawForcedBackgroundColor(gfxContext* aContext, Layer* aLayer, nscolor aBackgroundColor)

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

@ -8,9 +8,12 @@
* changes need to happen, scheduling them, and doing them.
*/
#include <algorithm> // For std::max
#include "RestyleManager.h"
#include "mozilla/EventStates.h"
#include "nsLayoutUtils.h"
#include "AnimationCommon.h" // For GetLayerAnimationInfo
#include "FrameLayerBuilder.h"
#include "GeckoProfiler.h"
#include "nsStyleChangeList.h"
#include "nsRuleProcessorData.h"
@ -1149,6 +1152,27 @@ RestyleManager::AttributeChanged(Element* aElement,
PostRestyleEvent(aElement, rshint, hint);
}
/* static */ uint64_t
RestyleManager::GetMaxAnimationGenerationForFrame(nsIFrame* aFrame)
{
nsIContent* content = aFrame->GetContent();
if (!content || !content->IsElement()) {
return 0;
}
nsCSSPseudoElements::Type pseudoType =
aFrame->StyleContext()->GetPseudoType();
AnimationPlayerCollection* transitions =
aFrame->PresContext()->TransitionManager()->GetAnimationPlayers(
content->AsElement(), pseudoType, false /* don't create */);
AnimationPlayerCollection* animations =
aFrame->PresContext()->AnimationManager()->GetAnimationPlayers(
content->AsElement(), pseudoType, false /* don't create */);
return std::max(transitions ? transitions->mAnimationGeneration : 0,
animations ? animations->mAnimationGeneration : 0);
}
void
RestyleManager::RestyleForEmptyChange(Element* aContainer)
{
@ -1560,7 +1584,7 @@ RestyleManager::ProcessPendingRestyles()
// correct old style for starting the transition.
if (nsLayoutUtils::AreAsyncAnimationsEnabled() &&
mPendingRestyles.Count() > 0) {
++mAnimationGeneration;
IncrementAnimationGeneration();
UpdateOnlyAnimationStyles();
}
@ -2408,6 +2432,40 @@ ElementRestyler::ElementRestyler(ParentContextFromChildFrame,
{
}
void
ElementRestyler::AddLayerChangesForAnimation()
{
// Bug 847286 - We should have separate animation generation counters
// on layers for transitions and animations and use != comparison below
// rather than a > comparison.
uint64_t frameGeneration =
RestyleManager::GetMaxAnimationGenerationForFrame(mFrame);
nsChangeHint hint = nsChangeHint(0);
const auto& layerInfo = css::CommonAnimationManager::sLayerAnimationInfo;
for (size_t i = 0; i < ArrayLength(layerInfo); i++) {
Layer* layer =
FrameLayerBuilder::GetDedicatedLayer(mFrame, layerInfo[i].mLayerType);
if (layer && frameGeneration > layer->GetAnimationGeneration()) {
// If we have a transform layer but don't have any transform style, we
// probably just removed the transform but haven't destroyed the layer
// yet. In this case we will add the appropriate change hint
// (nsChangeHint_AddOrRemoveTransform) when we compare style contexts
// so we can skip adding any change hint here. (If we *were* to add
// nsChangeHint_UpdateTransformLayer, ApplyRenderingChangeToTree would
// complain that we're updating a transform layer without a transform).
if (layerInfo[i].mLayerType == nsDisplayItem::TYPE_TRANSFORM &&
!mFrame->StyleDisplay()->HasTransformStyle()) {
continue;
}
NS_UpdateHint(hint, layerInfo[i].mChangeHint);
}
}
if (hint) {
mChangeList->AppendChange(mFrame, mContent, hint);
}
}
void
ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
nsStyleContext* aNewContext,
@ -2522,6 +2580,12 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
}
}
// Some changes to animations don't affect the computed style and yet still
// require the layer to be updated. For example, pausing an animation via
// the Web Animations API won't affect an element's style but still
// requires us to pull the animation off the layer.
AddLayerChangesForAnimation();
// If we are restyling this frame with eRestyle_Self or weaker hints,
// we restyle children with nsRestyleHint(0). But we pass the
// eRestyle_ChangeAnimationPhaseDescendants and eRestyle_ForceDescendants

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

@ -92,6 +92,19 @@ public:
// track whether off-main-thread animations are up-to-date.
uint64_t GetAnimationGeneration() const { return mAnimationGeneration; }
// A workaround until bug 847286 lands that gets the maximum of the animation
// generation counters stored on the set of animations and transitions
// respectively for |aFrame|.
static uint64_t GetMaxAnimationGenerationForFrame(nsIFrame* aFrame);
// Update the animation generation count to mark that animation state
// has changed.
//
// This is normally performed automatically by ProcessPendingRestyles
// but it is also called when we have out-of-band changes to animations
// such as changes made through the Web Animations API.
void IncrementAnimationGeneration() { ++mAnimationGeneration; }
// Whether rule matching should skip styles associated with animation
bool SkipAnimationRules() const {
MOZ_ASSERT(mSkipAnimationRules || !mPostAnimationRestyles,
@ -593,6 +606,11 @@ private:
*/
void RestyleChildren(nsRestyleHint aChildRestyleHint);
/**
* Helpers for Restyle().
*/
void AddLayerChangesForAnimation();
/**
* Helpers for RestyleSelf().
*/

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

@ -1444,7 +1444,7 @@ nsCSSBorderRenderer::DrawBorders()
strokeOptions.mDashOffset = 0.5f;
DrawOptions drawOptions;
drawOptions.mAntialiasMode = AntialiasMode::NONE;
mDrawTarget->StrokeRect(rect, color, strokeOptions);
mDrawTarget->StrokeRect(rect, color, strokeOptions, drawOptions);
return;
}

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

@ -62,6 +62,7 @@
#include "UnitTransforms.h"
#include "LayersLogging.h"
#include "FrameLayerBuilder.h"
#include "RestyleManager.h"
#include "nsCaret.h"
#include "nsISelection.h"
@ -440,6 +441,15 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
aLayer->ClearAnimations();
}
// Update the animation generation on the layer. We need to do this before
// any early returns since even if we don't add any animations to the
// layer, we still need to mark it as up-to-date with regards to animations.
// Otherwise, in RestyleManager we'll notice the discrepancy between the
// animation generation numbers and update the layer indefinitely.
uint64_t animationGeneration =
RestyleManager::GetMaxAnimationGenerationForFrame(aFrame);
aLayer->SetAnimationGeneration(animationGeneration);
nsIContent* content = aFrame->GetContent();
if (!content) {
return;
@ -507,13 +517,11 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
if (transitions) {
AddAnimationsForProperty(aFrame, aProperty, transitions->mPlayers,
aLayer, data, pending);
aLayer->SetAnimationGeneration(transitions->mAnimationGeneration);
}
if (animations) {
AddAnimationsForProperty(aFrame, aProperty, animations->mPlayers,
aLayer, data, pending);
aLayer->SetAnimationGeneration(animations->mAnimationGeneration);
}
}

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

@ -1558,7 +1558,7 @@ nsPresContext::Detach()
}
bool
nsPresContext::StyleUpdateForAllAnimationsIsUpToDate()
nsPresContext::StyleUpdateForAllAnimationsIsUpToDate() const
{
return mLastStyleUpdateForAllAnimations == mRefreshDriver->MostRecentRefresh();
}
@ -1569,6 +1569,12 @@ nsPresContext::TickLastStyleUpdateForAllAnimations()
mLastStyleUpdateForAllAnimations = mRefreshDriver->MostRecentRefresh();
}
void
nsPresContext::ClearLastStyleUpdateForAllAnimations()
{
mLastStyleUpdateForAllAnimations = TimeStamp();
}
bool
nsPresContext::BidiEnabledExternal() const
{

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

@ -705,10 +705,11 @@ public:
}
/**
* Getter and setter for OMTA time counters
* Getter and setters for OMTA time counters
*/
bool StyleUpdateForAllAnimationsIsUpToDate();
bool StyleUpdateForAllAnimationsIsUpToDate() const;
void TickLastStyleUpdateForAllAnimations();
void ClearLastStyleUpdateForAllAnimations();
/**
* Check if bidi enabled (set depending on the presence of RTL

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

@ -296,7 +296,7 @@ NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OverflowOutOfFlowsProperty)
NS_DECLARE_FRAME_PROPERTY_FRAMELIST(PushedFloatProperty)
NS_DECLARE_FRAME_PROPERTY_FRAMELIST(OutsideBulletProperty)
NS_DECLARE_FRAME_PROPERTY(InsideBulletProperty, nullptr)
NS_DECLARE_FRAME_PROPERTY(BottomEdgeOfChildrenProperty, nullptr)
NS_DECLARE_FRAME_PROPERTY(BlockEndEdgeOfChildrenProperty, nullptr)
//----------------------------------------------------------------------
@ -1048,7 +1048,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
if (GetLogicalSkipSides().BStart()) {
blockDirExtras.BStart(wm) = 0;
} else {
// Bottom margin never causes us to create continuations, so we
// Block-end margin never causes us to create continuations, so we
// don't need to worry about whether it fits in its entirety.
blockDirExtras.BStart(wm) +=
aReflowState.ComputedLogicalMargin().BStart(wm);
@ -1206,11 +1206,11 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
WritingMode wm = aReflowState.GetWritingMode();
bool havePosition = nsLayoutUtils::GetFirstLinePosition(wm, this,
&position);
nscoord lineTop = havePosition ?
nscoord lineBStart = havePosition ?
position.mBStart :
reflowState->ComputedLogicalBorderPadding().BStart(wm);
nsIFrame* bullet = GetOutsideBullet();
ReflowBullet(bullet, state, metrics, lineTop);
ReflowBullet(bullet, state, metrics, lineBStart);
NS_ASSERTION(!BulletIsEmpty() || metrics.BSize(wm) == 0,
"empty bullet took up space");
@ -1225,7 +1225,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
bbox.BStart(wm) = position.mBaseline - metrics.BlockStartAscent();
bullet->SetRect(wm, bbox, metrics.Width());
}
// Otherwise just leave the bullet where it is, up against our top padding.
// Otherwise just leave the bullet where it is, up against our
// block-start padding.
}
CheckFloats(state);
@ -1369,7 +1370,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
printf(": status=%x (%scomplete) metrics=%d,%d carriedMargin=%d",
aStatus, NS_FRAME_IS_COMPLETE(aStatus) ? "" : "not ",
aMetrics.ISize(parentWM), aMetrics.BSize(parentWM),
aMetrics.mCarriedOutBottomMargin.get());
aMetrics.mCarriedOutBEndMargin.get());
if (HasOverflowAreas()) {
printf(" overflow-vis={%d,%d,%d,%d}",
aMetrics.VisualOverflow().x,
@ -1452,42 +1453,42 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
aReflowState.ComputedISize()),
borderPadding.IEnd(wm));
// Return bottom margin information
// Return block-end margin information
// rbs says he hit this assertion occasionally (see bug 86947), so
// just set the margin to zero and we'll figure out why later
//NS_ASSERTION(aMetrics.mCarriedOutBottomMargin.IsZero(),
//NS_ASSERTION(aMetrics.mCarriedOutBEndMargin.IsZero(),
// "someone else set the margin");
nscoord nonCarriedOutBDirMargin = 0;
if (!aState.GetFlag(BRS_ISBENDMARGINROOT)) {
// Apply rule from CSS 2.1 section 8.3.1. If we have some empty
// line with clearance and a non-zero top margin and all
// line with clearance and a non-zero block-start margin and all
// subsequent lines are empty, then we do not allow our children's
// carried out bottom margin to be carried out of us and collapse
// with our own bottom margin.
// carried out block-end margin to be carried out of us and collapse
// with our own block-end margin.
if (CheckForCollapsedBEndMarginFromClearanceLine()) {
// Convert the children's carried out margin to something that
// we will include in our height
nonCarriedOutBDirMargin = aState.mPrevBEndMargin.get();
aState.mPrevBEndMargin.Zero();
}
aMetrics.mCarriedOutBottomMargin = aState.mPrevBEndMargin;
aMetrics.mCarriedOutBEndMargin = aState.mPrevBEndMargin;
} else {
aMetrics.mCarriedOutBottomMargin.Zero();
aMetrics.mCarriedOutBEndMargin.Zero();
}
nscoord blockEndEdgeOfChildren = aState.mBCoord + nonCarriedOutBDirMargin;
// Shrink wrap our height around our contents.
if (aState.GetFlag(BRS_ISBENDMARGINROOT) ||
NS_UNCONSTRAINEDSIZE != aReflowState.ComputedBSize()) {
// When we are a bottom-margin root make sure that our last
// childs bottom margin is fully applied. We also do this when
// When we are a block-end-margin root make sure that our last
// childs block-end margin is fully applied. We also do this when
// we have a computed height, since in that case the carried out
// margin is not going to be applied anywhere, so we should note it
// here to be included in the overflow area.
// Apply the margin only if there's space for it.
if (blockEndEdgeOfChildren < aState.mReflowState.AvailableBSize())
{
// Truncate bottom margin if it doesn't fit to our available height.
// Truncate block-end margin if it doesn't fit to our available BSize.
blockEndEdgeOfChildren =
std::min(blockEndEdgeOfChildren + aState.mPrevBEndMargin.get(),
aState.mReflowState.AvailableBSize());
@ -1495,7 +1496,7 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
}
if (aState.GetFlag(BRS_FLOAT_MGR)) {
// Include the float manager's state to properly account for the
// bottom margin of any floated elements; e.g., inside a table cell.
// block-end margin of any floated elements; e.g., inside a table cell.
nscoord floatHeight =
aState.ClearFloats(blockEndEdgeOfChildren, NS_STYLE_CLEAR_BOTH,
nullptr, nsFloatManager::DONT_CLEAR_PUSHED_FLOATS);
@ -1527,16 +1528,16 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// height in the current frame, not whether it's last-in-flow.
}
// Don't carry out a bottom margin when our height is fixed.
aMetrics.mCarriedOutBottomMargin.Zero();
// Don't carry out a block-end margin when our BSize is fixed.
aMetrics.mCarriedOutBEndMargin.Zero();
}
else if (NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
nscoord contentBSize = blockEndEdgeOfChildren - borderPadding.BStart(wm);
nscoord autoBSize = aReflowState.ApplyMinMaxHeight(contentBSize);
if (autoBSize != contentBSize) {
// Our min-height or max-height made our height change. Don't carry out
// our kids' bottom margins.
aMetrics.mCarriedOutBottomMargin.Zero();
// our kids' block-end margins.
aMetrics.mCarriedOutBEndMargin.Zero();
}
autoBSize += borderPadding.BStart(wm) + borderPadding.BEnd(wm);
finalSize.BSize(wm) = autoBSize;
@ -1566,10 +1567,10 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
FrameProperties properties = Properties();
if (blockEndEdgeOfChildren != finalSize.BSize(wm) - borderPadding.BEnd(wm)) {
properties.Set(BottomEdgeOfChildrenProperty(),
properties.Set(BlockEndEdgeOfChildrenProperty(),
NS_INT32_TO_PTR(blockEndEdgeOfChildren));
} else {
properties.Delete(BottomEdgeOfChildrenProperty());
properties.Delete(BlockEndEdgeOfChildrenProperty());
}
aMetrics.SetSize(wm, finalSize);
@ -1583,25 +1584,45 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
}
static void
ConsiderBottomEdgeOfChildren(nscoord aBottomEdgeOfChildren,
nsOverflowAreas& aOverflowAreas)
ConsiderBlockEndEdgeOfChildren(const WritingMode aWritingMode,
nscoord aBEndEdgeOfChildren,
nsOverflowAreas& aOverflowAreas)
{
// Factor in the bottom edge of the children. Child frames will be added
// Factor in the block-end edge of the children. Child frames will be added
// to the overflow area as we iterate through the lines, but their margins
// won't, so we need to account for bottom margins here.
// won't, so we need to account for block-end margins here.
// REVIEW: For now, we do this for both visual and scrollable area,
// although when we make scrollable overflow area not be a subset of
// visual, we can change this.
NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
nsRect& o = aOverflowAreas.Overflow(otype);
o.height = std::max(o.YMost(), aBottomEdgeOfChildren) - o.y;
// XXX Currently, overflow areas are stored as physical rects, so we have
// to handle writing modes explicitly here. If we change overflow rects
// to be stored logically, this can be simplified again.
if (aWritingMode.IsVertical()) {
if (aWritingMode.IsVerticalLR()) {
NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
nsRect& o = aOverflowAreas.Overflow(otype);
o.width = std::max(o.XMost(), aBEndEdgeOfChildren) - o.x;
}
} else {
NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
nsRect& o = aOverflowAreas.Overflow(otype);
nscoord xmost = o.XMost();
o.x = std::min(o.x, xmost - aBEndEdgeOfChildren);
o.width = xmost - o.x;
}
}
} else {
NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
nsRect& o = aOverflowAreas.Overflow(otype);
o.height = std::max(o.YMost(), aBEndEdgeOfChildren) - o.y;
}
}
}
void
nsBlockFrame::ComputeOverflowAreas(const nsRect& aBounds,
const nsStyleDisplay* aDisplay,
nscoord aBottomEdgeOfChildren,
nscoord aBEndEdgeOfChildren,
nsOverflowAreas& aOverflowAreas)
{
// Compute the overflow areas of our children
@ -1625,7 +1646,8 @@ nsBlockFrame::ComputeOverflowAreas(const nsRect& aBounds,
areas.UnionAllWith(outsideBullet->GetRect());
}
ConsiderBottomEdgeOfChildren(aBottomEdgeOfChildren, areas);
ConsiderBlockEndEdgeOfChildren(GetWritingMode(),
aBEndEdgeOfChildren, areas);
}
#ifdef NOISY_COMBINED_AREA
@ -1679,10 +1701,11 @@ nsBlockFrame::UpdateOverflow()
kPrincipalList | kFloatList);
bool found;
nscoord bottomEdgeOfChildren = NS_PTR_TO_INT32(
Properties().Get(BottomEdgeOfChildrenProperty(), &found));
nscoord blockEndEdgeOfChildren = NS_PTR_TO_INT32(
Properties().Get(BlockEndEdgeOfChildrenProperty(), &found));
if (found) {
ConsiderBottomEdgeOfChildren(bottomEdgeOfChildren, overflowAreas);
ConsiderBlockEndEdgeOfChildren(GetWritingMode(),
blockEndEdgeOfChildren, overflowAreas);
}
return FinishAndStoreOverflow(overflowAreas, GetSize());
@ -2077,7 +2100,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
// Reflow the line if it might not have clearance anymore.
if (newBCoord == curBCoord
// aState.mBCoord is the clearance point which should be the
// top border-edge of the block frame. If sliding the
// block-start border-edge of the block frame. If sliding the
// block by deltaBCoord isn't going to put it in the predicted
// position, then we'd better reflow the line.
|| newBCoord != line->BStart() + deltaBCoord) {
@ -2156,9 +2179,9 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
}
if (needToRecoverState && line->IsDirty()) {
// We need to reconstruct the bottom margin only if we didn't
// We need to reconstruct the block-end margin only if we didn't
// reflow the previous line and we do need to reflow (or repair
// the top position of) the next line.
// the block-start position of) the next line.
aState.ReconstructMarginBefore(line);
}
@ -2227,22 +2250,22 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
// Test to see whether the margin that should be carried out
// to the next line (NL) might have changed. In ReflowBlockFrame
// we call nextLine->MarkPreviousMarginDirty if the block's
// actual carried-out bottom margin changed. So here we only
// actual carried-out block-end margin changed. So here we only
// need to worry about the following effects:
// 1) the line was just created, and it might now be blocking
// a carried-out bottom margin from previous lines that
// a carried-out block-end margin from previous lines that
// used to reach NL from reaching NL
// 2) the line used to be empty, and is now not empty,
// thus blocking a carried-out bottom margin from previous lines
// thus blocking a carried-out block-end margin from previous lines
// that used to reach NL from reaching NL
// 3) the line wasn't empty, but now is, so a carried-out
// bottom margin from previous lines that didn't used to reach NL
// block-end margin from previous lines that didn't used to reach NL
// now does
// 4) the line might have changed in a way that affects NL's
// ShouldApplyBStartMargin decision. The three things that matter
// are the line's emptiness, its adjacency to the top of the block,
// and whether it has clearance (the latter only matters if the block
// was and is adjacent to the top and empty).
// are the line's emptiness, its adjacency to the block-start edge of the
// block, and whether it has clearance (the latter only matters if the
// block was and is adjacent to the block-start and empty).
//
// If the line is empty now, we can't reliably tell if the line was empty
// before, so we just assume it was and do nextLine->MarkPreviousMarginDirty.
@ -2956,8 +2979,8 @@ nsBlockFrame::ShouldApplyBStartMargin(nsBlockReflowState& aState,
if (!aState.IsAdjacentWithTop() ||
aChildFrame->StyleBorder()->mBoxDecorationBreak ==
NS_STYLE_BOX_DECORATION_BREAK_CLONE) {
// If we aren't at the top Y coordinate then something of non-zero
// height must have been placed. Therefore the childs top-margin
// If we aren't at the start block-coordinate then something of non-zero
// height must have been placed. Therefore the childs block-start margin
// applies.
aState.SetFlag(BRS_APPLYBSTARTMARGIN, true);
return true;
@ -2971,11 +2994,11 @@ nsBlockFrame::ShouldApplyBStartMargin(nsBlockReflowState& aState,
while (line != aLine) {
if (!line->CachedIsEmpty() || line->HasClearance()) {
// A line which precedes aLine is non-empty, or has clearance,
// so therefore the top margin applies.
// so therefore the block-start margin applies.
aState.SetFlag(BRS_APPLYBSTARTMARGIN, true);
return true;
}
// No need to apply the top margin if the line has floats. We
// No need to apply the block-start margin if the line has floats. We
// should collapse anyway (bug 44419)
++line;
aState.SetFlag(BRS_HAVELINEADJACENTTOTOP, true);
@ -2983,7 +3006,7 @@ nsBlockFrame::ShouldApplyBStartMargin(nsBlockReflowState& aState,
}
// The line being reflowed is "essentially" the first line in the
// block. Therefore its top-margin will be collapsed by the
// block. Therefore its block-start margin will be collapsed by the
// generational collapsing logic with its parent (us).
return false;
}
@ -3015,9 +3038,9 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// Clear past floats before the block if the clear style is not none
aLine->SetBreakTypeBefore(breakType);
// See if we should apply the top margin. If the block frame being
// See if we should apply the block-start margin. If the block frame being
// reflowed is a continuation (non-null prev-in-flow) then we don't
// apply its top margin because it's not significant unless it has
// apply its block-start margin because it's not significant unless it has
// 'box-decoration-break:clone'. Otherwise, dig deeper.
bool applyBStartMargin = (frame->StyleBorder()->mBoxDecorationBreak ==
NS_STYLE_BOX_DECORATION_BREAK_CLONE ||
@ -3025,7 +3048,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
ShouldApplyBStartMargin(aState, aLine, frame);
if (applyBStartMargin) {
// The HasClearance setting is only valid if ShouldApplyBStartMargin
// returned false (in which case the top-margin-root set our
// returned false (in which case the block-start margin-root set our
// clearance flag). Otherwise clear it now. We'll set it later on
// ourselves if necessary.
aLine->ClearHasClearance();
@ -3039,8 +3062,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
replacedBlock = frame;
}
// If our top margin was counted as part of some parents top-margin
// collapse and we are being speculatively reflowed assuming this
// If our block-start margin was counted as part of some parent's block-start
// margin collapse, and we are being speculatively reflowed assuming this
// frame DID NOT need clearance, then we need to check that
// assumption.
if (!treatWithClearance && !applyBStartMargin && mightClearFloats &&
@ -3080,19 +3103,19 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
bool mayNeedRetry = false;
bool clearedFloats = false;
if (applyBStartMargin) {
// Precompute the blocks top margin value so that we can get the
// Precompute the blocks block-start margin value so that we can get the
// correct available space (there might be a float that's
// already been placed below the aState.mPrevBEndMargin
// Setup a reflowState to get the style computed margin-top
// Setup a reflowState to get the style computed block-start margin
// value. We'll use a reason of `resize' so that we don't fudge
// any incremental reflow state.
// The availSpace here is irrelevant to our needs - all we want
// out if this setup is the margin-top value which doesn't depend
// out if this setup is the block-start margin value which doesn't depend
// on the childs available space.
// XXX building a complete nsHTMLReflowState just to get the margin-top
// seems like a waste. And we do this for almost every block!
// XXX building a complete nsHTMLReflowState just to get the block-start
// margin seems like a waste. And we do this for almost every block!
WritingMode wm = frame->GetWritingMode();
LogicalSize availSpace = aState.ContentSize(wm);
availSpace.BSize(wm) = NS_UNCONSTRAINEDSIZE;
@ -3117,7 +3140,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
if (clearanceFrame) {
// Don't allow retries on the second pass. The clearance decisions for the
// blocks whose top-margins collapse with ours are now fixed.
// blocks whose block-start margins collapse with ours are now fixed.
mayNeedRetry = false;
}
@ -3173,7 +3196,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// Note that negative clearance is possible
clearance = aState.mBCoord - (currentBCoord + bStartMargin);
// Add clearance to our top margin while we compute available
// Add clearance to our block-start margin while we compute available
// space for the frame
bStartMargin += clearance;
@ -3200,14 +3223,14 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// The check for
// (!aState.mReflowState.mFlags.mIsTopOfPage || clearedFloats)
// is to some degree out of paranoia: if we reliably eat up top
// is to some degree out of paranoia: if we reliably eat up block-start
// margins at the top of the page as we ought to, it wouldn't be
// needed.
if ((!aState.mReflowState.mFlags.mIsTopOfPage || clearedFloats) &&
availSpace.BSize(wm) < 0) {
// We know already that this child block won't fit on this
// page/column due to the top margin or the clearance. So we need
// to get out of here now. (If we don't, most blocks will handle
// page/column due to the block-start margin or the clearance. So we
// need to get out of here now. (If we don't, most blocks will handle
// things fine, and report break-before, but zero-height blocks
// won't, and will thus make their parent overly-large and force
// *it* to be pushed in its entirety.)
@ -3393,7 +3416,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
}
*aKeepReflowGoing = false;
// The bottom margin for a block is only applied on the last
// The block-end margin for a block is only applied on the last
// flow block. Since we just continued the child block frame,
// we know that line->mFirstChild is not the last flow block
// therefore zero out the running margin value.
@ -3494,7 +3517,7 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
aLine->SetLineIsImpactedByFloat(false);
// Setup initial coordinate system for reflowing the inline frames
// into. Apply a previous block frame's bottom margin first.
// into. Apply a previous block frame's block-end margin first.
if (ShouldApplyBStartMargin(aState, aLine, aLine->mFirstChild)) {
aState.mBCoord += aState.mPrevBEndMargin.get();
}
@ -4286,9 +4309,9 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// Inline lines do not have margins themselves; however they are
// impacted by prior block margins. If this line ends up having some
// height then we zero out the previous bottom margin value that was
// height then we zero out the previous block-end margin value that was
// already applied to the line's starting Y coordinate. Otherwise we
// leave it be so that the previous blocks bottom margin can be
// leave it be so that the previous blocks block-end margin can be
// collapsed with a block that follows.
nscoord newBCoord;
@ -5898,7 +5921,7 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
nsCollapsingMargin margin;
bool mayNeedRetry = false;
floatRS.mDiscoveredClearance = nullptr;
// Only first in flow gets a top margin.
// Only first in flow gets a block-start margin.
if (!aFloat->GetPrevInFlow()) {
brc.ComputeCollapsedBStartMargin(floatRS, &margin,
clearanceFrame,

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

@ -351,7 +351,7 @@ nsBlockReflowContext::PlaceBlock(const nsHTMLReflowState& aReflowState,
WritingMode wm = aReflowState.GetWritingMode();
WritingMode parentWM = mMetrics.GetWritingMode();
if (NS_FRAME_IS_COMPLETE(aReflowStatus)) {
aBEndMarginResult = mMetrics.mCarriedOutBottomMargin;
aBEndMarginResult = mMetrics.mCarriedOutBEndMargin;
aBEndMarginResult.Include(aReflowState.ComputedLogicalMargin().BEnd(wm));
} else {
// The used bottom-margin is set to zero above a break.

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

@ -46,7 +46,7 @@ public:
nsReflowStatus aReflowStatus);
nsCollapsingMargin& GetCarriedOutBEndMargin() {
return mMetrics.mCarriedOutBottomMargin;
return mMetrics.mCarriedOutBEndMargin;
}
const nsHTMLReflowMetrics& GetMetrics() const {

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

@ -572,12 +572,12 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
#ifdef DEBUG_roc
printf("*** Reflowed child #%d %p: status = %d, desiredSize=%d,%d CarriedOutBottomMargin=%d\n",
columnCount, (void*)child, aStatus, kidDesiredSize.Width(), kidDesiredSize.Height(),
kidDesiredSize.mCarriedOutBottomMargin.get());
kidDesiredSize.mCarriedOutBEndMargin.get());
#endif
NS_FRAME_TRACE_REFLOW_OUT("Column::Reflow", aStatus);
*aBottomMarginCarriedOut = kidDesiredSize.mCarriedOutBottomMargin;
*aBottomMarginCarriedOut = kidDesiredSize.mCarriedOutBEndMargin;
FinishReflowChild(child, PresContext(), kidDesiredSize,
&kidReflowState, childOrigin.x, childOrigin.y, 0);
@ -1030,7 +1030,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus, false);
aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
aDesiredSize.mCarriedOutBEndMargin = carriedOutBottomMargin;
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
}

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

@ -5405,7 +5405,7 @@ nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
ClearOverflowRects();
aMetrics.ClearSize();
aMetrics.SetBlockStartAscent(0);
aMetrics.mCarriedOutBottomMargin.Zero();
aMetrics.mCarriedOutBEndMargin.Zero();
aMetrics.mOverflowAreas.Clear();
if (GetNextInFlow()) {

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

@ -419,37 +419,63 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState,
nsHTMLReflowMetrics* aMetrics,
bool aFirstPass)
{
WritingMode wm = mHelper.mScrolledFrame->GetWritingMode();
// these could be NS_UNCONSTRAINEDSIZE ... std::min arithmetic should
// be OK
const nsMargin& padding = aState->mReflowState.ComputedPhysicalPadding();
nscoord availWidth = aState->mReflowState.ComputedWidth() + padding.LeftRight();
LogicalMargin padding = aState->mReflowState.ComputedLogicalPadding();
nscoord availISize =
aState->mReflowState.ComputedISize() + padding.IStartEnd(wm);
nscoord computedHeight = aState->mReflowState.ComputedHeight();
nscoord computedMinHeight = aState->mReflowState.ComputedMinHeight();
nscoord computedMaxHeight = aState->mReflowState.ComputedMaxHeight();
nscoord computedBSize = aState->mReflowState.ComputedBSize();
nscoord computedMinBSize = aState->mReflowState.ComputedMinBSize();
nscoord computedMaxBSize = aState->mReflowState.ComputedMaxBSize();
if (!ShouldPropagateComputedHeightToScrolledContent()) {
computedHeight = NS_UNCONSTRAINEDSIZE;
computedMinHeight = 0;
computedMaxHeight = NS_UNCONSTRAINEDSIZE;
}
if (aAssumeHScroll) {
nsSize hScrollbarPrefSize;
GetScrollbarMetrics(aState->mBoxState, mHelper.mHScrollbarBox,
nullptr, &hScrollbarPrefSize, false);
if (computedHeight != NS_UNCONSTRAINEDSIZE) {
computedHeight = std::max(0, computedHeight - hScrollbarPrefSize.height);
}
computedMinHeight = std::max(0, computedMinHeight - hScrollbarPrefSize.height);
if (computedMaxHeight != NS_UNCONSTRAINEDSIZE) {
computedMaxHeight = std::max(0, computedMaxHeight - hScrollbarPrefSize.height);
}
computedBSize = NS_UNCONSTRAINEDSIZE;
computedMinBSize = 0;
computedMaxBSize = NS_UNCONSTRAINEDSIZE;
}
if (aAssumeVScroll) {
nsSize vScrollbarPrefSize;
GetScrollbarMetrics(aState->mBoxState, mHelper.mVScrollbarBox,
nullptr, &vScrollbarPrefSize, true);
availWidth = std::max(0, availWidth - vScrollbarPrefSize.width);
if (wm.IsVertical()) {
if (aAssumeVScroll) {
nsSize vScrollbarPrefSize;
GetScrollbarMetrics(aState->mBoxState, mHelper.mVScrollbarBox,
nullptr, &vScrollbarPrefSize, false);
if (computedBSize != NS_UNCONSTRAINEDSIZE) {
computedBSize = std::max(0, computedBSize - vScrollbarPrefSize.width);
}
computedMinBSize = std::max(0, computedMinBSize - vScrollbarPrefSize.width);
if (computedMaxBSize != NS_UNCONSTRAINEDSIZE) {
computedMaxBSize = std::max(0, computedMaxBSize - vScrollbarPrefSize.width);
}
}
if (aAssumeHScroll) {
nsSize hScrollbarPrefSize;
GetScrollbarMetrics(aState->mBoxState, mHelper.mHScrollbarBox,
nullptr, &hScrollbarPrefSize, true);
availISize = std::max(0, availISize - hScrollbarPrefSize.height);
}
} else {
if (aAssumeHScroll) {
nsSize hScrollbarPrefSize;
GetScrollbarMetrics(aState->mBoxState, mHelper.mHScrollbarBox,
nullptr, &hScrollbarPrefSize, false);
if (computedBSize != NS_UNCONSTRAINEDSIZE) {
computedBSize = std::max(0, computedBSize - hScrollbarPrefSize.height);
}
computedMinBSize = std::max(0, computedMinBSize - hScrollbarPrefSize.height);
if (computedMaxBSize != NS_UNCONSTRAINEDSIZE) {
computedMaxBSize = std::max(0, computedMaxBSize - hScrollbarPrefSize.height);
}
}
if (aAssumeVScroll) {
nsSize vScrollbarPrefSize;
GetScrollbarMetrics(aState->mBoxState, mHelper.mVScrollbarBox,
nullptr, &vScrollbarPrefSize, true);
availISize = std::max(0, availISize - vScrollbarPrefSize.width);
}
}
nsPresContext* presContext = PresContext();
@ -458,16 +484,16 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState,
nsHTMLReflowState
kidReflowState(presContext, aState->mReflowState,
mHelper.mScrolledFrame,
LogicalSize(mHelper.mScrolledFrame->GetWritingMode(),
nsSize(availWidth, NS_UNCONSTRAINEDSIZE)),
LogicalSize(wm, availISize, NS_UNCONSTRAINEDSIZE),
-1, -1, nsHTMLReflowState::CALLER_WILL_INIT);
const nsMargin physicalPadding = padding.GetPhysicalMargin(wm);
kidReflowState.Init(presContext, -1, -1, nullptr,
&padding);
&physicalPadding);
kidReflowState.mFlags.mAssumingHScrollbar = aAssumeHScroll;
kidReflowState.mFlags.mAssumingVScrollbar = aAssumeVScroll;
kidReflowState.SetComputedHeight(computedHeight);
kidReflowState.ComputedMinHeight() = computedMinHeight;
kidReflowState.ComputedMaxHeight() = computedMaxHeight;
kidReflowState.SetComputedBSize(computedBSize);
kidReflowState.ComputedMinBSize() = computedMinBSize;
kidReflowState.ComputedMaxBSize() = computedMaxBSize;
// Temporarily set mHasHorizontalScrollbar/mHasVerticalScrollbar to
// reflect our assumptions while we reflow the child.
@ -507,8 +533,10 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState,
nsOverflowAreas childOverflow;
nsLayoutUtils::UnionChildOverflow(mHelper.mScrolledFrame, childOverflow);
nsRect childScrollableOverflow = childOverflow.ScrollableOverflow();
childScrollableOverflow.Inflate(padding);
nsRect contentArea = nsRect(0, 0, availWidth, computedHeight);
childScrollableOverflow.Inflate(padding.GetPhysicalMargin(wm));
nsRect contentArea =
wm.IsVertical() ? nsRect(0, 0, computedBSize, availISize)
: nsRect(0, 0, availISize, computedBSize);
if (!contentArea.Contains(childScrollableOverflow)) {
aMetrics->mOverflowAreas.ScrollableOverflow() = childScrollableOverflow;
}
@ -4128,7 +4156,8 @@ ScrollFrameHelper::IsLTR() const
}
}
return frame->StyleVisibility()->mDirection != NS_STYLE_DIRECTION_RTL;
WritingMode wm = frame->GetWritingMode();
return wm.IsVertical() ? wm.IsVerticalLR() : wm.IsBidiLTR();
}
bool
@ -4584,13 +4613,21 @@ ScrollFrameHelper::AdjustScrollbarRectForResizer(
aPresContext->DevPixelsToAppUnits(widgetRect.height));
}
if (!resizerRect.Contains(aRect.BottomRight() - nsPoint(1, 1)))
return;
if (aVertical)
aRect.height = std::max(0, resizerRect.y - aRect.y);
else
aRect.width = std::max(0, resizerRect.x - aRect.x);
if (resizerRect.Contains(aRect.BottomRight() - nsPoint(1, 1))) {
if (aVertical) {
aRect.height = std::max(0, resizerRect.y - aRect.y);
} else {
aRect.width = std::max(0, resizerRect.x - aRect.x);
}
} else if (resizerRect.Contains(aRect.BottomLeft() + nsPoint(1, -1))) {
if (aVertical) {
aRect.height = std::max(0, resizerRect.y - aRect.y);
} else {
nscoord xmost = aRect.XMost();
aRect.x = std::max(aRect.x, resizerRect.XMost());
aRect.width = xmost - aRect.x;
}
}
}
static void

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

@ -287,9 +287,9 @@ public:
// of the base and the text of the superscript.
nsBoundingMetrics mBoundingMetrics; // [OUT]
// Carried out bottom margin values. This is the collapsed
// (generational) bottom margin value.
nsCollapsingMargin mCarriedOutBottomMargin;
// Carried out block-end margin values. This is the collapsed
// (generational) block-end margin value.
nsCollapsingMargin mCarriedOutBEndMargin;
// For frames that have content that overflow their content area
// (HasOverflowAreas() is true) these rectangles represent the total

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

@ -565,6 +565,19 @@ RenderFrameParent::HitTest(const nsRect& aRect)
return mTouchRegion.Contains(aRect);
}
void
RenderFrameParent::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier)
{
nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
// Perhaps the document containing this frame currently has no presentation?
if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
*aTextureFactoryIdentifier =
static_cast<ClientLayerManager*>(lm.get())->GetTextureFactoryIdentifier();
} else {
*aTextureFactoryIdentifier = TextureFactoryIdentifier();
}
}
} // namespace layout
} // namespace mozilla

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

@ -109,6 +109,11 @@ public:
bool HitTest(const nsRect& aRect);
bool UseAsyncPanZoom() { return !!mContentController; }
void GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier);
inline uint64_t GetLayersId() { return mLayersId; }
protected:
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;

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

@ -16,6 +16,7 @@
/**************************************************************************/
math {
writing-mode: horizontal-tb !important;
direction: ltr;
unicode-bidi: embed;
display: inline;

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

@ -24,11 +24,11 @@
# more serious tests, using SVG reference
== border-circle-2.html border-circle-2-ref.xhtml
fails == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945
fuzzy-if(gtk2Widget,7,437) fuzzy-if(azureQuartz,4,582) fuzzy-if(Android||B2G,36,264) fuzzy-if(d2d,51,323) fuzzy-if(winWidget&&!d2d,16,377) == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945
# Corners
== corner-1.html corner-1-ref.svg # bottom corners different radius than top corners
random == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804
fuzzy-if(winWidget&&!d2d,23,5) fuzzy-if(d2d,32,8) fuzzy-if(Android||B2G,10,8) == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804
fuzzy-if(winWidget&&!d2d,3,10) fuzzy-if(d2d,15,32) fuzzy-if(Android||B2G,3,15) == corner-3.html corner-3-ref.svg
== corner-4.html corner-4-ref.svg
@ -39,7 +39,7 @@ fuzzy-if(winWidget&&!d2d,3,10) fuzzy-if(d2d,15,32) fuzzy-if(Android||B2G,3,15) =
fails == clipping-1.html clipping-1-ref.html # background color should completely fill box; bug 466572
!= clipping-2.html about:blank # background color clipped to inner/outer border, can't get
# great tests for this due to antialiasing problems described in bug 466572
fuzzy-if(Android&&AndroidVersion<15,9,73) fuzzy-if(Android&&AndroidVersion>=15,9,200) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
== clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
# Tests for clipping the contents of replaced elements and overflow!=visible
!= clipping-4-ref.html clipping-4-notref.html
@ -87,6 +87,6 @@ skip-if(B2G) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,20) fuzzy-if(A
== iframe-1.html iframe-1-ref.html
# Test for antialiasing gaps between background and border
skip-if(B2G) fails-if(d2d) fuzzy-if(winWidget&&!d2d,1,9) fuzzy-if(Android,1,5) == curved-border-background-nogap.html curved-border-background-nogap-ref.html
fuzzy-if(winWidget&&!d2d,1,9) fuzzy-if(d2d,5,40) fuzzy-if(Android||B2G,1,5) == curved-border-background-nogap.html curved-border-background-nogap-ref.html
== color-layer-1a.html color-layer-1-ref.html

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

@ -1195,9 +1195,9 @@ test-pref(dom.use_xbl_scopes_for_remote_xul,true) != 449149-1b.html about:blank
== 455280-1.xhtml 455280-1-ref.xhtml
skip-if(B2G) fails-if(Android) == 455826-1.html 455826-1-ref.html
skip-if(B2G) fails-if(cocoaWidget) fails-if(Android) == 456147.xul 456147-ref.html # bug 458047
skip-if(B2G) fails-if(Android) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),1,1) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1a.html 456219-1-ref.html # bug 853273
skip-if(B2G) fails-if(Android) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),1,1) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1b.html 456219-1-ref.html # bug 853273
skip-if(B2G) fails-if(Android) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),1,1) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1c.html 456219-1-ref.html # bug 853273
fuzzy-if(Android,11,40) fuzzy-if(B2G,11,35) fuzzy-if(d2d&&/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1a.html 456219-1-ref.html # bug 853273
fuzzy-if(Android,11,40) fuzzy-if(B2G,11,35) fuzzy-if(d2d&&/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1b.html 456219-1-ref.html # bug 853273
fuzzy-if(Android,11,40) fuzzy-if(B2G,11,35) fuzzy-if(d2d&&/^Windows\x20NT\x206\.2/.test(http.oscpu),1,69) == 456219-1c.html 456219-1-ref.html # bug 853273
== 456219-2.html 456219-2-ref.html
== 456330-1.gif 456330-1-ref.png
== 456484-1.html 456484-1-ref.html

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

@ -17,7 +17,7 @@ fuzzy-if(d2d&&/^Windows\x20NT\x206\.1/.test(http.oscpu),16,90) == element-paint-
== element-paint-background-size-02.html element-paint-background-size-02-ref.html
== element-paint-transform-repeated.html element-paint-transform-repeated-ref.html
fuzzy-if(d2d,255,24) == element-paint-transform-03.html element-paint-transform-03-ref.html
fuzzy-if(B2G,1,5) fuzzy-if(gtk2Widget,1,32) fuzzy-if(cocoaWidget,1,106) == element-paint-native-widget.html element-paint-native-widget-ref.html
== element-paint-native-widget.html element-paint-native-widget-ref.html
== element-paint-subimage-sampling-restriction.html about:blank
== element-paint-clippath.html element-paint-clippath-ref.html
== element-paint-sharpness-01a.html element-paint-sharpness-01b.html

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

@ -52,6 +52,7 @@ namespace css {
CommonAnimationManager::CommonAnimationManager(nsPresContext *aPresContext)
: mPresContext(aPresContext)
, mIsObservingRefreshDriver(false)
{
PR_INIT_CLIST(&mElementCollections);
}
@ -70,6 +71,21 @@ CommonAnimationManager::Disconnect()
mPresContext = nullptr;
}
void
CommonAnimationManager::AddElementCollection(AnimationPlayerCollection*
aCollection)
{
if (!mIsObservingRefreshDriver) {
NS_ASSERTION(aCollection->mNeedsRefreshes,
"Added data which doesn't need refreshing?");
// We need to observe the refresh driver.
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mIsObservingRefreshDriver = true;
}
PR_INSERT_BEFORE(aCollection, &mElementCollections);
}
void
CommonAnimationManager::RemoveAllElementCollections()
{
@ -81,6 +97,26 @@ CommonAnimationManager::RemoveAllElementCollections()
}
}
void
CommonAnimationManager::CheckNeedsRefresh()
{
for (PRCList *l = PR_LIST_HEAD(&mElementCollections);
l != &mElementCollections;
l = PR_NEXT_LINK(l)) {
if (static_cast<AnimationPlayerCollection*>(l)->mNeedsRefreshes) {
if (!mIsObservingRefreshDriver) {
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mIsObservingRefreshDriver = true;
}
return;
}
}
if (mIsObservingRefreshDriver) {
mIsObservingRefreshDriver = false;
mPresContext->RefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
}
}
AnimationPlayerCollection*
CommonAnimationManager::GetAnimationsForCompositor(nsIContent* aContent,
nsIAtom* aElementProperty,
@ -102,10 +138,12 @@ CommonAnimationManager::GetAnimationsForCompositor(nsIContent* aContent,
// Mark the frame as active, in case we are able to throttle this animation.
nsIFrame* frame = nsLayoutUtils::GetStyleFrame(collection->mElement);
if (frame) {
if (aProperty == eCSSProperty_opacity) {
ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_opacity);
} else if (aProperty == eCSSProperty_transform) {
ActiveLayerTracker::NotifyAnimated(frame, eCSSProperty_transform);
const auto& info = sLayerAnimationInfo;
for (size_t i = 0; i < ArrayLength(info); i++) {
if (aProperty == info[i].mProperty) {
ActiveLayerTracker::NotifyAnimated(frame, aProperty);
break;
}
}
}
@ -189,6 +227,17 @@ CommonAnimationManager::AddStyleUpdatesTo(RestyleTracker& aTracker)
}
}
void
CommonAnimationManager::NotifyCollectionUpdated(AnimationPlayerCollection&
aCollection)
{
CheckNeedsRefresh();
mPresContext->ClearLastStyleUpdateForAllAnimations();
mPresContext->RestyleManager()->IncrementAnimationGeneration();
aCollection.UpdateAnimationGeneration(mPresContext);
aCollection.PostRestyleForAnimation(mPresContext);
}
/* static */ bool
CommonAnimationManager::ExtractComputedValueForTransition(
nsCSSProperty aProperty,
@ -208,6 +257,15 @@ CommonAnimationManager::ExtractComputedValueForTransition(
return result;
}
/* static */ const CommonAnimationManager::LayerAnimationRecord
CommonAnimationManager::sLayerAnimationInfo[] =
{ { eCSSProperty_transform,
nsDisplayItem::TYPE_TRANSFORM,
nsChangeHint_UpdateTransformLayer },
{ eCSSProperty_opacity,
nsDisplayItem::TYPE_OPACITY,
nsChangeHint_UpdateOpacityLayer } };
NS_IMPL_ISUPPORTS(AnimValuesStyleRule, nsIStyleRule)
/* virtual */ void
@ -438,6 +496,16 @@ AnimationPlayerCollection::GetElementToRestyle() const
return pseudoFrame->GetContent()->AsElement();
}
void
AnimationPlayerCollection::NotifyPlayerUpdated()
{
// On the next flush, force us to update the style rule
mNeedsRefreshes = true;
mStyleRuleRefreshTime = TimeStamp();
mManager->NotifyCollectionUpdated(*this);
}
/* static */ void
AnimationPlayerCollection::LogAsyncAnimationFailure(nsCString& aMessage,
const nsIContent* aContent)
@ -527,8 +595,9 @@ AnimationPlayerCollection::EnsureStyleRuleFor(TimeStamp aRefreshTime,
mNeedsRefreshes);
}
}
}
mManager->CheckNeedsRefresh();
}
bool
AnimationPlayerCollection::CanThrottleTransformChanges(TimeStamp aTime)
@ -546,7 +615,8 @@ AnimationPlayerCollection::CanThrottleTransformChanges(TimeStamp aTime)
}
// If this animation can cause overflow, we can throttle some of the ticks.
if ((aTime - mStyleRuleRefreshTime) < TimeDuration::FromMilliseconds(200)) {
if (!mStyleRuleRefreshTime.IsNull() &&
(aTime - mStyleRuleRefreshTime) < TimeDuration::FromMilliseconds(200)) {
return true;
}
@ -576,27 +646,27 @@ AnimationPlayerCollection::CanThrottleAnimation(TimeStamp aTime)
return false;
}
bool hasTransform = HasAnimationOfProperty(eCSSProperty_transform);
bool hasOpacity = HasAnimationOfProperty(eCSSProperty_opacity);
if (hasOpacity) {
const auto& info = css::CommonAnimationManager::sLayerAnimationInfo;
for (size_t i = 0; i < ArrayLength(info); i++) {
auto record = info[i];
if (!HasAnimationOfProperty(record.mProperty)) {
continue;
}
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
frame, nsDisplayItem::TYPE_OPACITY);
frame, record.mLayerType);
if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
return false;
}
if (record.mProperty == eCSSProperty_transform &&
!CanThrottleTransformChanges(aTime)) {
return false;
}
}
if (!hasTransform) {
return true;
}
Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
frame, nsDisplayItem::TYPE_TRANSFORM);
if (!layer || mAnimationGeneration > layer->GetAnimationGeneration()) {
return false;
}
return CanThrottleTransformChanges(aTime);
return true;
}
void

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

@ -10,7 +10,9 @@
#include "nsIStyleRule.h"
#include "nsRefreshDriver.h"
#include "prclist.h"
#include "nsChangeHint.h"
#include "nsCSSProperty.h"
#include "nsDisplayList.h" // For nsDisplayItem::Type
#include "mozilla/MemoryReporting.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/AnimationPlayer.h"
@ -66,6 +68,15 @@ public:
// elements.
void AddStyleUpdatesTo(mozilla::RestyleTracker& aTracker);
virtual AnimationPlayerCollection*
GetAnimationPlayers(dom::Element *aElement,
nsCSSPseudoElements::Type aPseudoType,
bool aCreateIfNeeded) = 0;
// Notify this manager that one of its collections of animation players,
// has been updated.
void NotifyCollectionUpdated(AnimationPlayerCollection& aCollection);
enum FlushFlags {
Can_Throttle,
Cannot_Throttle
@ -75,17 +86,34 @@ public:
nsCSSProperty aProperty,
nsStyleContext* aStyleContext,
mozilla::StyleAnimationValue& aComputedValue);
// For CSS properties that may be animated on a separate layer, represents
// a record of the corresponding layer type and change hint.
struct LayerAnimationRecord {
nsCSSProperty mProperty;
nsDisplayItem::Type mLayerType;
nsChangeHint mChangeHint;
};
protected:
static const size_t kLayerRecords = 2;
public:
static const LayerAnimationRecord sLayerAnimationInfo[kLayerRecords];
protected:
virtual ~CommonAnimationManager();
// For ElementCollectionRemoved
friend struct mozilla::AnimationPlayerCollection;
virtual void
AddElementCollection(AnimationPlayerCollection* aCollection) = 0;
virtual void ElementCollectionRemoved() = 0;
void AddElementCollection(AnimationPlayerCollection* aCollection);
void ElementCollectionRemoved() { CheckNeedsRefresh(); }
void RemoveAllElementCollections();
// Check to see if we should stop or start observing the refresh driver
void CheckNeedsRefresh();
// When this returns a value other than nullptr, it also,
// as a side-effect, notifies the ActiveLayerTracker.
static AnimationPlayerCollection*
@ -95,6 +123,7 @@ protected:
PRCList mElementCollections;
nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
bool mIsObservingRefreshDriver;
};
/**
@ -184,10 +213,6 @@ struct AnimationPlayerCollection : public PRCList
void Tick();
// This updates mNeedsRefreshes so the caller may need to check
// for changes to values (for example, nsAnimationManager provides
// CheckNeedsRefresh to register or unregister from observing the refresh
// driver when this value changes).
void EnsureStyleRuleFor(TimeStamp aRefreshTime, EnsureStyleRuleFlags aFlags);
bool CanThrottleTransformChanges(mozilla::TimeStamp aTime);
@ -274,6 +299,8 @@ struct AnimationPlayerCollection : public PRCList
}
}
void NotifyPlayerUpdated();
static void LogAsyncAnimationFailure(nsCString& aMessage,
const nsIContent* aContent = nullptr);

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

@ -28,17 +28,35 @@ using mozilla::dom::AnimationPlayer;
using mozilla::CSSAnimationPlayer;
void
CSSAnimationPlayer::Play(UpdateFlags aUpdateFlags)
CSSAnimationPlayer::Play()
{
mPauseShouldStick = false;
AnimationPlayer::Play(aUpdateFlags);
AnimationPlayer::Play();
}
void
CSSAnimationPlayer::Pause(UpdateFlags aUpdateFlags)
CSSAnimationPlayer::Pause()
{
mPauseShouldStick = true;
AnimationPlayer::Pause(aUpdateFlags);
AnimationPlayer::Pause();
}
mozilla::dom::AnimationPlayState
CSSAnimationPlayer::PlayStateFromJS() const
{
// Flush style to ensure that any properties controlling animation state
// (e.g. animation-play-state) are fully updated.
FlushStyle();
return AnimationPlayer::PlayStateFromJS();
}
void
CSSAnimationPlayer::PlayFromJS()
{
// Note that flushing style below might trigger calls to
// PlayFromStyle()/PauseFromStyle() on this object.
FlushStyle();
AnimationPlayer::PlayFromJS();
}
void
@ -46,7 +64,7 @@ CSSAnimationPlayer::PlayFromStyle()
{
mIsStylePaused = false;
if (!mPauseShouldStick) {
AnimationPlayer::Play(eNoUpdate);
DoPlay();
}
}
@ -59,7 +77,7 @@ CSSAnimationPlayer::PauseFromStyle()
}
mIsStylePaused = true;
AnimationPlayer::Pause(eNoUpdate);
DoPause();
}
void
@ -134,6 +152,17 @@ CSSAnimationPlayer::QueueEvents(EventArray& aEventsToDispatch)
}
}
CommonAnimationManager*
CSSAnimationPlayer::GetAnimationManager() const
{
nsPresContext* context = GetPresContext();
if (!context) {
return nullptr;
}
return context->AnimationManager();
}
/* static */ nsString
CSSAnimationPlayer::PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType)
{
@ -155,7 +184,6 @@ nsAnimationManager::UpdateStyleAndEvents(AnimationPlayerCollection*
{
aCollection->EnsureStyleRuleFor(aRefreshTime, aFlags);
QueueEvents(aCollection, mPendingEvents);
CheckNeedsRefresh();
}
void
@ -760,42 +788,6 @@ nsAnimationManager::WillRefresh(mozilla::TimeStamp aTime)
FlushAnimations(Can_Throttle);
}
void
nsAnimationManager::AddElementCollection(
AnimationPlayerCollection* aCollection)
{
if (!mObservingRefreshDriver) {
NS_ASSERTION(
static_cast<AnimationPlayerCollection*>(aCollection)->mNeedsRefreshes,
"Added data which doesn't need refreshing?");
// We need to observe the refresh driver.
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mObservingRefreshDriver = true;
}
PR_INSERT_BEFORE(aCollection, &mElementCollections);
}
void
nsAnimationManager::CheckNeedsRefresh()
{
for (PRCList *l = PR_LIST_HEAD(&mElementCollections);
l != &mElementCollections;
l = PR_NEXT_LINK(l)) {
if (static_cast<AnimationPlayerCollection*>(l)->mNeedsRefreshes) {
if (!mObservingRefreshDriver) {
mPresContext->RefreshDriver()->AddRefreshObserver(this, Flush_Style);
mObservingRefreshDriver = true;
}
return;
}
}
if (mObservingRefreshDriver) {
mObservingRefreshDriver = false;
mPresContext->RefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
}
}
void
nsAnimationManager::FlushAnimations(FlushFlags aFlags)
{

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

@ -63,8 +63,11 @@ public:
virtual CSSAnimationPlayer*
AsCSSAnimationPlayer() MOZ_OVERRIDE { return this; }
virtual void Play(UpdateFlags aUpdateFlags) MOZ_OVERRIDE;
virtual void Pause(UpdateFlags aUpdateFlags) MOZ_OVERRIDE;
virtual void Play() MOZ_OVERRIDE;
virtual void Pause() MOZ_OVERRIDE;
virtual dom::AnimationPlayState PlayStateFromJS() const MOZ_OVERRIDE;
virtual void PlayFromJS() MOZ_OVERRIDE;
void PlayFromStyle();
void PauseFromStyle();
@ -75,6 +78,7 @@ public:
protected:
virtual ~CSSAnimationPlayer() { }
virtual css::CommonAnimationManager* GetAnimationManager() const MOZ_OVERRIDE;
static nsString PseudoTypeAsString(nsCSSPseudoElements::Type aPseudoType);
@ -147,7 +151,6 @@ class nsAnimationManager MOZ_FINAL
public:
explicit nsAnimationManager(nsPresContext *aPresContext)
: mozilla::css::CommonAnimationManager(aPresContext)
, mObservingRefreshDriver(false)
{
}
@ -220,26 +223,13 @@ public:
}
}
mozilla::AnimationPlayerCollection*
virtual mozilla::AnimationPlayerCollection*
GetAnimationPlayers(mozilla::dom::Element *aElement,
nsCSSPseudoElements::Type aPseudoType,
bool aCreateIfNeeded);
bool aCreateIfNeeded) MOZ_OVERRIDE;
nsIStyleRule* GetAnimationRule(mozilla::dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType);
protected:
virtual void ElementCollectionRemoved() MOZ_OVERRIDE
{
CheckNeedsRefresh();
}
virtual void
AddElementCollection(mozilla::AnimationPlayerCollection* aData) MOZ_OVERRIDE;
/**
* Check to see if we should stop or start observing the refresh driver
*/
void CheckNeedsRefresh();
private:
void BuildAnimations(nsStyleContext* aStyleContext,
mozilla::dom::Element* aTarget,
@ -257,8 +247,6 @@ private:
void DoDispatchEvents();
mozilla::EventArray mPendingEvents;
bool mObservingRefreshDriver;
};
#endif /* !defined(nsAnimationManager_h_) */

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

@ -71,32 +71,38 @@ ElementPropertyTransition::CurrentValuePortion() const
}
/*****************************************************************************
* nsTransitionManager *
* CSSTransitionPlayer *
*****************************************************************************/
void
nsTransitionManager::ElementCollectionRemoved()
mozilla::dom::AnimationPlayState
CSSTransitionPlayer::PlayStateFromJS() const
{
// If we have no transitions or animations left, remove ourselves from
// the refresh driver.
if (PR_CLIST_IS_EMPTY(&mElementCollections)) {
mPresContext->RefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
}
FlushStyle();
return AnimationPlayer::PlayStateFromJS();
}
void
nsTransitionManager::AddElementCollection(
AnimationPlayerCollection* aCollection)
CSSTransitionPlayer::PlayFromJS()
{
if (PR_CLIST_IS_EMPTY(&mElementCollections)) {
// We need to observe the refresh driver.
nsRefreshDriver *rd = mPresContext->RefreshDriver();
rd->AddRefreshObserver(this, Flush_Style);
FlushStyle();
AnimationPlayer::PlayFromJS();
}
CommonAnimationManager*
CSSTransitionPlayer::GetAnimationManager() const
{
nsPresContext* context = GetPresContext();
if (!context) {
return nullptr;
}
PR_INSERT_BEFORE(aCollection, &mElementCollections);
return context->TransitionManager();
}
/*****************************************************************************
* nsTransitionManager *
*****************************************************************************/
already_AddRefed<nsIStyleRule>
nsTransitionManager::StyleContextChanged(dom::Element *aElement,
nsStyleContext *aOldStyleContext,
@ -166,7 +172,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
}
AnimationPlayerCollection* collection =
GetElementTransitions(aElement, pseudoType, false);
GetAnimationPlayers(aElement, pseudoType, false);
if (!collection &&
disp->mTransitionPropertyCount == 1 &&
disp->mTransitions[0].GetDelay() == 0.0f &&
@ -532,14 +538,13 @@ nsTransitionManager::ConsiderStartingTransition(
segment.mToKey = 1;
segment.mTimingFunction.Init(tf);
nsRefPtr<dom::AnimationPlayer> player = new dom::AnimationPlayer(timeline);
nsRefPtr<CSSTransitionPlayer> player = new CSSTransitionPlayer(timeline);
player->mStartTime = timeline->GetCurrentTime();
player->SetSource(pt);
if (!aElementTransitions) {
aElementTransitions =
GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
true);
GetAnimationPlayers(aElement, aNewStyleContext->GetPseudoType(), true);
if (!aElementTransitions) {
NS_WARNING("allocating CommonAnimationManager failed");
return;
@ -575,7 +580,7 @@ nsTransitionManager::ConsiderStartingTransition(
}
AnimationPlayerCollection*
nsTransitionManager::GetElementTransitions(
nsTransitionManager::GetAnimationPlayers(
dom::Element *aElement,
nsCSSPseudoElements::Type aPseudoType,
bool aCreateIfNeeded)
@ -631,7 +636,7 @@ nsTransitionManager::WalkTransitionRule(dom::Element* aElement,
nsRuleWalker* aRuleWalker)
{
AnimationPlayerCollection* collection =
GetElementTransitions(aElement, aPseudoType, false);
GetAnimationPlayers(aElement, aPseudoType, false);
if (!collection) {
return;
}

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

@ -11,6 +11,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/dom/Animation.h"
#include "mozilla/dom/AnimationPlayer.h"
#include "AnimationCommon.h"
#include "nsCSSPseudoElements.h"
@ -64,6 +65,26 @@ struct ElementPropertyTransition : public dom::Animation
double CurrentValuePortion() const;
};
class CSSTransitionPlayer MOZ_FINAL : public dom::AnimationPlayer
{
public:
explicit CSSTransitionPlayer(dom::AnimationTimeline* aTimeline)
: dom::AnimationPlayer(aTimeline)
{
}
virtual CSSTransitionPlayer*
AsCSSTransitionPlayer() MOZ_OVERRIDE { return this; }
virtual dom::AnimationPlayState PlayStateFromJS() const MOZ_OVERRIDE;
virtual void PlayFromJS() MOZ_OVERRIDE;
protected:
virtual ~CSSTransitionPlayer() { }
virtual css::CommonAnimationManager* GetAnimationManager() const MOZ_OVERRIDE;
};
} // namespace mozilla
class nsTransitionManager MOZ_FINAL
@ -144,19 +165,14 @@ public:
void FlushTransitions(FlushFlags aFlags);
AnimationPlayerCollection* GetElementTransitions(
mozilla::dom::Element *aElement,
nsCSSPseudoElements::Type aPseudoType,
bool aCreateIfNeeded);
virtual AnimationPlayerCollection*
GetAnimationPlayers(mozilla::dom::Element *aElement,
nsCSSPseudoElements::Type aPseudoType,
bool aCreateIfNeeded) MOZ_OVERRIDE;
void WalkTransitionRule(mozilla::dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
nsRuleWalker* aRuleWalker);
protected:
virtual void ElementCollectionRemoved() MOZ_OVERRIDE;
virtual void
AddElementCollection(AnimationPlayerCollection* aCollection) MOZ_OVERRIDE;
private:
void
ConsiderStartingTransition(nsCSSProperty aProperty,

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

@ -25,3 +25,20 @@ USE_STATIC_LIBS = True
DISABLE_STL_WRAPPING = True
DEFINES['MOZ_NO_MOZALLOC'] = True
# Suppress warnings in third-party code.
if CONFIG['GNU_CXX']:
CFLAGS += [
'-Wno-missing-braces',
'-Wno-pointer-to-int-cast',
'-Wno-sign-compare',
'-include stdio.h', # for sprintf() prototype
'-include unistd.h', # for getpid() prototype
]
elif CONFIG['_MSC_VER']:
CFLAGS += [
'-FI stdio.h', # for sprintf() prototype
'-wd4090', # '=' : different 'const' qualifiers
]
FAIL_ON_WARNINGS = True

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

@ -174,6 +174,7 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd)
reader->DiscardRemaining();
return;
}
uint8_t version = flags >> 24;
uint32_t sampleCount = reader->ReadU32();
if (sampleCount == 0) {
@ -194,7 +195,14 @@ Moof::ParseTrun(Box& aBox, Tfhd& aTfhd, Tfdt& aTfdt, Mdhd& aMdhd)
flags & 0x400 ? reader->ReadU32() : hasFirstSampleFlags && i == 0
? firstSampleFlags
: aTfhd.mDefaultSampleFlags;
uint32_t ctsOffset = flags & 0x800 ? reader->ReadU32() : 0;
int64_t ctsOffset = 0;
if (flags & 0x800) {
if (version == 0) {
ctsOffset = reader->ReadU32();
} else {
ctsOffset = reader->Read32();
}
}
Sample sample;
sample.mByteRange = MediaByteRange(offset, offset + sampleSize);

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

@ -76,6 +76,16 @@ public:
return mozilla::BigEndian::readUint32(ptr);
}
int64_t Read32()
{
auto ptr = Read(4);
if (!ptr) {
MOZ_ASSERT(false);
return 0;
}
return mozilla::BigEndian::readInt32(ptr);
}
uint64_t ReadU64()
{
auto ptr = Read(8);

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

@ -139,7 +139,7 @@ private:
off64_t offset;
uint32_t size;
uint32_t duration;
uint32_t ctsOffset;
int64_t ctsOffset;
uint32_t flags;
uint8_t iv[16];
Vector<uint16_t> clearsizes;
@ -2993,12 +2993,10 @@ status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
if (!mDataSource->getUInt32(offset, &flags)) {
return ERROR_MALFORMED;
}
uint8_t version = flags >> 24;
ALOGV("fragment run flags: %08x", flags);
// Some videos have the 0x01000000 flag (unknown) present, and ignoring
// it doesn't appear to affect playerback. Assume other flags in the high
// byte are invalid.
if (flags & 0xfe000000) {
if (version > 1) {
return -EINVAL;
}
@ -3127,7 +3125,11 @@ status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
tmp.offset = dataOffset;
tmp.size = sampleSize;
tmp.duration = sampleDuration;
tmp.ctsOffset = sampleCtsOffset;
if (version == 0) {
tmp.ctsOffset = sampleCtsOffset;
} else {
tmp.ctsOffset = (int32_t)sampleCtsOffset;
}
mCurrentSamples.add(tmp);
dataOffset += sampleSize;
@ -3609,7 +3611,7 @@ status_t MPEG4Source::fragmentedRead(
// If we're pointing to a segment type or sidx box then we skip them.
if (chunk_type != FOURCC('m', 'o', 'o', 'f')) {
moofOffset += chunk_size;
mNextMoofOffset += chunk_size;
continue;
}
mCurrentMoofOffset = moofOffset;
@ -3652,7 +3654,7 @@ status_t MPEG4Source::fragmentedRead(
off64_t offset = 0;
size_t size = 0;
uint32_t dts = 0;
uint32_t cts = 0;
int64_t cts = 0;
uint32_t duration = 0;
bool isSyncSample = false;
bool newBuffer = false;
@ -3743,7 +3745,7 @@ status_t MPEG4Source::fragmentedRead(
mBuffer->meta_data()->setInt64(
kKeyDecodingTime, ((int64_t)dts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
kKeyTime, (cts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyDuration, ((int64_t)duration * 1000000) / mTimescale);
@ -3872,7 +3874,7 @@ status_t MPEG4Source::fragmentedRead(
mBuffer->meta_data()->setInt64(
kKeyDecodingTime, ((int64_t)dts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
kKeyTime, (cts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyDuration, ((int64_t)duration * 1000000) / mTimescale);

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

@ -1771,7 +1771,7 @@ pref("font.mathfont-family", "Latin Modern Math, XITS Math, STIX Math, Cambria M
// These fonts are ignored the underline offset, instead of it, the underline is lowered to bottom of its em descent.
pref("font.blacklist.underline_offset", "FangSong,Gulim,GulimChe,MingLiU,MingLiU-ExtB,MingLiU_HKSCS,MingLiU-HKSCS-ExtB,MS Gothic,MS Mincho,MS PGothic,MS PMincho,MS UI Gothic,PMingLiU,PMingLiU-ExtB,SimHei,SimSun,SimSun-ExtB,Hei,Kai,Apple LiGothic,Apple LiSung,Osaka");
#ifdef MOZ_WIDGET_GONK
#ifdef MOZ_B2G
// Whitelist of fonts that ship with B2G that do not include space lookups in
// default features. This allows us to skip analyzing the GSUB/GPOS tables
// unless features are explicitly enabled.
@ -3345,166 +3345,6 @@ pref("print.print_extra_margin", 0); // twips
pref("layout.css.scroll-behavior.enabled", false);
pref("layout.css.scroll-behavior.property-enabled", false);
# ANDROID
#endif
#if defined(ANDROID) || defined(FXOS_SIMULATOR)
// font names
// Gonk (along with FxOS Simulator) and Android ship different sets of fonts
#if defined(MOZ_WIDGET_GONK) || defined(FXOS_SIMULATOR)
// TODO: some entries could probably be cleaned up.
// ar
pref("font.name.serif.el", "Droid Serif"); // not Charis SIL Compact, only has a few Greek chars
pref("font.name.sans-serif.el", "Fira Sans");
pref("font.name.monospace.el", "Fira Mono");
pref("font.name.serif.he", "Charis SIL Compact");
pref("font.name.sans-serif.he", "Fira Sans");
pref("font.name.monospace.he", "Fira Mono");
pref("font.name-list.sans-serif.he", "Droid Sans Hebrew, Fira Sans");
pref("font.name.serif.ja", "Charis SIL Compact");
pref("font.name.sans-serif.ja", "Fira Sans");
pref("font.name.monospace.ja", "MotoyaLMaru");
pref("font.name-list.sans-serif.ja", "Fira Sans, MotoyaLMaru, MotoyaLCedar, Droid Sans Japanese");
pref("font.name-list.monospace.ja", "MotoyaLMaru, MotoyaLCedar, Fira Mono");
pref("font.name.serif.ko", "Charis SIL Compact");
pref("font.name.sans-serif.ko", "Fira Sans");
pref("font.name.monospace.ko", "Fira Mono");
pref("font.name.serif.th", "Charis SIL Compact");
pref("font.name.sans-serif.th", "Fira Sans");
pref("font.name.monospace.th", "Fira Mono");
pref("font.name-list.sans-serif.th", "Fira Sans, Noto Sans Thai, Droid Sans Thai");
pref("font.name.serif.x-cyrillic", "Charis SIL Compact");
pref("font.name.sans-serif.x-cyrillic", "Fira Sans");
pref("font.name.monospace.x-cyrillic", "Fira Mono");
pref("font.name.serif.x-unicode", "Charis SIL Compact");
pref("font.name.sans-serif.x-unicode", "Fira Sans");
pref("font.name.monospace.x-unicode", "Fira Mono");
pref("font.name.serif.x-western", "Charis SIL Compact");
pref("font.name.sans-serif.x-western", "Fira Sans");
pref("font.name.monospace.x-western", "Fira Mono");
pref("font.name.serif.zh-CN", "Charis SIL Compact");
pref("font.name.sans-serif.zh-CN", "Fira Sans");
pref("font.name.monospace.zh-CN", "Fira Mono");
pref("font.name.serif.zh-HK", "Charis SIL Compact");
pref("font.name.sans-serif.zh-HK", "Fira Sans");
pref("font.name.monospace.zh-HK", "Fira Mono");
pref("font.name.serif.zh-TW", "Charis SIL Compact");
pref("font.name.sans-serif.zh-TW", "Fira Sans");
pref("font.name.monospace.zh-TW", "Fira Mono");
#else
// not MOZ_WIDGET_GONK / FXOS_SIMULATOR
// (i.e. this is Firefox for Android) - here, we use the bundled fonts
// ar
pref("font.name.serif.el", "Droid Serif"); // not Charis SIL Compact, only has a few Greek chars
pref("font.name.sans-serif.el", "Clear Sans");
pref("font.name.monospace.el", "Droid Sans Mono");
pref("font.name-list.sans-serif.el", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.he", "Droid Serif");
pref("font.name.sans-serif.he", "Clear Sans");
pref("font.name.monospace.he", "Droid Sans Mono");
pref("font.name-list.sans-serif.he", "Droid Sans Hebrew, Clear Sans, Droid Sans");
pref("font.name.serif.ja", "Charis SIL Compact");
pref("font.name.sans-serif.ja", "Clear Sans");
pref("font.name.monospace.ja", "MotoyaLMaru");
pref("font.name-list.serif.ja", "Droid Serif");
pref("font.name-list.sans-serif.ja", "Clear Sans, Roboto, Droid Sans, MotoyaLMaru, MotoyaLCedar, Droid Sans Japanese");
pref("font.name-list.monospace.ja", "MotoyaLMaru, MotoyaLCedar, Droid Sans Mono");
pref("font.name.serif.ko", "Charis SIL Compact");
pref("font.name.sans-serif.ko", "Clear Sans");
pref("font.name.monospace.ko", "Droid Sans Mono");
pref("font.name-list.serif.ko", "Droid Serif, HYSerif");
pref("font.name-list.sans-serif.ko", "SmartGothic, NanumGothic, DroidSansFallback, Droid Sans Fallback");
pref("font.name.serif.th", "Charis SIL Compact");
pref("font.name.sans-serif.th", "Clear Sans");
pref("font.name.monospace.th", "Droid Sans Mono");
pref("font.name-list.serif.th", "Droid Serif");
pref("font.name-list.sans-serif.th", "Droid Sans Thai, Clear Sans, Droid Sans");
pref("font.name.serif.x-cyrillic", "Charis SIL Compact");
pref("font.name.sans-serif.x-cyrillic", "Clear Sans");
pref("font.name.monospace.x-cyrillic", "Droid Sans Mono");
pref("font.name-list.serif.x-cyrillic", "Droid Serif");
pref("font.name-list.sans-serif.x-cyrillic", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.x-unicode", "Charis SIL Compact");
pref("font.name.sans-serif.x-unicode", "Clear Sans");
pref("font.name.monospace.x-unicode", "Droid Sans Mono");
pref("font.name-list.serif.x-unicode", "Droid Serif");
pref("font.name-list.sans-serif.x-unicode", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.x-western", "Charis SIL Compact");
pref("font.name.sans-serif.x-western", "Clear Sans");
pref("font.name.monospace.x-western", "Droid Sans Mono");
pref("font.name-list.serif.x-western", "Droid Serif");
pref("font.name-list.sans-serif.x-western", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.zh-CN", "Charis SIL Compact");
pref("font.name.sans-serif.zh-CN", "Clear Sans");
pref("font.name.monospace.zh-CN", "Droid Sans Mono");
pref("font.name-list.serif.zh-CN", "Droid Serif, Droid Sans Fallback");
pref("font.name-list.sans-serif.zh-CN", "Roboto, Droid Sans, Droid Sans Fallback");
pref("font.name-list.monospace.zh-CN", "Droid Sans Fallback");
pref("font.name.serif.zh-HK", "Charis SIL Compact");
pref("font.name.sans-serif.zh-HK", "Clear Sans");
pref("font.name.monospace.zh-HK", "Droid Sans Mono");
pref("font.name-list.serif.zh-HK", "Droid Serif, Droid Sans Fallback");
pref("font.name-list.sans-serif.zh-HK", "Roboto, Droid Sans, Droid Sans Fallback");
pref("font.name-list.monospace.zh-HK", "Droid Sans Fallback");
pref("font.name.serif.zh-TW", "Charis SIL Compact");
pref("font.name.sans-serif.zh-TW", "Clear Sans");
pref("font.name.monospace.zh-TW", "Droid Sans Mono");
pref("font.name-list.serif.zh-TW", "Droid Serif, Droid Sans Fallback");
pref("font.name-list.sans-serif.zh-TW", "Roboto, Droid Sans, Droid Sans Fallback");
pref("font.name-list.monospace.zh-TW", "Droid Sans Fallback");
// end ! (MOZ_WIDGET_GONK || FXOS_SIMULATOR)
#endif
pref("font.size.fixed.ar", 12);
pref("font.default.el", "sans-serif");
pref("font.size.fixed.el", 12);
pref("font.size.fixed.he", 12);
pref("font.default.x-cyrillic", "sans-serif");
pref("font.size.fixed.x-cyrillic", 12);
pref("font.default.x-unicode", "sans-serif");
pref("font.size.fixed.x-unicode", 12);
pref("font.default.x-western", "sans-serif");
pref("font.size.fixed.x-western", 12);
# ANDROID || FXOS_SIMUALTOR
#endif
#ifdef ANDROID
/* PostScript print module prefs */
// pref("print.postscript.enabled", true);
pref("print.postscript.paper_size", "letter");
@ -3655,6 +3495,157 @@ pref("intl.ime.use_simple_context_on_password_field", false);
#endif
#endif
#if defined(ANDROID) || defined(MOZ_B2G)
pref("font.size.fixed.ar", 12);
pref("font.default.el", "sans-serif");
pref("font.size.fixed.el", 12);
pref("font.size.fixed.he", 12);
pref("font.default.x-cyrillic", "sans-serif");
pref("font.size.fixed.x-cyrillic", 12);
pref("font.default.x-unicode", "sans-serif");
pref("font.size.fixed.x-unicode", 12);
pref("font.default.x-western", "sans-serif");
pref("font.size.fixed.x-western", 12);
# ANDROID || MOZ_B2G
#endif
#if defined(MOZ_B2G)
// Gonk, FxOS Simulator, B2G Desktop and Mulet.
// TODO: some entries could probably be cleaned up.
// ar
pref("font.name.serif.el", "Droid Serif"); // not Charis SIL Compact, only has a few Greek chars
pref("font.name.sans-serif.el", "Fira Sans");
pref("font.name.monospace.el", "Fira Mono");
pref("font.name.serif.he", "Charis SIL Compact");
pref("font.name.sans-serif.he", "Fira Sans");
pref("font.name.monospace.he", "Fira Mono");
pref("font.name-list.sans-serif.he", "Droid Sans Hebrew, Fira Sans");
pref("font.name.serif.ja", "Charis SIL Compact");
pref("font.name.sans-serif.ja", "Fira Sans");
pref("font.name.monospace.ja", "MotoyaLMaru");
pref("font.name-list.sans-serif.ja", "Fira Sans, MotoyaLMaru, MotoyaLCedar, Droid Sans Japanese");
pref("font.name-list.monospace.ja", "MotoyaLMaru, MotoyaLCedar, Fira Mono");
pref("font.name.serif.ko", "Charis SIL Compact");
pref("font.name.sans-serif.ko", "Fira Sans");
pref("font.name.monospace.ko", "Fira Mono");
pref("font.name.serif.th", "Charis SIL Compact");
pref("font.name.sans-serif.th", "Fira Sans");
pref("font.name.monospace.th", "Fira Mono");
pref("font.name-list.sans-serif.th", "Fira Sans, Noto Sans Thai, Droid Sans Thai");
pref("font.name.serif.x-cyrillic", "Charis SIL Compact");
pref("font.name.sans-serif.x-cyrillic", "Fira Sans");
pref("font.name.monospace.x-cyrillic", "Fira Mono");
pref("font.name.serif.x-unicode", "Charis SIL Compact");
pref("font.name.sans-serif.x-unicode", "Fira Sans");
pref("font.name.monospace.x-unicode", "Fira Mono");
pref("font.name.serif.x-western", "Charis SIL Compact");
pref("font.name.sans-serif.x-western", "Fira Sans");
pref("font.name.monospace.x-western", "Fira Mono");
pref("font.name.serif.zh-CN", "Charis SIL Compact");
pref("font.name.sans-serif.zh-CN", "Fira Sans");
pref("font.name.monospace.zh-CN", "Fira Mono");
pref("font.name.serif.zh-HK", "Charis SIL Compact");
pref("font.name.sans-serif.zh-HK", "Fira Sans");
pref("font.name.monospace.zh-HK", "Fira Mono");
pref("font.name.serif.zh-TW", "Charis SIL Compact");
pref("font.name.sans-serif.zh-TW", "Fira Sans");
pref("font.name.monospace.zh-TW", "Fira Mono");
#elif defined(ANDROID)
// We use the bundled fonts for Firefox for Android
// ar
pref("font.name.serif.el", "Droid Serif"); // not Charis SIL Compact, only has a few Greek chars
pref("font.name.sans-serif.el", "Clear Sans");
pref("font.name.monospace.el", "Droid Sans Mono");
pref("font.name-list.sans-serif.el", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.he", "Droid Serif");
pref("font.name.sans-serif.he", "Clear Sans");
pref("font.name.monospace.he", "Droid Sans Mono");
pref("font.name-list.sans-serif.he", "Droid Sans Hebrew, Clear Sans, Droid Sans");
pref("font.name.serif.ja", "Charis SIL Compact");
pref("font.name.sans-serif.ja", "Clear Sans");
pref("font.name.monospace.ja", "MotoyaLMaru");
pref("font.name-list.serif.ja", "Droid Serif");
pref("font.name-list.sans-serif.ja", "Clear Sans, Roboto, Droid Sans, MotoyaLMaru, MotoyaLCedar, Droid Sans Japanese");
pref("font.name-list.monospace.ja", "MotoyaLMaru, MotoyaLCedar, Droid Sans Mono");
pref("font.name.serif.ko", "Charis SIL Compact");
pref("font.name.sans-serif.ko", "Clear Sans");
pref("font.name.monospace.ko", "Droid Sans Mono");
pref("font.name-list.serif.ko", "Droid Serif, HYSerif");
pref("font.name-list.sans-serif.ko", "SmartGothic, NanumGothic, DroidSansFallback, Droid Sans Fallback");
pref("font.name.serif.th", "Charis SIL Compact");
pref("font.name.sans-serif.th", "Clear Sans");
pref("font.name.monospace.th", "Droid Sans Mono");
pref("font.name-list.serif.th", "Droid Serif");
pref("font.name-list.sans-serif.th", "Droid Sans Thai, Clear Sans, Droid Sans");
pref("font.name.serif.x-cyrillic", "Charis SIL Compact");
pref("font.name.sans-serif.x-cyrillic", "Clear Sans");
pref("font.name.monospace.x-cyrillic", "Droid Sans Mono");
pref("font.name-list.serif.x-cyrillic", "Droid Serif");
pref("font.name-list.sans-serif.x-cyrillic", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.x-unicode", "Charis SIL Compact");
pref("font.name.sans-serif.x-unicode", "Clear Sans");
pref("font.name.monospace.x-unicode", "Droid Sans Mono");
pref("font.name-list.serif.x-unicode", "Droid Serif");
pref("font.name-list.sans-serif.x-unicode", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.x-western", "Charis SIL Compact");
pref("font.name.sans-serif.x-western", "Clear Sans");
pref("font.name.monospace.x-western", "Droid Sans Mono");
pref("font.name-list.serif.x-western", "Droid Serif");
pref("font.name-list.sans-serif.x-western", "Clear Sans, Roboto, Droid Sans");
pref("font.name.serif.zh-CN", "Charis SIL Compact");
pref("font.name.sans-serif.zh-CN", "Clear Sans");
pref("font.name.monospace.zh-CN", "Droid Sans Mono");
pref("font.name-list.serif.zh-CN", "Droid Serif, Droid Sans Fallback");
pref("font.name-list.sans-serif.zh-CN", "Roboto, Droid Sans, Droid Sans Fallback");
pref("font.name-list.monospace.zh-CN", "Droid Sans Fallback");
pref("font.name.serif.zh-HK", "Charis SIL Compact");
pref("font.name.sans-serif.zh-HK", "Clear Sans");
pref("font.name.monospace.zh-HK", "Droid Sans Mono");
pref("font.name-list.serif.zh-HK", "Droid Serif, Droid Sans Fallback");
pref("font.name-list.sans-serif.zh-HK", "Roboto, Droid Sans, Droid Sans Fallback");
pref("font.name-list.monospace.zh-HK", "Droid Sans Fallback");
pref("font.name.serif.zh-TW", "Charis SIL Compact");
pref("font.name.sans-serif.zh-TW", "Clear Sans");
pref("font.name.monospace.zh-TW", "Droid Sans Mono");
pref("font.name-list.serif.zh-TW", "Droid Serif, Droid Sans Fallback");
pref("font.name-list.sans-serif.zh-TW", "Roboto, Droid Sans, Droid Sans Fallback");
pref("font.name-list.monospace.zh-TW", "Droid Sans Fallback");
#endif
#if OS_ARCH==AIX
// Override default Japanese fonts

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

@ -991,6 +991,10 @@ VARIABLES = {
"""List of manifest files defining mochitest tests.
""", None),
'MOCHITEST_WEBAPPRT_CONTENT_MANIFESTS': (StrictOrderingOnAppendList, list,
"""List of manifest files defining webapprt mochitest content tests.
""", None),
'MOCHITEST_WEBAPPRT_CHROME_MANIFESTS': (StrictOrderingOnAppendList, list,
"""List of manifest files defining webapprt mochitest chrome tests.
""", None),

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