Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2014-03-27 16:08:53 +01:00
commit 31adfc2eda
65 changed files with 1435 additions and 530 deletions

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="a9e08b91e9cd1f0930f16cfc49ec72f63575d5fe">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "5aec7ae12f4adb8518fb6d409fa1ea2dc7ea0c06",
"revision": "57c407d3e94ba322688b4bd121eda317806ab44e",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="cb16958e41105d7c551d9941f522db97b8312538"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="485846b2a40d8ac7d6c1c5f8af6d15b0c10af19d"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e909a131d5ae702b2befdbc165996f9930653171"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="287195d1fed2e6c883745d7091a4c05e56c4dbb7"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>

View File

@ -1315,6 +1315,8 @@ pref("browser.newtabpage.rows", 3);
// number of columns of newtab grid
pref("browser.newtabpage.columns", 3);
pref("browser.newtabpage.directorySource", "chrome://global/content/directoryLinks.json");
// Enable the DOM fullscreen API.
pref("full-screen-api.enabled", true);

View File

@ -36,7 +36,7 @@ endif
# Main rules (export, compile, binaries, libs and tools) call recurse_* rules.
# This wrapping is only really useful for build status.
compile binaries libs export tools::
$(call BUILDSTATUS,TIER_START $@ $($@_subtiers))
$(call BUILDSTATUS,TIER_START $@)
+$(MAKE) recurse_$@
$(call BUILDSTATUS,TIER_FINISH $@)
@ -77,11 +77,9 @@ endif
# Subtier delimiter rules
$(addprefix subtiers/,$(addsuffix _start/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_start/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_start))
$(call BUILDSTATUS,SUBTIER_START $(CURRENT_TIER) $* $(if $(BUG_915535_FIXED),$($(CURRENT_TIER)_subtier_$*)))
@$(STAMP_TOUCH)
$(addprefix subtiers/,$(addsuffix _finish/$(CURRENT_TIER),$(CURRENT_SUBTIERS))): subtiers/%_finish/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,subtiers/%_finish))
$(call BUILDSTATUS,SUBTIER_FINISH $(CURRENT_TIER) $*)
@$(STAMP_TOUCH)
$(addprefix subtiers/,$(addsuffix /$(CURRENT_TIER),$(CURRENT_SUBTIERS))): %/$(CURRENT_TIER): $(if $(WANT_STAMPS),$(call mkdir_deps,%))
@ -94,15 +92,9 @@ GARBAGE_DIRS += subtiers
# root.mk defines subtier_of_* variables, that map a normalized subdir path to
# a subtier name (e.g. subtier_of_memory_jemalloc = base)
$(addsuffix /$(CURRENT_TIER),$(CURRENT_DIRS)): %/$(CURRENT_TIER):
ifdef BUG_915535_FIXED
$(call BUILDSTATUS,TIERDIR_START $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
endif
+@$(MAKE) -C $* $(if $(filter $*,$(tier_$(subtier_of_$(subst /,_,$*))_staticdirs)),,$(CURRENT_TIER))
# Ensure existing stamps are up-to-date, but don't create one if submake didn't create one.
$(if $(wildcard $@),@$(STAMP_TOUCH))
ifdef BUG_915535_FIXED
$(call BUILDSTATUS,TIERDIR_FINISH $(CURRENT_TIER) $(subtier_of_$(subst /,_,$*)) $*)
endif
# Dummy rules for possibly inexisting dependencies for the above tier targets
$(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
@ -158,12 +150,10 @@ else
ifdef TIERS
libs export tools::
$(call BUILDSTATUS,TIER_START $@ $(filter-out $(if $(filter export,$@),,precompile),$(TIERS)))
$(call BUILDSTATUS,TIER_START $@)
$(foreach tier,$(TIERS), $(if $(filter-out libs_precompile tools_precompile,$@_$(tier)), \
$(call BUILDSTATUS,SUBTIER_START $@ $(tier) $(if $(filter libs,$@),$(tier_$(tier)_staticdirs)) $(tier_$(tier)_dirs)) \
$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@)) \
$(call BUILDSTATUS,SUBTIER_FINISH $@ $(tier))))
$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@))))
$(call BUILDSTATUS,TIER_FINISH $@)
else
@ -198,34 +188,24 @@ endif # ifeq ($(NO_RECURSE_MAKELEVEL),$(MAKELEVEL))
endif # ifeq (1_.,$(MOZ_PSEUDO_DERECURSE)_$(DEPTH))
ifdef MOZ_PSEUDO_DERECURSE
ifeq (.,$(DEPTH))
# top-level directories
ifndef JS_STANDALONE
# Only define recurse_targets for js, when it is built as part of gecko.
recurse_targets := $(addsuffix /binaries,$(call TIER_DIRS,binaries))
# we want to adjust paths for js/src.
want_abspaths = 1
endif
endif
ifdef COMPILE_ENVIRONMENT
# Aggregate all dependency files relevant to a binaries build except in
# the mozilla top-level directory.
ifneq (_.,$(recurse_targets)_$(DEPTH))
ifneq (.,$(DEPTH))
ALL_DEP_FILES := \
$(BINARIES_PP) \
$(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
$(TARGETS) \
$(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
))) \
$(recurse_targets) \
$(NULL)
endif
binaries libs:: $(TARGETS) $(BINARIES_PP)
ifneq (_.,$(recurse_targets)_$(DEPTH))
@$(if $(or $(recurse_targets),$^),$(call py_action,link_deps,-o binaries --group-all $(if $(want_abspaths),--abspaths )--topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
ifneq (.,$(DEPTH))
@$(if $^,$(call py_action,link_deps,-o binaries --group-all --topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
endif
endif

View File

@ -376,9 +376,7 @@ define SUBMAKE # $(call SUBMAKE,target,directory,static)
endef # The extra line is important here! don't delete it
define TIER_DIR_SUBMAKE
$(call BUILDSTATUS,TIERDIR_START $(1) $(2) $(3))
$(call SUBMAKE,$(4),$(3),$(5))
$(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3))
endef # Ths empty line is important.

View File

@ -2023,6 +2023,8 @@ GK_ATOM(DeleteTxnName, "Deleting")
GK_ATOM(Remote, "remote")
GK_ATOM(RemoteId, "_remote_id")
GK_ATOM(DisplayPort, "_displayport")
GK_ATOM(DisplayPortMargins, "_displayportmargins")
GK_ATOM(DisplayPortBase, "_displayportbase")
GK_ATOM(CriticalDisplayPort, "_critical_displayport")
// Names for system metrics

View File

@ -322,49 +322,6 @@ nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
return NS_OK;
}
static void
MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
{
if (aPresContext) {
nsIPresShell* presShell = aPresContext->GetPresShell();
bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
presShell->NotifyFontSizeInflationEnabledIsDirty();
bool changed = false;
if (presShell && presShell->FontSizeInflationEnabled() &&
presShell->FontSizeInflationMinTwips() != 0) {
aPresContext->ScreenWidthInchesForFontInflation(&changed);
}
changed = changed ||
(fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
if (changed) {
nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
if (docShell) {
nsCOMPtr<nsIContentViewer> cv;
docShell->GetContentViewer(getter_AddRefs(cv));
nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
if (mudv) {
nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
mudv->AppendSubtree(array);
for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
cv->GetPresShell(getter_AddRefs(shell));
if (shell) {
nsIFrame *rootFrame = shell->GetRootFrame();
if (rootFrame) {
shell->FrameNeedsReflow(rootFrame,
nsIPresShell::eStyleChange,
NS_FRAME_IS_DIRTY);
}
}
}
}
}
}
}
}
NS_IMETHODIMP
nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
float aWidthPx, float aHeightPx,
@ -380,11 +337,6 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
return NS_ERROR_FAILURE;
}
nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
nsPresContext::CSSPixelsToAppUnits(aYPx),
nsPresContext::CSSPixelsToAppUnits(aWidthPx),
nsPresContext::CSSPixelsToAppUnits(aHeightPx));
if (!aElement) {
return NS_ERROR_INVALID_ARG;
}
@ -405,25 +357,20 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
return NS_OK;
}
nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
nsPresContext::CSSPixelsToAppUnits(aYPx),
nsPresContext::CSSPixelsToAppUnits(aWidthPx),
nsPresContext::CSSPixelsToAppUnits(aHeightPx));
content->SetProperty(nsGkAtoms::DisplayPort,
new DisplayPortPropertyData(displayport, aPriority),
nsINode::DeleteProperty<DisplayPortPropertyData>);
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
if (rootScrollFrame) {
if (content == rootScrollFrame->GetContent()) {
// We are setting a root displayport for a document.
// The pres shell needs a special flag set.
presShell->SetIgnoreViewportScrolling(true);
// When the "font.size.inflation.minTwips" preference is set, the
// layout depends on the size of the screen. Since when the size
// of the screen changes, the root displayport also changes, we
// hook in the needed updates here rather than adding a
// separate notification just for this change.
nsPresContext* presContext = GetPresContext();
MaybeReflowForInflationScreenWidthChange(presContext);
}
if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
// We are setting a root displayport for a document.
// The pres shell needs a special flag set.
presShell->SetIgnoreViewportScrolling(true);
}
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
@ -452,6 +399,107 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
float aTopMargin,
float aRightMargin,
float aBottomMargin,
uint32_t aAlignment,
nsIDOMElement* aElement,
uint32_t aPriority)
{
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsIPresShell* presShell = GetPresShell();
if (!presShell) {
return NS_ERROR_FAILURE;
}
if (!aElement) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
if (!content) {
return NS_ERROR_INVALID_ARG;
}
if (content->GetCurrentDoc() != presShell->GetDocument()) {
return NS_ERROR_INVALID_ARG;
}
DisplayPortMarginsPropertyData* currentData =
static_cast<DisplayPortMarginsPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPortMargins));
if (currentData && currentData->mPriority > aPriority) {
return NS_OK;
}
// Note order change of arguments between our function signature and
// LayerMargin constructor.
LayerMargin displayportMargins(aTopMargin,
aRightMargin,
aBottomMargin,
aLeftMargin);
content->SetProperty(nsGkAtoms::DisplayPortMargins,
new DisplayPortMarginsPropertyData(displayportMargins, aAlignment, aPriority),
nsINode::DeleteProperty<DisplayPortMarginsPropertyData>);
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
// We are setting a root displayport for a document.
// The pres shell needs a special flag set.
presShell->SetIgnoreViewportScrolling(true);
}
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
if (rootFrame) {
rootFrame->SchedulePaint();
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
int32_t aY,
int32_t aWidth,
int32_t aHeight,
nsIDOMElement* aElement)
{
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsIPresShell* presShell = GetPresShell();
if (!presShell) {
return NS_ERROR_FAILURE;
}
if (!aElement) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
if (!content) {
return NS_ERROR_INVALID_ARG;
}
if (content->GetCurrentDoc() != presShell->GetDocument()) {
return NS_ERROR_INVALID_ARG;
}
content->SetProperty(nsGkAtoms::DisplayPortBase, new nsRect(aX, aY, aWidth, aHeight),
nsINode::DeleteProperty<nsRect>);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx,
float aWidthPx, float aHeightPx,
@ -3262,6 +3310,49 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugin
return NS_OK;
}
static void
MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
{
if (aPresContext) {
nsIPresShell* presShell = aPresContext->GetPresShell();
bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
presShell->NotifyFontSizeInflationEnabledIsDirty();
bool changed = false;
if (presShell && presShell->FontSizeInflationEnabled() &&
presShell->FontSizeInflationMinTwips() != 0) {
aPresContext->ScreenWidthInchesForFontInflation(&changed);
}
changed = changed ||
(fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
if (changed) {
nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
if (docShell) {
nsCOMPtr<nsIContentViewer> cv;
docShell->GetContentViewer(getter_AddRefs(cv));
nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
if (mudv) {
nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
mudv->AppendSubtree(array);
for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
cv->GetPresShell(getter_AddRefs(shell));
if (shell) {
nsIFrame *rootFrame = shell->GetRootFrame();
if (rootFrame) {
shell->FrameNeedsReflow(rootFrame,
nsIPresShell::eStyleChange,
NS_FRAME_IS_DIRTY);
}
}
}
}
}
}
}
}
NS_IMETHODIMP
nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
{
@ -3282,6 +3373,14 @@ nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aH
nsPresContext::CSSPixelsToAppUnits(aWidth),
nsPresContext::CSSPixelsToAppUnits(aHeight));
// When the "font.size.inflation.minTwips" preference is set, the
// layout depends on the size of the screen. Since when the size
// of the screen changes, the scroll position clamping scroll port
// size also changes, we hook in the needed updates here rather
// than adding a separate notification just for this change.
nsPresContext* presContext = GetPresContext();
MaybeReflowForInflationScreenWidthChange(presContext);
return NS_OK;
}

View File

@ -43,7 +43,7 @@ interface nsIDOMEventTarget;
interface nsIRunnable;
interface nsICompositionStringSynthesizer;
[scriptable, uuid(ef70a299-033c-4adc-b214-6649aed9d828)]
[scriptable, uuid(f3148b3e-6db8-4a49-aa5c-de726449054d)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -152,6 +152,38 @@ interface nsIDOMWindowUtils : nsISupports {
in float aWidthPx, in float aHeightPx,
in nsIDOMElement aElement,
in uint32_t aPriority);
/**
* An alternate way to represent a displayport rect as a set of margins and a
* base rect to apply those margins to. A consumer of pixels may ask for as
* many extra pixels as it would like in each direction. Layout then sets
* the base rect to the "visible rect" of the element, which is just the
* subrect of the element that is drawn (it does not take in account content
* covering the element).
*
* If both a displayport rect and displayport margins with corresponding base
* rect are set with the same priority then the margins will take precendence.
*
* Specifying an alignment value will ensure that after the base rect has
* been expanded by the displayport margins, it will be further expanded so
* that each edge is located at a multiple of the "alignment" value.
*
* Note that both the margin values and alignment are treated as values in
* LayerPixels. Refer to layout/base/Units.h for a description of this unit.
* The base rect values are in app units.
*/
void setDisplayPortMarginsForElement(in float aLeftMargin,
in float aTopMargin,
in float aRightMargin,
in float aBottomMargin,
in uint32_t aAlignment,
in nsIDOMElement aElement,
in uint32_t aPriority);
void setDisplayPortBaseForElement(in int32_t aX,
in int32_t aY,
in int32_t aWidth,
in int32_t aHeight,
in nsIDOMElement aElement);
/**
* When a display port is set, this allows a sub-section of that

View File

@ -244,6 +244,8 @@ TabChildBase::HandlePossibleViewportChange()
metrics.mCompositionBounds = ParentLayerIntRect(
ParentLayerIntPoint(),
ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot));
metrics.SetRootCompositionSize(
ScreenSize(mInnerSize) * ScreenToLayoutDeviceScale(1.0f) / metrics.mDevPixelsPerCSSPixel);
// This change to the zoom accounts for all types of changes I can conceive:
// 1. screen size changes, CSS viewport does not (pages with no meta viewport
@ -302,11 +304,12 @@ TabChildBase::HandlePossibleViewportChange()
// Calculate a display port _after_ having a scrollable rect because the
// display port is clamped to the scrollable rect.
metrics.mDisplayPort = AsyncPanZoomController::CalculatePendingDisplayPort(
metrics.SetDisplayPortMargins(AsyncPanZoomController::CalculatePendingDisplayPort(
// The page must have been refreshed in some way such as a new document or
// new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take.
metrics, ScreenPoint(0.0f, 0.0f), 0.0);
metrics, ScreenPoint(0.0f, 0.0f), 0.0));
metrics.SetUseDisplayPortMargins();
// Force a repaint with these metrics. This, among other things, sets the
// displayport, so we start with async painting.

View File

@ -280,7 +280,8 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
nsIXPConnect *xpc = nsContentUtils::XPConnect();
nsCOMPtr<nsIXPConnectJSObjectHolder> sandbox;
rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(sandbox));
// Important: Use a null principal here
rv = xpc->CreateSandbox(cx, nullptr, getter_AddRefs(sandbox));
NS_ENSURE_SUCCESS(rv, rv);
// The nsXPConnect sandbox API gives us a wrapper to the sandbox for

View File

@ -28,7 +28,7 @@ var ConsoleObserver = {
try {
let tab = gBrowser.selectedTab;
let browser = gBrowser.selectedBrowser;
let win = XPCNativeWrapper.unwrap(browser.contentWindow);
let win = browser.contentWindow;
let windowID = getWindowId(win);
let messages = ConsoleAPIStorage.getEvents(windowID);
ok(messages.length >= 4, "Some messages found in the storage service");
@ -56,6 +56,7 @@ var ConsoleObserver = {
} catch (ex) {
dump(ex + "\n\n\n");
dump(ex.stack + "\n\n\n");
ok(false, "We got an unexpected exception");
}
}
}
@ -88,7 +89,7 @@ function test()
browser.addEventListener("DOMContentLoaded", function onLoad(event) {
browser.removeEventListener("DOMContentLoaded", onLoad, false);
executeSoon(function test_executeSoon() {
let win = XPCNativeWrapper.unwrap(browser.contentWindow);
let win = browser.contentWindow;
win.console.log("this", "is", "a", "log message");
win.console.info("this", "is", "a", "info message");
win.console.warn("this", "is", "a", "warn message");

View File

@ -563,10 +563,10 @@ struct ParamTraits< mozilla::gfx::IntPointTyped<T> >
}
};
template<>
struct ParamTraits<mozilla::gfx::Size>
template<class T>
struct ParamTraits< mozilla::gfx::SizeTyped<T> >
{
typedef mozilla::gfx::Size paramType;
typedef mozilla::gfx::SizeTyped<T> paramType;
static void Write(Message* msg, const paramType& param)
{
@ -707,8 +707,11 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
WriteParam(aMsg, aParam.mViewport);
WriteParam(aMsg, aParam.mScrollOffset);
WriteParam(aMsg, aParam.mDisplayPort);
WriteParam(aMsg, aParam.mDisplayPortMargins);
WriteParam(aMsg, aParam.mUseDisplayPortMargins);
WriteParam(aMsg, aParam.mCriticalDisplayPort);
WriteParam(aMsg, aParam.mCompositionBounds);
WriteParam(aMsg, aParam.mRootCompositionSize);
WriteParam(aMsg, aParam.mScrollId);
WriteParam(aMsg, aParam.mResolution);
WriteParam(aMsg, aParam.mCumulativeResolution);
@ -730,8 +733,11 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
ReadParam(aMsg, aIter, &aResult->mViewport) &&
ReadParam(aMsg, aIter, &aResult->mScrollOffset) &&
ReadParam(aMsg, aIter, &aResult->mDisplayPort) &&
ReadParam(aMsg, aIter, &aResult->mDisplayPortMargins) &&
ReadParam(aMsg, aIter, &aResult->mUseDisplayPortMargins) &&
ReadParam(aMsg, aIter, &aResult->mCriticalDisplayPort) &&
ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
ReadParam(aMsg, aIter, &aResult->mRootCompositionSize) &&
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
ReadParam(aMsg, aIter, &aResult->mResolution) &&
ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) &&

View File

@ -85,6 +85,9 @@ public:
, mZoom(1)
, mUpdateScrollOffset(false)
, mScrollGeneration(0)
, mRootCompositionSize(0, 0)
, mDisplayPortMargins(0, 0, 0, 0)
, mUseDisplayPortMargins(false)
{}
// Default copy ctor and operator= are fine
@ -94,7 +97,10 @@ public:
// mContentDescription is not compared on purpose as it's only used
// for debugging.
return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) &&
mRootCompositionSize == aOther.mRootCompositionSize &&
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
mDisplayPortMargins == aOther.mDisplayPortMargins &&
mUseDisplayPortMargins == aOther.mUseDisplayPortMargins &&
mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) &&
mViewport.IsEqualEdges(aOther.mViewport) &&
mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
@ -376,7 +382,37 @@ public:
{
mScrollId = scrollId;
}
void SetRootCompositionSize(const CSSSize& aRootCompositionSize)
{
mRootCompositionSize = aRootCompositionSize;
}
const CSSSize& GetRootCompositionSize() const
{
return mRootCompositionSize;
}
void SetDisplayPortMargins(const LayerMargin& aDisplayPortMargins)
{
mDisplayPortMargins = aDisplayPortMargins;
}
const LayerMargin& GetDisplayPortMargins() const
{
return mDisplayPortMargins;
}
void SetUseDisplayPortMargins()
{
mUseDisplayPortMargins = true;
}
bool GetUseDisplayPortMargins() const
{
return mUseDisplayPortMargins;
}
private:
// New fields from now on should be made private and old fields should
// be refactored to be private.
@ -416,6 +452,17 @@ private:
// A description of the content element corresponding to this frame.
// This is empty unless the apz.printtree pref is turned on.
std::string mContentDescription;
// The size of the root scrollable's composition bounds, but in local CSS pixels.
CSSSize mRootCompositionSize;
// A display port expressed as layer margins that apply to the rect of what
// is drawn of the scrollable element.
LayerMargin mDisplayPortMargins;
// If this is true then we use the display port margins on this metrics,
// otherwise use the display port rect.
bool mUseDisplayPortMargins;
};
/**

View File

@ -19,6 +19,10 @@
#include "nsRegion.h" // for nsIntRegion
#include "nsTArray.h" // for nsTArray
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include <ui/Fence.h>
#endif
namespace mozilla {
namespace layers {
@ -206,6 +210,14 @@ public:
* returns that region. If it is not, an empty region will be returned.
*/
virtual const nsIntRegion& GetValidLowPrecisionRegion() const = 0;
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
/**
* Store a fence that will signal when the current buffer is no longer being read.
* Similar to android's GLConsumer::setReleaseFence()
*/
virtual void SetReleaseFence(const android::sp<android::Fence>& aReleaseFence) = 0;
#endif
};
// Normal integer division truncates towards zero,

View File

@ -64,6 +64,7 @@ SimpleTextureClientPool::GetTextureClient(bool aAutoRecycle)
RefPtr<TextureClient> textureClient;
if (mAvailableTextureClients.size()) {
textureClient = mAvailableTextureClients.top();
textureClient->WaitReleaseFence();
mAvailableTextureClients.pop();
RECYCLE_LOG("%s Skip allocate (%i left), returning %p\n", (mFormat == SurfaceFormat::B8G8R8A8?"poolA":"poolX"), mAvailableTextureClients.size(), textureClient.get());

View File

@ -79,6 +79,9 @@ private:
// when we shrink this list, we use pop(), but should use pop_back() to
// nuke the oldest.
// We may need to switch to a std::deque
// On b2g gonk, std::queue might be a better choice.
// On ICS, fence wait happens implicitly before drawing.
// Since JB, fence wait happens explicitly when fetching a client from the pool.
std::stack<RefPtr<TextureClient> > mAvailableTextureClients;
std::list<RefPtr<TextureClient> > mOutstandingTextureClients;

View File

@ -96,9 +96,17 @@ public:
bool Recv__delete__() MOZ_OVERRIDE;
bool RecvCompositorRecycle()
bool RecvCompositorRecycle(const MaybeFenceHandle& aFence)
{
RECYCLE_LOG("Receive recycle %p (%p)\n", mTextureClient, mWaitForRecycle.get());
if (aFence.type() != aFence.Tnull_t) {
FenceHandle fence = aFence.get_FenceHandle();
if (fence.IsValid() && mTextureClient) {
mTextureClient->SetReleaseFenceHandle(aFence);
// HWC might not provide Fence.
// In this case, HWC implicitly handles buffer's fence.
}
}
mWaitForRecycle = nullptr;
return true;
}

View File

@ -340,6 +340,13 @@ public:
return mReleaseFenceHandle;
}
/**
* Wait until the current buffer is no longer being read.
*
* Platform support is necessary. gonk JB supports this function.
*/
virtual void WaitReleaseFence() {}
private:
/**
* Called once, just before the destructor.

View File

@ -44,6 +44,7 @@ TextureClientPool::GetTextureClient()
RefPtr<TextureClient> textureClient;
if (mTextureClients.size()) {
textureClient = mTextureClients.top();
textureClient->WaitReleaseFence();
mTextureClients.pop();
return textureClient;
}

View File

@ -99,6 +99,9 @@ private:
uint32_t mOutstandingClients;
// On b2g gonk, std::queue might be a better choice.
// On ICS, fence wait happens implicitly before drawing.
// Since JB, fence wait happens explicitly when fetching a client from the pool.
std::stack<RefPtr<TextureClient> > mTextureClients;
std::stack<RefPtr<TextureClient> > mTextureClientsDeferred;
nsRefPtr<nsITimer> mTimer;

View File

@ -14,6 +14,7 @@
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
#ifdef MOZ_X11
#include "mozilla/layers/X11TextureHost.h"
#endif
@ -259,6 +260,15 @@ CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
return result;
}
void
TextureHost::CompositorRecycle()
{
if (!mActor) {
return;
}
static_cast<TextureParent*>(mActor)->CompositorRecycle();
}
void
TextureHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
{
@ -745,7 +755,20 @@ void
TextureParent::CompositorRecycle()
{
mTextureHost->ClearRecycleCallback();
mozilla::unused << SendCompositorRecycle();
MaybeFenceHandle handle = null_t();
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mTextureHost) {
TextureHostOGL* hostOGL = mTextureHost->AsHostOGL();
android::sp<android::Fence> fence = hostOGL->GetAndResetReleaseFence();
if (fence.get() && fence->isValid()) {
handle = FenceHandle(fence);
// HWC might not provide Fence.
// In this case, HWC implicitly handles buffer's fence.
}
}
#endif
mozilla::unused << SendCompositorRecycle(handle);
// Don't forget to prepare for the next reycle
mWaitForClientRecycle = mTextureHost;

View File

@ -287,6 +287,16 @@ public:
ISurfaceAllocator* aDeallocator,
TextureFlags aFlags);
/**
* Tell to TextureChild that TextureHost is recycled.
* This function should be called from TextureHost's RecycleCallback.
* If SetRecycleCallback is set to TextureHost.
* TextureHost can be recycled by calling RecycleCallback
* when reference count becomes one.
* One reference count is always added by TextureChild.
*/
void CompositorRecycle();
/**
* Lock the texture host for compositing.
*/

View File

@ -91,7 +91,10 @@ ThebesLayerComposite::GetLayer()
TiledLayerComposer*
ThebesLayerComposite::GetTiledLayerComposer()
{
MOZ_ASSERT(mBuffer && mBuffer->IsAttached());
if (!mBuffer) {
return nullptr;
}
MOZ_ASSERT(mBuffer->IsAttached());
return mBuffer->AsTiledLayerComposer();
}

View File

@ -9,6 +9,7 @@
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
#include "nsAString.h"
#include "nsDebug.h" // for NS_WARNING
#include "nsPoint.h" // for nsIntPoint
@ -31,6 +32,12 @@ TiledLayerBufferComposite::TiledLayerBufferComposite()
, mUninitialized(true)
{}
/* static */ void
TiledLayerBufferComposite::RecycleCallback(TextureHost* textureHost, void* aClosure)
{
textureHost->CompositorRecycle();
}
TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocator,
const SurfaceDescriptorTiles& aDescriptor,
const nsIntRegion& aOldPaintedRegion)
@ -56,6 +63,11 @@ TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocat
switch (tileDesc.type()) {
case TileDescriptor::TTexturedTileDescriptor : {
texture = TextureHost::AsTextureHost(tileDesc.get_TexturedTileDescriptor().textureParent());
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (!gfxPrefs::LayersUseSimpleTiles()) {
texture->SetRecycleCallback(RecycleCallback, nullptr);
}
#endif
const TileLock& ipcLock = tileDesc.get_TexturedTileDescriptor().sharedLock();
nsRefPtr<gfxSharedReadLock> sharedLock;
if (ipcLock.type() == TileLock::TShmemSection) {
@ -160,6 +172,23 @@ TiledLayerBufferComposite::SetCompositor(Compositor* aCompositor)
}
}
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
void
TiledLayerBufferComposite::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence)
{
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
if (!mRetainedTiles[i].mTextureHost) {
continue;
}
TextureHostOGL* texture = mRetainedTiles[i].mTextureHost->AsHostOGL();
if (!texture) {
continue;
}
texture->SetReleaseFence(new android::Fence(aReleaseFence->dup()));
}
}
#endif
TiledContentHost::TiledContentHost(const TextureInfo& aTextureInfo)
: ContentHost(aTextureInfo)
, mTiledBuffer(TiledLayerBufferComposite())

View File

@ -27,6 +27,10 @@
#include "nsRegion.h" // for nsIntRegion
#include "nscore.h" // for nsACString
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include <ui/Fence.h>
#endif
class gfxReusableSurfaceWrapper;
struct nsIntPoint;
struct nsIntRect;
@ -133,6 +137,14 @@ public:
bool IsValid() const { return !mUninitialized; }
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
virtual void SetReleaseFence(const android::sp<android::Fence>& aReleaseFence);
#endif
// Recycle callback for TextureHost.
// Used when TiledContentClient is present in client side.
static void RecycleCallback(TextureHost* textureHost, void* aClosure);
protected:
TileHost ValidateTile(TileHost aTile,
const nsIntPoint& aTileRect,
@ -243,6 +255,18 @@ public:
virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
/**
* Store a fence that will signal when the current buffer is no longer being read.
* Similar to android's GLConsumer::setReleaseFence()
*/
virtual void SetReleaseFence(const android::sp<android::Fence>& aReleaseFence)
{
mTiledBuffer.SetReleaseFence(aReleaseFence);
mLowPrecisionTiledBuffer.SetReleaseFence(aReleaseFence);
}
#endif
private:
void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
const nsIntRegion& aValidRegion,

View File

@ -66,12 +66,15 @@
// #define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__)
#define APZC_LOG_FM(fm, prefix, ...) \
APZC_LOG(prefix ":" \
" i=(%ld %lld) cb=(%d %d %d %d) dp=(%.3f %.3f %.3f %.3f) v=(%.3f %.3f %.3f %.3f) " \
"s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %llu)\n", \
" i=(%ld %lld) cb=(%d %d %d %d) rcs=(%.3f %.3f) dp=(%.3f %.3f %.3f %.3f) dpm=(%.3f %.3f %.3f %.3f) um=%d " \
"v=(%.3f %.3f %.3f %.3f) s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %llu)\n", \
__VA_ARGS__, \
fm.mPresShellId, fm.GetScrollId(), \
fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \
fm.GetRootCompositionSize().width, fm.GetRootCompositionSize().height, \
fm.mDisplayPort.x, fm.mDisplayPort.y, fm.mDisplayPort.width, fm.mDisplayPort.height, \
fm.mDisplayPortMargins.top, fm.mDisplayPortMargins.right, fm.mDisplayPortMargins.bottom, fm.mDisplayPortMargins.left, \
fm.mUseDisplayPortMargins ? 1 : 0, \
fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \
fm.GetScrollOffset().x, fm.GetScrollOffset().y, \
fm.mScrollableRect.x, fm.mScrollableRect.y, fm.mScrollableRect.width, fm.mScrollableRect.height, \
@ -1368,7 +1371,7 @@ void AsyncPanZoomController::ScaleWithFocus(float aScale,
* Enlarges the displayport along both axes based on the velocity.
*/
static CSSSize
CalculateDisplayPortSize(const CSSRect& aCompositionBounds,
CalculateDisplayPortSize(const CSSSize& aCompositionSize,
const CSSPoint& aVelocity)
{
float xMultiplier = fabsf(aVelocity.x) < gMinSkateSpeed
@ -1377,8 +1380,8 @@ CalculateDisplayPortSize(const CSSRect& aCompositionBounds,
float yMultiplier = fabsf(aVelocity.y) < gMinSkateSpeed
? gYStationarySizeMultiplier
: gYSkateSizeMultiplier;
return CSSSize(aCompositionBounds.width * xMultiplier,
aCompositionBounds.height * yMultiplier);
return CSSSize(aCompositionSize.width * xMultiplier,
aCompositionSize.height * yMultiplier);
}
/**
@ -1388,7 +1391,6 @@ CalculateDisplayPortSize(const CSSRect& aCompositionBounds,
*/
static void
RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize,
const CSSRect& aCompositionBounds,
const CSSRect& aScrollableRect)
{
float xSlack = std::max(0.0f, aDisplayPortSize.width - aScrollableRect.width);
@ -1408,21 +1410,25 @@ RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize,
}
/* static */
const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
const LayerMargin AsyncPanZoomController::CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const ScreenPoint& aVelocity,
double aEstimatedPaintDuration)
{
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
CSSSize compositionSize = aFrameMetrics.GetRootCompositionSize();
compositionSize =
CSSSize(std::min(compositionBounds.width, compositionSize.width),
std::min(compositionBounds.height, compositionSize.height));
CSSPoint velocity = aVelocity / aFrameMetrics.GetZoom();
CSSPoint scrollOffset = aFrameMetrics.GetScrollOffset();
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
// Calculate the displayport size based on how fast we're moving along each axis.
CSSSize displayPortSize = CalculateDisplayPortSize(compositionBounds, velocity);
CSSSize displayPortSize = CalculateDisplayPortSize(compositionSize, velocity);
if (gEnlargeDisplayPortWhenClipped) {
RedistributeDisplayPortExcess(displayPortSize, compositionBounds, scrollableRect);
RedistributeDisplayPortExcess(displayPortSize, scrollableRect);
}
// Offset the displayport, depending on how fast we're moving and the
@ -1432,9 +1438,9 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
CSSRect displayPort = CSSRect(scrollOffset + (velocity * paintFactor * gVelocityBias),
displayPortSize);
// Re-center the displayport based on its expansion over the composition bounds.
displayPort.MoveBy((compositionBounds.width - displayPort.width)/2.0f,
(compositionBounds.height - displayPort.height)/2.0f);
// Re-center the displayport based on its expansion over the composition size.
displayPort.MoveBy((compositionSize.width - displayPort.width)/2.0f,
(compositionSize.height - displayPort.height)/2.0f);
// Make sure the displayport remains within the scrollable rect.
displayPort = displayPort.ForceInside(scrollableRect) - scrollOffset;
@ -1444,7 +1450,15 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
displayPort.x, displayPort.y, displayPort.width, displayPort.height,
aVelocity.x, aVelocity.y, (float)estimatedPaintDurationMillis);
return displayPort;
CSSMargin cssMargins;
cssMargins.left = -displayPort.x;
cssMargins.top = -displayPort.y;
cssMargins.right = displayPort.width - compositionSize.width - cssMargins.left;
cssMargins.bottom = displayPort.height - compositionSize.height - cssMargins.top;
LayerMargin layerMargins = cssMargins * aFrameMetrics.LayersPixelsPerCSSPixel();
return layerMargins;
}
void AsyncPanZoomController::ScheduleComposite() {
@ -1464,10 +1478,11 @@ void AsyncPanZoomController::RequestContentRepaint() {
}
void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics) {
aFrameMetrics.mDisplayPort =
aFrameMetrics.SetDisplayPortMargins(
CalculatePendingDisplayPort(aFrameMetrics,
GetVelocityVector(),
mPaintThrottler.AverageDuration().ToSeconds());
mPaintThrottler.AverageDuration().ToSeconds()));
aFrameMetrics.SetUseDisplayPortMargins();
// If we're trying to paint what we already think is painted, discard this
// request since it's a pointless paint.
@ -1749,6 +1764,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
}
mFrameMetrics.mScrollableRect = aLayerMetrics.mScrollableRect;
mFrameMetrics.mCompositionBounds = aLayerMetrics.mCompositionBounds;
mFrameMetrics.SetRootCompositionSize(aLayerMetrics.GetRootCompositionSize());
mFrameMetrics.mResolution = aLayerMetrics.mResolution;
mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution;
mFrameMetrics.mHasScrollgrab = aLayerMetrics.mHasScrollgrab;
@ -1868,10 +1884,11 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
}
endZoomToMetrics.SetScrollOffset(aRect.TopLeft());
endZoomToMetrics.mDisplayPort =
endZoomToMetrics.SetDisplayPortMargins(
CalculatePendingDisplayPort(endZoomToMetrics,
ScreenPoint(0,0),
0);
0));
endZoomToMetrics.SetUseDisplayPortMargins();
StartAnimation(new ZoomAnimation(
mFrameMetrics.GetScrollOffset(),

View File

@ -238,7 +238,7 @@ public:
* checkerboard immediately. This includes a bunch of logic, including
* algorithms to bias painting in the direction of the velocity.
*/
static const CSSRect CalculatePendingDisplayPort(
static const LayerMargin CalculatePendingDisplayPort(
const FrameMetrics& aFrameMetrics,
const ScreenPoint& aVelocity,
double aEstimatedPaintDuration);

View File

@ -304,7 +304,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation
return true;
}
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
void
CompositableParentManager::ReturnTextureDataIfNecessary(CompositableHost* aCompositable,
EditReplyVector& replyv,

View File

@ -12,10 +12,16 @@ include protocol PGrallocBuffer;
include "mozilla/GfxMessageUtils.h";
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
namespace mozilla {
namespace layers {
union MaybeFenceHandle {
FenceHandle;
null_t;
};
/**
* PTexture is the IPDL glue between a TextureClient and a TextureHost.
*/
@ -25,7 +31,7 @@ sync protocol PTexture {
child:
async __delete__();
async CompositorRecycle();
async CompositorRecycle(MaybeFenceHandle aFence);
parent:

View File

@ -27,6 +27,7 @@
#include "mozilla/Preferences.h" // for Preferences
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Matrix.h" // for Matrix4x4, Matrix
#include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite, etc
#include "mozilla/layers/CompositingRenderTargetOGL.h"
#include "mozilla/layers/Effects.h" // for EffectChain, TexturedEffect, etc
#include "mozilla/layers/TextureHost.h" // for TextureSource, etc
@ -43,6 +44,7 @@
#include "DecomposeIntoNoRepeatTriangles.h"
#include "ScopedGLHelpers.h"
#include "GLReadTexImageHelper.h"
#include "TiledLayerBuffer.h" // for TiledLayerComposer
#if MOZ_ANDROID_OMTC
#include "TexturePoolOGL.h"
@ -1213,6 +1215,13 @@ CompositorOGL::EndFrame()
void
CompositorOGL::SetFBAcquireFence(Layer* aLayer)
{
// OpenGL does not provide ReleaseFence for rendering.
// Instead use FBAcquireFence as layer buffer's ReleaseFence
// to prevent flickering and tearing.
// FBAcquireFence is FramebufferSurface's AcquireFence.
// AcquireFence will be signaled when a buffer's content is available.
// See Bug 974152.
if (!aLayer) {
return;
}
@ -1222,7 +1231,7 @@ CompositorOGL::SetFBAcquireFence(Layer* aLayer)
return;
}
// Set FBAcquireFence to child
// Set FBAcquireFence on ContainerLayer's childs
ContainerLayer* container = aLayer->AsContainerLayer();
if (container) {
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
@ -1231,7 +1240,18 @@ CompositorOGL::SetFBAcquireFence(Layer* aLayer)
return;
}
// Set FBAcquireFence to TexutreHost
// Set FBAcquireFence as tiles' ReleaseFence on TiledLayerComposer.
TiledLayerComposer* composer = nullptr;
LayerComposite* shadow = aLayer->AsLayerComposite();
if (shadow) {
composer = shadow->GetTiledLayerComposer();
if (composer) {
composer->SetReleaseFence(new android::Fence(GetGonkDisplay()->GetPrevFBAcquireFd()));
return;
}
}
// Set FBAcquireFence as layer buffer's ReleaseFence
LayerRenderState state = aLayer->GetRenderState();
if (!state.mTexture) {
return;

View File

@ -187,6 +187,24 @@ GrallocTextureClientOGL::SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle)
}
}
void
GrallocTextureClientOGL::WaitReleaseFence()
{
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
if (mReleaseFenceHandle.IsValid()) {
android::sp<Fence> fence = mReleaseFenceHandle.mFence;
#if ANDROID_VERSION == 17
fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
// 1000 is what Android uses. It is warning timeout ms.
// This timeous is removed since ANDROID_VERSION 18.
#else
fence->waitForever("GrallocTextureClientOGL::Lock");
#endif
mReleaseFenceHandle = FenceHandle();
}
#endif
}
bool
GrallocTextureClientOGL::Lock(OpenMode aMode)
{
@ -199,18 +217,7 @@ GrallocTextureClientOGL::Lock(OpenMode aMode)
return true;
}
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
if (mReleaseFenceHandle.IsValid()) {
android::sp<Fence> fence = mReleaseFenceHandle.mFence;
#if ANDROID_VERSION == 17
fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
// 1000 is what Android uses. It is warning timeout ms.
#else
fence->waitForever("GrallocTextureClientOGL::Lock");
#endif
mReleaseFenceHandle = FenceHandle();
}
#endif
WaitReleaseFence();
uint32_t usage = 0;
if (aMode & OPEN_READ) {

View File

@ -63,10 +63,7 @@ public:
virtual void SetReleaseFenceHandle(FenceHandle aReleaseFenceHandle) MOZ_OVERRIDE;
const FenceHandle& GetReleaseFenceHandle() const
{
return mReleaseFenceHandle;
}
virtual void WaitReleaseFence() MOZ_OVERRIDE;
void InitWith(GrallocBufferActor* aActor, gfx::IntSize aSize);

View File

@ -74,7 +74,7 @@ protected:
};
class GrallocTextureHostOGL : public TextureHost
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
, public TextureHostOGL
#endif
{
@ -110,7 +110,7 @@ public:
return mTextureSource;
}
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
virtual TextureHostOGL* AsHostOGL() MOZ_OVERRIDE
{
return this;

View File

@ -197,11 +197,13 @@ CompositableDataGonkOGL::DeleteTextureIfPresent()
}
}
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
bool
TextureHostOGL::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence)
{
if (!aReleaseFence.get() || !aReleaseFence->isValid()) {
// HWC might not provide Fence.
// In this case, HWC implicitly handles buffer's fence.
return false;
}
@ -226,9 +228,11 @@ TextureHostOGL::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence
android::sp<android::Fence>
TextureHostOGL::GetAndResetReleaseFence()
{
android::sp<android::Fence> fence = mReleaseFence;
// Hold previous ReleaseFence to prevent Fence delivery failure via gecko IPC.
mPrevReleaseFence = mReleaseFence;
// Reset current ReleaseFence.
mReleaseFence = android::Fence::NO_FENCE;
return fence;
return mPrevReleaseFence;
}
#endif

View File

@ -157,7 +157,7 @@ private:
class TextureHostOGL
{
public:
#if MOZ_WIDGET_GONK && ANDROID_VERSION >= 17
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
/**
* Store a fence that will signal when the current buffer is no longer being read.
@ -169,8 +169,16 @@ public:
* Return a releaseFence's Fence and clear a reference to the Fence.
*/
virtual android::sp<android::Fence> GetAndResetReleaseFence();
protected:
android::sp<android::Fence> mReleaseFence;
/**
* Hold previous ReleaseFence to prevent Fence delivery failure via gecko IPC.
* Fence is a kernel object and its lifetime is managed by a reference count.
* Until the Fence is delivered to client side, need to hold Fence on host side.
*/
android::sp<android::Fence> mPrevReleaseFence;
#endif
};

View File

@ -638,6 +638,85 @@ static bool GetApzcTreePrintPref() {
return gPrintApzcTree;
}
static CSSSize
CalculateRootCompositionSize(FrameMetrics& aMetrics,
bool aIsRootContentDocRootScrollFrame,
nsPresContext* aPresContext,
nsIFrame* aForFrame, nsIFrame* aScrollFrame)
{
if (aIsRootContentDocRootScrollFrame) {
// convert from parent layer pixels to layer pixels to css pixels
return ParentLayerSize(aMetrics.mCompositionBounds.Size())
* aMetrics.mResolution / aMetrics.LayersPixelsPerCSSPixel();
}
ParentLayerIntSize rootCompositionSize;
nsPresContext* rootPresContext =
aPresContext->GetToplevelContentDocumentPresContext();
if (!rootPresContext) {
rootPresContext = aPresContext->GetRootPresContext();
}
nsIPresShell* rootPresShell = nullptr;
if (rootPresContext) {
nsIPresShell* rootPresShell = rootPresContext->PresShell();
if (nsIFrame* rootFrame = rootPresShell->GetRootFrame()) {
if (nsView* view = rootFrame->GetView()) {
nsIWidget* widget = view->GetWidget();
#ifdef MOZ_WIDGET_ANDROID
// Android hack - temporary workaround for bug 983208 until we figure
// out what a proper fix is.
if (!widget) {
widget = rootFrame->GetNearestWidget();
}
#endif
if (widget) {
nsIntRect bounds;
widget->GetBounds(bounds);
rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize(
bounds.width, bounds.height));
} else {
gfxSize res = rootPresShell->GetCumulativeResolution();
LayoutDeviceToParentLayerScale parentResolution(res.width);
int32_t rootAUPerDevPixel = rootPresContext->AppUnitsPerDevPixel();
nsRect viewBounds = view->GetBounds();
rootCompositionSize =
RoundedToInt(LayoutDeviceRect::FromAppUnits(viewBounds, rootAUPerDevPixel)
* parentResolution).Size();
}
}
}
} else {
nsIWidget* widget = (aScrollFrame ? aScrollFrame : aForFrame)->GetNearestWidget();
nsIntRect bounds;
widget->GetBounds(bounds);
rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize(
bounds.width, bounds.height));
}
LayoutDeviceToParentLayerScale parentResolution(1.0f);
if (rootPresShell) {
parentResolution.scale =
rootPresShell->GetCumulativeResolution().width / rootPresShell->GetResolution().width;
}
CSSSize size =
ParentLayerSize(rootCompositionSize) / (parentResolution * aMetrics.mDevPixelsPerCSSPixel);
// Adjust composition size for the size of scroll bars.
nsIFrame* rootRootScrollFrame = rootPresShell ? rootPresShell->GetRootScrollFrame() : nullptr;
nsIScrollableFrame* rootScrollableFrame = nullptr;
if (rootRootScrollFrame) {
rootScrollableFrame = aScrollFrame->GetScrollTargetFrame();
}
if (rootScrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
CSSMargin margins = CSSMargin::FromAppUnits(rootScrollableFrame->GetActualScrollbarSizes());
size.width -= margins.LeftRight();
size.height -= margins.TopBottom();
}
return size;
}
static void RecordFrameMetrics(nsIFrame* aForFrame,
nsIFrame* aScrollFrame,
const nsIFrame* aReferenceFrame,
@ -670,29 +749,11 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
if (aScrollFrame)
scrollableFrame = aScrollFrame->GetScrollTargetFrame();
metrics.mScrollableRect = CSSRect::FromAppUnits(
nsLayoutUtils::CalculateScrollableRectForFrame(scrollableFrame, aForFrame));
if (scrollableFrame) {
nsRect contentBounds = scrollableFrame->GetScrollRange();
nsPoint scrollPosition = scrollableFrame->GetScrollPosition();
// We ifndef the below code for Fennec because it requires special behaviour
// on the APZC side. Because Fennec has it's own PZC implementation which doesn't
// provide the special behaviour, this code will cause it to break. We can remove
// the ifndef once Fennec switches over to APZ or if we add the special handling
// to Fennec
#ifndef MOZ_WIDGET_ANDROID
if (scrollableFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.y = scrollPosition.y;
contentBounds.height = 0;
}
if (scrollableFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.x = scrollPosition.x;
contentBounds.width = 0;
}
#endif
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
contentBounds.height += scrollableFrame->GetScrollPortRect().height;
metrics.mScrollableRect = CSSRect::FromAppUnits(contentBounds);
metrics.SetScrollOffset(CSSPoint::FromAppUnits(scrollPosition));
// If the frame was scrolled since the last layers update, and by
@ -703,10 +764,6 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
metrics.SetScrollOffsetUpdated(scrollableFrame->CurrentScrollGeneration());
}
}
else {
nsRect contentBounds = aForFrame->GetRect();
metrics.mScrollableRect = CSSRect::FromAppUnits(contentBounds);
}
metrics.SetScrollId(aScrollId);
metrics.mIsRoot = aIsRoot;
@ -806,6 +863,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
metrics.mCompositionBounds.Deflate(boundMargins);
}
metrics.SetRootCompositionSize(
CalculateRootCompositionSize(metrics, isRootContentDocRootScrollFrame,
presContext, aForFrame, aScrollFrame));
if (GetApzcTreePrintPref()) {
if (nsIContent* content = frameForCompositionBoundsCalculation->GetContent()) {
nsAutoString contentDescription;

View File

@ -73,6 +73,7 @@
#include "ActiveLayerTracker.h"
#include "mozilla/gfx/2D.h"
#include "gfx2DGlue.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/Preferences.h"
@ -655,17 +656,120 @@ nsLayoutUtils::FindScrollableFrameFor(ViewID aId)
bool
nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
{
void* property = aContent->GetProperty(nsGkAtoms::DisplayPort);
if (!property) {
DisplayPortPropertyData* rectData =
static_cast<DisplayPortPropertyData*>(aContent->GetProperty(nsGkAtoms::DisplayPort));
DisplayPortMarginsPropertyData* marginsData =
static_cast<DisplayPortMarginsPropertyData*>(aContent->GetProperty(nsGkAtoms::DisplayPortMargins));
if (!rectData && !marginsData) {
return false;
}
if (aResult) {
*aResult = (static_cast<DisplayPortPropertyData*>(property))->mRect;
if (rectData && marginsData) {
// choose margins if equal priority
if (rectData->mPriority > marginsData->mPriority) {
marginsData = nullptr;
} else {
rectData = nullptr;
}
}
if (rectData) {
*aResult = rectData->mRect;
} else {
nsRect* baseData =
static_cast<nsRect*>(aContent->GetProperty(nsGkAtoms::DisplayPortBase));
nsRect base;
if (baseData) {
base = *baseData;
}
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
bool isRoot = false;
if (aContent->OwnerDoc()->GetRootElement() == aContent) {
// We want the scroll frame, the root scroll frame differs from all
// others in that the primary frame is not the scroll frame.
frame = frame->PresContext()->PresShell()->GetRootScrollFrame();
isRoot = true;
}
// first convert the base rect to layer pixels
nsPresContext* presContext = frame->PresContext();
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
gfxSize res = presContext->PresShell()->GetCumulativeResolution();
gfxSize parentRes = res;
if (isRoot) {
// the base rect for root scroll frames is specified in the parent document
// coordinate space, so it doesn't include the local resolution.
gfxSize localRes = presContext->PresShell()->GetResolution();
parentRes.width /= localRes.width;
parentRes.height /= localRes.height;
}
LayerRect rect;
rect.x = parentRes.width * NSAppUnitsToFloatPixels(base.x, auPerDevPixel);
rect.y = parentRes.height * NSAppUnitsToFloatPixels(base.y, auPerDevPixel);
rect.width =
parentRes.width * NSAppUnitsToFloatPixels(base.width, auPerDevPixel);
rect.height =
parentRes.height * NSAppUnitsToFloatPixels(base.height, auPerDevPixel);
rect.Inflate(marginsData->mMargins);
nsIScrollableFrame* scrollableFrame = frame->GetScrollTargetFrame();
nsPoint scrollPos(
scrollableFrame ? scrollableFrame->GetScrollPosition() : nsPoint(0,0));
if (marginsData->mAlignment > 0) {
LayerPoint scrollPosLayer(
res.width * NSAppUnitsToFloatPixels(scrollPos.x, auPerDevPixel),
res.height * NSAppUnitsToFloatPixels(scrollPos.y, auPerDevPixel));
rect += scrollPosLayer;
// Inflate the rectangle by 1 so that we always push to the next tile
// boundary. This is desirable to stop from having a rectangle with a
// moving origin occasionally being smaller when it coincidentally lines
// up to tile boundaries.
rect.Inflate(1);
float left =
marginsData->mAlignment * floor(rect.x / marginsData->mAlignment);
float top =
marginsData->mAlignment * floor(rect.y / marginsData->mAlignment);
float right =
marginsData->mAlignment * ceil(rect.XMost() / marginsData->mAlignment);
float bottom =
marginsData->mAlignment * ceil(rect.YMost() / marginsData->mAlignment);
rect = LayerRect(left, top, right - left, bottom - top);
rect -= scrollPosLayer;
}
nsRect result;
result.x = NSFloatPixelsToAppUnits(rect.x / res.width, auPerDevPixel);
result.y = NSFloatPixelsToAppUnits(rect.y / res.height, auPerDevPixel);
result.width =
NSFloatPixelsToAppUnits(rect.width / res.width, auPerDevPixel);
result.height =
NSFloatPixelsToAppUnits(rect.height / res.height, auPerDevPixel);
// Finally, clamp the display port to the expanded scrollable rect.
nsRect expandedScrollableRect = CalculateExpandedScrollableRect(frame);
result = expandedScrollableRect.Intersect(result + scrollPos) - scrollPos;
*aResult = result;
}
}
}
return true;
}
void
nsLayoutUtils::SetDisplayPortBase(nsIContent* aContent, const nsRect& aBase)
{
aContent->SetProperty(nsGkAtoms::DisplayPortBase, new nsRect(aBase),
nsINode::DeleteProperty<nsRect>);
}
bool
nsLayoutUtils::GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult)
{
@ -2279,7 +2383,12 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
if (rootScrollFrame && !aFrame->GetParent()) {
nsIContent* content = rootScrollFrame->GetContent();
if (content) {
usingDisplayPort = nsLayoutUtils::GetDisplayPort(content, &displayport);
usingDisplayPort = nsLayoutUtils::GetDisplayPort(content);
if (usingDisplayPort) {
nsLayoutUtils::SetDisplayPortBase(content,
nsRect(nsPoint(0,0), nsLayoutUtils::CalculateCompositionSizeForFrame(rootScrollFrame)));
nsLayoutUtils::GetDisplayPort(content, &displayport);
}
}
}
@ -5959,6 +6068,122 @@ nsLayoutUtils::UpdateImageVisibilityForFrame(nsIFrame* aImageFrame)
}
}
/* static */ nsSize
nsLayoutUtils::CalculateCompositionSizeForFrame(nsIFrame* aFrame)
{
nsSize size(aFrame->GetSize());
nsPresContext* presContext = aFrame->PresContext();
nsIPresShell* presShell = presContext->PresShell();
// For the root scroll frame of the root content document, the above calculation
// will yield the size of the viewport frame as the composition bounds, which
// doesn't actually correspond to what is visible when
// nsIDOMWindowUtils::setCSSViewport has been called to modify the visible area of
// the prescontext that the viewport frame is reflowed into. In that case if our
// document has a widget then the widget's bounds will correspond to what is
// visible. If we don't have a widget the root view's bounds correspond to what
// would be visible because they don't get modified by setCSSViewport.
bool isRootContentDocRootScrollFrame = presContext->IsRootContentDocument()
&& aFrame == presShell->GetRootScrollFrame();
if (isRootContentDocRootScrollFrame) {
if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
if (nsView* view = rootFrame->GetView()) {
nsIWidget* widget = view->GetWidget();
#ifdef MOZ_WIDGET_ANDROID
// Android hack - temporary workaround for bug 983208 until we figure
// out what a proper fix is.
if (!widget) {
widget = rootFrame->GetNearestWidget();
}
#endif
if (widget) {
nsIntRect bounds;
widget->GetBounds(bounds);
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
size = nsSize(bounds.width * auPerDevPixel,
bounds.height * auPerDevPixel);
} else {
nsRect viewBounds = view->GetBounds();
size = nsSize(viewBounds.width, viewBounds.height);
}
}
}
}
// Adjust composition bounds for the size of scroll bars.
nsIScrollableFrame* scrollableFrame = aFrame->GetScrollTargetFrame();
if (scrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
nsMargin margins = scrollableFrame->GetActualScrollbarSizes();
size.width -= margins.LeftRight();
size.height -= margins.TopBottom();
}
return size;
}
/* static */ nsRect
nsLayoutUtils::CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFrame, nsIFrame* aRootFrame)
{
nsRect contentBounds;
if (aScrollableFrame) {
contentBounds = aScrollableFrame->GetScrollRange();
// We ifndef the below code for Fennec because it requires special behaviour
// on the APZC side. Because Fennec has it's own PZC implementation which doesn't
// provide the special behaviour, this code will cause it to break. We can remove
// the ifndef once Fennec switches over to APZ or if we add the special handling
// to Fennec
#ifndef MOZ_WIDGET_ANDROID
nsPoint scrollPosition = aScrollableFrame->GetScrollPosition();
if (aScrollableFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.y = scrollPosition.y;
contentBounds.height = 0;
}
if (aScrollableFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
contentBounds.x = scrollPosition.x;
contentBounds.width = 0;
}
#endif
contentBounds.width += aScrollableFrame->GetScrollPortRect().width;
contentBounds.height += aScrollableFrame->GetScrollPortRect().height;
} else {
contentBounds = aRootFrame->GetRect();
}
return contentBounds;
}
/* static */ nsRect
nsLayoutUtils::CalculateExpandedScrollableRect(nsIFrame* aFrame)
{
nsRect scrollableRect =
CalculateScrollableRectForFrame(aFrame->GetScrollTargetFrame(),
aFrame->PresContext()->PresShell()->GetRootFrame());
nsSize compSize = CalculateCompositionSizeForFrame(aFrame);
if (aFrame == aFrame->PresContext()->PresShell()->GetRootScrollFrame()) {
// the composition size for the root scroll frame does not include the
// local resolution, so we adjust.
gfxSize res = aFrame->PresContext()->PresShell()->GetResolution();
compSize.width = NSToCoordRound(compSize.width / ((float) res.width));
compSize.height = NSToCoordRound(compSize.height / ((float) res.height));
}
if (scrollableRect.width < compSize.width) {
scrollableRect.x = std::max(0,
scrollableRect.x - (compSize.width - scrollableRect.width));
scrollableRect.width = compSize.width;
}
if (scrollableRect.height < compSize.height) {
scrollableRect.y = std::max(0,
scrollableRect.y - (compSize.height - scrollableRect.height));
scrollableRect.height = compSize.height;
}
return scrollableRect;
}
nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
// Use safe default values here
: mIsWriteOnly(true), mIsStillLoading(false), mCORSUsed(false)

View File

@ -85,6 +85,18 @@ struct DisplayPortPropertyData {
uint32_t mPriority;
};
struct DisplayPortMarginsPropertyData {
DisplayPortMarginsPropertyData(const LayerMargin& aMargins,
uint32_t aAlignment, uint32_t aPriority)
: mMargins(aMargins)
, mAlignment(aAlignment)
, mPriority(aPriority)
{}
LayerMargin mMargins;
uint32_t mAlignment;
uint32_t mPriority;
};
template <class AnimationsOrTransitions>
extern AnimationsOrTransitions* HasAnimationOrTransition(nsIContent* aContent,
nsIAtom* aAnimationProperty,
@ -138,6 +150,12 @@ public:
*/
static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult = nullptr);
/**
* Set the display port base rect for given element to be used with display
* port margins.
*/
static void SetDisplayPortBase(nsIContent* aContent, const nsRect& aBase);
/**
* Get the critical display port for the given element.
*/
@ -2054,6 +2072,29 @@ public:
static void
UpdateImageVisibilityForFrame(nsIFrame* aImageFrame);
/**
* Calculate the compostion size for a frame. See FrameMetrics.h for
* defintion of composition size (or bounds).
*/
static nsSize
CalculateCompositionSizeForFrame(nsIFrame* aFrame);
/**
* Calculate the scrollable rect for a frame. See FrameMetrics.h for
* defintion of scrollable rect. aScrollableFrame is the scroll frame to calculate
* the scrollable rect for. If it's null then we calculate the scrollable rect
* as the rect of the root frame.
*/
static nsRect
CalculateScrollableRectForFrame(nsIScrollableFrame* aScrollableFrame, nsIFrame* aRootFrame);
/**
* Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for
* defintion of expanded scrollable rect.
*/
static nsRect
CalculateExpandedScrollableRect(nsIFrame* aFrame);
private:
static uint32_t sFontSizeInflationEmPerLine;
static uint32_t sFontSizeInflationMinTwips;

View File

@ -2458,10 +2458,21 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsRect dirtyRect = aDirtyRect.Intersect(mScrollPort);
// Override the dirty rectangle if the displayport has been set.
nsRect displayPort;
bool usingDisplayport =
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort) &&
nsLayoutUtils::GetDisplayPort(mOuter->GetContent()) &&
!aBuilder->IsForEventDelivery();
// don't set the display port base rect for root scroll frames,
// nsLayoutUtils::PaintFrame or nsSubDocumentFrame::BuildDisplayList
// does that for root scroll frames before it expands the dirty rect
// to the display port.
if (usingDisplayport && !mIsRoot) {
nsLayoutUtils::SetDisplayPortBase(mOuter->GetContent(), dirtyRect);
}
// now that we have an updated base rect we can get the display port
nsRect displayPort;
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &displayPort);
if (usingDisplayport && DisplayportExceedsMaxTextureSize(mOuter->PresContext(), displayPort)) {
usingDisplayport = false;
}

View File

@ -376,18 +376,24 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
bool ignoreViewportScrolling = false;
nsIFrame* savedIgnoreScrollFrame = nullptr;
if (subdocRootFrame) {
nsRect displayPort;
if (nsLayoutUtils::ViewportHasDisplayPort(presContext, &displayPort)) {
haveDisplayPort = true;
dirty = displayPort;
} else {
// get the dirty rect relative to the root frame of the subdoc
dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame);
// and convert into the appunits of the subdoc
dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
}
// get the dirty rect relative to the root frame of the subdoc
dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame);
// and convert into the appunits of the subdoc
dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
if (nsLayoutUtils::ViewportHasDisplayPort(presContext)) {
haveDisplayPort = true;
// for root content documents we want the base to be the composition bounds
nsLayoutUtils::SetDisplayPortBase(rootScrollFrame->GetContent(),
presContext->IsRootContentDocument() ?
nsRect(nsPoint(0,0), nsLayoutUtils::CalculateCompositionSizeForFrame(rootScrollFrame)) :
dirty);
nsRect displayPort;
nsLayoutUtils::ViewportHasDisplayPort(presContext, &displayPort);
dirty = displayPort;
}
ignoreViewportScrolling =
rootScrollFrame && presShell->IgnoringViewportScrolling();
if (ignoreViewportScrolling) {

View File

@ -60,20 +60,12 @@ class TierStatus(object):
The build system is organized into linear phases called tiers. Each tier
executes in the order it was defined, 1 at a time.
Tiers can have subtiers. Subtiers can execute in any order. Some subtiers
execute sequentially. Others are concurrent.
Subtiers can have directories. Directories can execute in any order, just
like subtiers.
"""
def __init__(self, resources):
"""Accepts a SystemResourceMonitor to record results against."""
self.tiers = OrderedDict()
self.active_tier = None
self.active_subtiers = set()
self.active_dirs = {}
self.resources = resources
def set_tiers(self, tiers):
@ -83,98 +75,22 @@ class TierStatus(object):
begin_time=None,
finish_time=None,
duration=None,
subtiers=OrderedDict(),
)
def begin_tier(self, tier, subtiers):
def begin_tier(self, tier):
"""Record that execution of a tier has begun."""
t = self.tiers[tier]
# We should ideally use a monotonic clock here. Unfortunately, we won't
# have one until Python 3.
t['begin_time'] = time.time()
self.resources.begin_phase(self._phase(tier))
for subtier in subtiers:
t['subtiers'][subtier] = dict(
begin_time=None,
finish_time=None,
duration=None,
concurrent=False,
dirs=OrderedDict(),
dirs_complete=0,
)
self.resources.begin_phase(tier)
self.active_tier = tier
self.active_subtiers = set()
self.active_dirs = {}
def finish_tier(self, tier):
"""Record that execution of a tier has finished."""
t = self.tiers[tier]
t['finish_time'] = time.time()
t['duration'] = self.resources.finish_phase(self._phase(tier))
def begin_subtier(self, tier, subtier, dirs):
"""Record that execution of a subtier has begun."""
self.resources.begin_phase(self._phase(tier, subtier))
st = self.tiers[tier]['subtiers'][subtier]
st['begin_time'] = time.time()
for d in dirs:
st['dirs'][d] = dict(
begin_time=None,
finish_time=None,
duration=None,
concurrent=False,
)
if self.active_subtiers:
st['concurrent'] = True
self.active_subtiers.add(subtier)
def finish_subtier(self, tier, subtier):
"""Record that execution of a subtier has finished."""
st = self.tiers[tier]['subtiers'][subtier]
st['finish_time'] = time.time()
self.active_subtiers.remove(subtier)
if self.active_subtiers:
st['concurrent'] = True
# A subtier may not have directories.
try:
del self.active_dirs[subtier]
except KeyError:
pass
st['duration'] = self.resources.finish_phase(self._phase(tier, subtier))
def begin_dir(self, tier, subtier, d):
"""Record that execution of a directory has begun."""
self.resources.begin_phase(self._phase(tier, subtier, d))
entry = self.tiers[tier]['subtiers'][subtier]['dirs'][d]
entry['begin_time'] = time.time()
self.active_dirs.setdefault(subtier, set()).add(d)
if len(self.active_dirs[subtier]) > 1:
entry['concurrent'] = True
def finish_dir(self, tier, subtier, d):
"""Record that execution of a directory has finished."""
st = self.tiers[tier]['subtiers'][subtier]
st['dirs_complete'] += 1
entry = st['dirs'][d]
entry['finish_time'] = time.time()
self.active_dirs[subtier].remove(d)
if self.active_dirs[subtier]:
entry['concurrent'] = True
entry['duration'] = self.resources.finish_phase(self._phase(tier,
subtier, d))
t['duration'] = self.resources.finish_phase(tier)
def tier_status(self):
for tier, state in self.tiers.items():
@ -183,21 +99,6 @@ class TierStatus(object):
yield tier, active, finished
def current_subtier_status(self):
if self.active_tier not in self.tiers:
return
for subtier, state in self.tiers[self.active_tier]['subtiers'].items():
active = subtier in self.active_subtiers
finished = state['finish_time'] is not None
yield subtier, active, finished
def current_dirs_status(self):
for subtier, dirs in self.active_dirs.items():
st = self.tiers[self.active_tier]['subtiers'][subtier]
yield subtier, st['dirs'].keys(), dirs, st['dirs_complete']
def tiered_resource_usage(self):
"""Obtains an object containing resource usage for tiers.
@ -211,38 +112,9 @@ class TierStatus(object):
start=state['begin_time'],
end=state['finish_time'],
duration=state['duration'],
subtiers=[],
)
self.add_resources_to_dict(t_entry, phase=self._phase(tier))
for subtier, state in state['subtiers'].items():
st_entry = dict(
name=subtier,
start=state['begin_time'],
end=state['finish_time'],
duration=state['duration'],
concurrent=state['concurrent'],
dirs=[],
)
self.add_resources_to_dict(st_entry, phase=self._phase(tier,
subtier))
for d, state in state['dirs'].items():
d_entry = dict(
name=d,
start=state['begin_time'],
end=state['finish_time'],
duration=state['duration'],
)
self.add_resources_to_dict(d_entry, phase=self._phase(tier,
subtier, d))
st_entry['dirs'].append(d_entry)
t_entry['subtiers'].append(st_entry)
self.add_resources_to_dict(t_entry, phase=tier)
o.append(t_entry)
@ -276,15 +148,6 @@ class TierStatus(object):
return d
def _phase(self, tier, subtier=None, d=None):
parts = [tier]
if subtier:
parts.append(subtier)
if d:
parts.append(d)
return '_'.join(parts)
class BuildMonitor(MozbuildObject):
"""Monitors the output of the build."""
@ -356,24 +219,10 @@ class BuildMonitor(MozbuildObject):
update_needed = False
elif action == 'TIER_START':
tier = args[0]
subtiers = args[1:]
self.tiers.begin_tier(tier, subtiers)
self.tiers.begin_tier(tier)
elif action == 'TIER_FINISH':
tier, = args
self.tiers.finish_tier(tier)
elif action == 'SUBTIER_START':
tier, subtier = args[0:2]
dirs = args[2:]
self.tiers.begin_subtier(tier, subtier, dirs)
elif action == 'SUBTIER_FINISH':
tier, subtier = args
self.tiers.finish_subtier(tier, subtier)
elif action == 'TIERDIR_START':
tier, subtier, d = args
self.tiers.begin_dir(tier, subtier, d)
elif action == 'TIERDIR_FINISH':
tier, subtier, d = args
self.tiers.finish_dir(tier, subtier, d)
else:
raise Exception('Unknown build status: %s' % action)

View File

@ -153,42 +153,6 @@ class BuildProgressFooter(object):
else:
parts.extend([tier, ' '])
parts.extend([('bold', 'SUBTIER'), ':', ' '])
for subtier, active, finished in tiers.current_subtier_status():
if active:
parts.extend([('underline_yellow', subtier), ' '])
elif finished:
parts.extend([('green', subtier), ' '])
else:
parts.extend([subtier, ' '])
if tiers.active_dirs:
parts.extend([('bold', 'DIRECTORIES'), ': '])
have_dirs = False
for subtier, all_dirs, active_dirs, complete in tiers.current_dirs_status():
if len(all_dirs) < 2:
continue
have_dirs = True
parts.extend([
'%02d' % (complete + 1),
'/',
'%02d' % len(all_dirs),
' ',
'(',
])
if active_dirs:
commas = [', '] * (len(active_dirs) - 1)
magenta_dirs = [('magenta', d) for d in active_dirs]
parts.extend(i.next() for i in itertools.cycle((iter(magenta_dirs),
iter(commas))))
parts.append(')')
if not have_dirs:
parts = parts[0:-2]
# We don't want to write more characters than the current width of the
# terminal otherwise wrapping may result in weird behavior. We can't
# simply truncate the line at terminal width characters because a)

View File

@ -201,38 +201,6 @@ BuildResources.prototype = Object.freeze({
}
}
},
getSubtier: function (tier, subtier) {
var t = this.getTier(tier);
if (!t) {
return;
}
for (var i = 0; i < t.subtiers.length; i++) {
var entry = t.subtiers[i];
if (entry.name == subtier) {
return entry;
}
}
},
getDirectory: function (tier, subtier, directory) {
var st = this.getSubtier(tier, subtier);
if (!st) {
return;
}
for (var i = 0; i < st.dirs.length; i++) {
var entry = st.dirs[i];
if (entry.name == directory) {
return entry;
}
}
},
});
function updateResourcesGraph() {
@ -391,8 +359,8 @@ function renderResources(id, resources, what) {
.call(yAxis)
;
// Now we render a timeline of sorts of the tiers, subtiers, and directories.
// There are 3 rows of rectangles that visualize divisions between the
// Now we render a timeline of sorts of the tiers
// There is a row of rectangles that visualize divisions between the
// different items. We use the same x scale as the resource graph so times
// line up properly.
svg = d3.select("#" + id).append("svg")
@ -418,73 +386,14 @@ function renderResources(id, resources, what) {
.attr("class", "timeline tier")
.attr("tier", t)
;
tier.subtiers.forEach(function (subtier) {
var x_start = x(subtier.start - resources.offset);
var x_end = x(subtier.end - resources.offset);
var draw_width = x_end - x_start;
var classes = "timeline subtier";
if (draw_width < 6) {
classes += " short";
}
svg.append("rect")
.attr("x", x_start)
.attr("y", 60)
.attr("height", 30)
.attr("width", draw_width)
.attr("class", classes)
.attr("tier", t)
.attr("subtier", subtier.name)
;
subtier.dirs.forEach(function (dir) {
var x_start = x(dir.start - resources.offset);
var x_end = x(dir.end - resources.offset);
var draw_width = x_end - x_start;
var classes = "timeline directory";
if (draw_width < 6) {
classes += " short";
}
svg.append("rect")
.attr("x", x_start)
.attr("y", 100)
.attr("height", 30)
.attr("width", draw_width)
.attr("class", classes)
.attr("tier", t)
.attr("subtier", subtier.name)
.attr("directory", dir.name)
;
});
});
});
function getEntry(element) {
var tier = element.getAttribute("tier");
var subtier = element.getAttribute("subtier");
var directory = element.getAttribute("directory");
var entry = resources.getTier(tier);
entry.tier = tier;
if (subtier) {
entry = resources.getSubtier(tier, subtier);
entry.tier = tier;
entry.subtier = subtier;
}
if (directory) {
entry = resources.getDirectory(tier, subtier, directory);
entry.tier = tier;
entry.subtier = subtier;
entry.directory = directory;
}
return entry;
}
@ -493,8 +402,6 @@ function renderResources(id, resources, what) {
var entry = getEntry(this);
d3.select("#tt_tier").html(entry.tier);
d3.select("#tt_subtier").html(entry.subtier || "n/a");
d3.select("#tt_directory").html(entry.directory || "n/a");
d3.select("#tt_duration").html(entry.duration || "n/a");
d3.select("#tt_cpu_percent").html(entry.cpu_percent || "n/a");
@ -536,8 +443,6 @@ document.addEventListener("DOMContentLoaded", function() {
<div id="tooltip" style="display: none;">
<table border="0">
<tr><td>Tier</td><td id="tt_tier"></td></tr>
<tr><td>Subtier</td><td id="tt_subtier"></td></tr>
<tr><td>Directory</td><td id="tt_directory"></td></tr>
<tr><td>Duration</td><td id="tt_duration"></td></tr>
<tr><td>CPU %</td><td id="tt_cpu_percent"></td></tr>
</table>

File diff suppressed because one or more lines are too long

View File

@ -39,6 +39,7 @@ toolkit.jar:
* content/global/customizeToolbar.js (customizeToolbar.js)
content/global/customizeToolbar.xul (customizeToolbar.xul)
content/global/devicestorage.properties (devicestorage.properties)
content/global/directoryLinks.json (directoryLinks.json)
content/global/editMenuOverlay.js (editMenuOverlay.js)
*+ content/global/editMenuOverlay.xul (editMenuOverlay.xul)
content/global/finddialog.js (finddialog.js)

View File

@ -165,11 +165,12 @@ ProfilerActor.prototype = {
}
/*
* If these values are objects with a non-null 'wrappedJSObject'
* property, use its value. Otherwise, use the value unchanged.
* If these values are objects with a non-null 'wrappedJSObject' property
* and aren't Xrays, use their .wrappedJSObject. Otherwise, use the value
* unchanged.
*/
aSubject = (aSubject && aSubject.wrappedJSObject) || aSubject;
aData = (aData && aData.wrappedJSObject) || aData;
aSubject = (aSubject && !Cu.isXrayWrapper(aSubject) && aSubject.wrappedJSObject) || aSubject;
aData = (aData && !Cu.isXrayWrapper(aData) && aData.wrappedJSObject) || aData;
let subj = JSON.parse(JSON.stringify(aSubject, cycleBreaker));
let data = JSON.parse(JSON.stringify(aData, cycleBreaker));

View File

@ -448,10 +448,7 @@ function ThreadActor(aHooks, aGlobal)
this._state = "detached";
this._frameActors = [];
this._hooks = aHooks;
this.global = this.globalSafe = aGlobal;
if (aGlobal && aGlobal.wrappedJSObject) {
this.global = aGlobal.wrappedJSObject;
}
this.global = aGlobal;
// A map of actorID -> actor for breakpoints created and managed by the server.
this._hiddenBreakpoints = new Map();
@ -1818,7 +1815,7 @@ ThreadActor.prototype = {
// Clear DOM event breakpoints.
// XPCShell tests don't use actual DOM windows for globals and cause
// removeListenerForAllEvents to throw.
if (this.globalSafe && !this.globalSafe.toString().contains("Sandbox")) {
if (this.global && !this.global.toString().contains("Sandbox")) {
let els = Cc["@mozilla.org/eventlistenerservice;1"]
.getService(Ci.nsIEventListenerService);
els.removeListenerForAllEvents(this.global, this._allEventsListener, true);

View File

@ -6,6 +6,7 @@
const { Cu } = require("chrome");
const { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
Cu.import("resource://gre/modules/jsdebugger.jsm");
addDebuggerToGlobal(this);
@ -91,7 +92,13 @@ function TraceActor(aConn, aParentActor)
this._buffer = [];
this.onExitFrame = this.onExitFrame.bind(this);
this.global = aParentActor.window.wrappedJSObject;
// aParentActor.window might be an Xray for a window, but it might also be a
// double-wrapper for a Sandbox. We want to unwrap the latter but not the
// former.
this.global = aParentActor.window;
if (!Cu.isXrayWrapper(this.global)) {
this.global = this.global.wrappedJSObject;
}
}
TraceActor.prototype = {

View File

@ -228,7 +228,7 @@ BrowserTabList.prototype.getList = function() {
// For each tab in this XUL window, ensure that we have an actor for
// it, reusing existing actors where possible. We actually iterate
// over 'browser' XUL elements, and BrowserTabActor uses
// browser.contentWindow.wrappedJSObject as the debuggee global.
// browser.contentWindow as the debuggee global.
for (let browser of this._getChildren(win)) {
// Do we have an existing actor for this browser? If not, create one.
let actor = this._actorByBrowser.get(browser);
@ -912,7 +912,7 @@ TabActor.prototype = {
this.threadActor.clearDebuggees();
if (this.threadActor.dbg) {
this.threadActor.dbg.enabled = true;
this.threadActor.global = evt.target.defaultView.wrappedJSObject;
this.threadActor.global = evt.target.defaultView;
this.threadActor.maybePauseOnExceptions();
}
}

View File

@ -296,6 +296,8 @@ WebConsoleActor.prototype =
hasNativeConsoleAPI: function WCA_hasNativeConsoleAPI(aWindow) {
let isNative = false;
try {
// We are very explicitly examining the "console" property of
// the non-Xrayed object here.
let console = aWindow.wrappedJSObject.console;
isNative = console instanceof aWindow.Console;
}

View File

@ -0,0 +1,196 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["DirectoryLinksProvider"];
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
/**
* Gets the currently selected locale for display.
* @return the selected locale or "en-US" if none is selected
*/
function getLocale() {
let matchOS;
try {
matchOS = Services.prefs.getBoolPref(PREF_MATCH_OS_LOCALE);
}
catch (e) {}
if (matchOS) {
return Services.locale.getLocaleComponentForUserAgent();
}
try {
let locale = Services.prefs.getComplexValue(PREF_SELECTED_LOCALE,
Ci.nsIPrefLocalizedString);
if (locale) {
return locale.data;
}
}
catch (e) {}
try {
return Services.prefs.getCharPref(PREF_SELECTED_LOCALE);
}
catch (e) {}
return "en-US";
}
// The preference that tells whether to match the OS locale
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
// The preference that tells what locale the user selected
const PREF_SELECTED_LOCALE = "general.useragent.locale";
// The preference that tells where to obtain directory links
const PREF_DIRECTORY_SOURCE = "browser.newtabpage.directorySource";
// The frecency of a directory link
const DIRECTORY_FRECENCY = 1000;
/**
* Singleton that serves as the provider of directory links.
* Directory links are a hard-coded set of links shown if a user's link
* inventory is empty.
*/
let DirectoryLinksProvider = {
__linksURL: null,
_observers: [],
get _prefs() Object.freeze({
linksURL: PREF_DIRECTORY_SOURCE,
matchOSLocale: PREF_MATCH_OS_LOCALE,
prefSelectedLocale: PREF_SELECTED_LOCALE,
}),
get _linksURL() {
if (!this.__linksURL) {
try {
this.__linksURL = Services.prefs.getCharPref(this._prefs["linksURL"]);
}
catch (e) {
Cu.reportError("Error fetching directory links url from prefs: " + e);
}
}
return this.__linksURL;
},
observe: function DirectoryLinksProvider_observe(aSubject, aTopic, aData) {
if (aTopic == "nsPref:changed") {
if (aData == this._prefs["linksURL"]) {
delete this.__linksURL;
}
this._callObservers("onManyLinksChanged");
}
},
_addPrefsObserver: function DirectoryLinksProvider_addObserver() {
for (let pref in this._prefs) {
let prefName = this._prefs[pref];
Services.prefs.addObserver(prefName, this, false);
}
},
_removePrefsObserver: function DirectoryLinksProvider_removeObserver() {
for (let pref in this._prefs) {
let prefName = this._prefs[pref];
Services.prefs.removeObserver(prefName, this);
}
},
/**
* Fetches the current set of directory links.
* @param aCallback a callback that is provided a set of links.
*/
_fetchLinks: function DirectoryLinksProvider_fetchLinks(aCallback) {
try {
NetUtil.asyncFetch(this._linksURL, (aInputStream, aResult, aRequest) => {
let output;
if (Components.isSuccessCode(aResult)) {
try {
let json = NetUtil.readInputStreamToString(aInputStream,
aInputStream.available(),
{charset: "UTF-8"});
let locale = getLocale();
output = JSON.parse(json)[locale];
}
catch (e) {
Cu.reportError(e);
}
}
else {
Cu.reportError(new Error("the fetch of " + this._linksURL + "was unsuccessful"));
}
aCallback(output || []);
});
}
catch (e) {
Cu.reportError(e);
aCallback([]);
}
},
/**
* Gets the current set of directory links.
* @param aCallback The function that the array of links is passed to.
*/
getLinks: function DirectoryLinksProvider_getLinks(aCallback) {
this._fetchLinks(rawLinks => {
// all directory links have a frecency of DIRECTORY_FRECENCY
aCallback(rawLinks.map((link, position) => {
link.frecency = DIRECTORY_FRECENCY;
link.lastVisitDate = rawLinks.length - position;
return link;
}));
});
},
init: function DirectoryLinksProvider_init() {
this._addPrefsObserver();
},
/**
* Return the object to its pre-init state
*/
reset: function DirectoryLinksProvider_reset() {
delete this.__linksURL;
this._removePrefsObserver();
this._removeObservers();
},
addObserver: function DirectoryLinksProvider_addObserver(aObserver) {
this._observers.push(aObserver);
},
_callObservers: function DirectoryLinksProvider__callObservers(aMethodName, aArg) {
for (let obs of this._observers) {
if (typeof(obs[aMethodName]) == "function") {
try {
obs[aMethodName](this, aArg);
} catch (err) {
Cu.reportError(err);
}
}
}
},
_removeObservers: function() {
while (this._observers.length) {
this._observers.pop();
}
}
};

View File

@ -17,6 +17,7 @@ EXTRA_JS_MODULES += [
'DeferredTask.jsm',
'Deprecated.jsm',
'Dict.jsm',
'DirectoryLinksProvider.jsm',
'FileUtils.jsm',
'Finder.jsm',
'Geometry.jsm',

View File

@ -0,0 +1,152 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
/**
* This file tests the DirectoryLinksProvider singleton in the DirectoryLinksProvider.jsm module.
*/
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DirectoryLinksProvider.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
const DIRECTORY_FRECENCY = 1000;
const kTestSource = 'data:application/json,{"en-US": [{"url":"http://example.com","title":"TestSource"}]}';
function isIdentical(actual, expected) {
if (expected == null) {
do_check_eq(actual, expected);
}
else if (typeof expected == "object") {
// Make sure all the keys match up
do_check_eq(Object.keys(actual).sort() + "", Object.keys(expected).sort());
// Recursively check each value individually
Object.keys(expected).forEach(key => {
isIdentical(actual[key], expected[key]);
});
}
else {
do_check_eq(actual, expected);
}
}
function fetchData(provider) {
let deferred = Promise.defer();
provider.getLinks(linkData => {
deferred.resolve(linkData);
});
return deferred.promise;
}
function run_test() {
run_next_test();
}
add_task(function test_DirectoryLinksProvider__linkObservers() {
let deferred = Promise.defer();
let testObserver = {
onManyLinksChanged: function() {
deferred.resolve();
}
}
let provider = DirectoryLinksProvider;
provider.init();
provider.addObserver(testObserver);
do_check_eq(provider._observers.length, 1);
Services.prefs.setCharPref(provider._prefs['linksURL'], kTestSource);
yield deferred.promise;
provider._removeObservers();
do_check_eq(provider._observers.length, 0);
provider.reset();
Services.prefs.clearUserPref(provider._prefs['linksURL']);
});
add_task(function test_DirectoryLinksProvider__linksURL_locale() {
let data = {
"en-US": [{url: "http://example.com", title: "US"}],
"zh-CN": [
{url: "http://example.net", title: "CN"},
{url:"http://example.net/2", title: "CN2"}
],
};
let dataURI = 'data:application/json,' + JSON.stringify(data);
let provider = DirectoryLinksProvider;
Services.prefs.setCharPref(provider._prefs['linksURL'], dataURI);
Services.prefs.setCharPref('general.useragent.locale', 'en-US');
// set up the observer
provider.init();
do_check_eq(provider._linksURL, dataURI);
let links;
let expected_data;
links = yield fetchData(provider);
do_check_eq(links.length, 1);
expected_data = [{url: "http://example.com", title: "US", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
isIdentical(links, expected_data);
Services.prefs.setCharPref('general.useragent.locale', 'zh-CN');
links = yield fetchData(provider);
do_check_eq(links.length, 2)
expected_data = [
{url: "http://example.net", title: "CN", frecency: DIRECTORY_FRECENCY, lastVisitDate: 2},
{url: "http://example.net/2", title: "CN2", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}
];
isIdentical(links, expected_data);
provider.reset();
Services.prefs.clearUserPref('general.useragent.locale');
Services.prefs.clearUserPref(provider._prefs['linksURL']);
});
add_task(function test_DirectoryLinksProvider__prefObserver_url() {
let provider = DirectoryLinksProvider;
Services.prefs.setCharPref('general.useragent.locale', 'en-US');
Services.prefs.setCharPref(provider._prefs['linksURL'], kTestSource);
// set up the observer
provider.init();
do_check_eq(provider._linksURL, kTestSource);
let links = yield fetchData(provider);
do_check_eq(links.length, 1);
let expectedData = [{url: "http://example.com", title: "TestSource", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}];
isIdentical(links, expectedData);
// tests these 2 things:
// 1. observer trigger on pref change
// 2. invalid source url
let exampleUrl = 'http://example.com/bad';
Services.prefs.setCharPref(provider._prefs['linksURL'], exampleUrl);
do_check_eq(provider._linksURL, exampleUrl);
let newLinks = yield fetchData(provider);
isIdentical(newLinks, []);
provider.reset();
Services.prefs.clearUserPref('general.useragent.locale')
Services.prefs.clearUserPref(provider._prefs['linksURL']);
});
add_task(function test_DirectoryLinksProvider_getLinks_noLocaleData() {
let provider = DirectoryLinksProvider;
Services.prefs.setCharPref('general.useragent.locale', 'zh-CN');
Services.prefs.setCharPref(provider._prefs['linksURL'], kTestSource);
let links = yield fetchData(provider);
do_check_eq(links.length, 0);
provider.reset();
Services.prefs.clearUserPref('general.useragent.locale')
Services.prefs.clearUserPref(provider._prefs['linksURL']);
});

View File

@ -10,6 +10,7 @@ support-files =
[test_AsyncShutdown.js]
[test_DeferredTask.js]
[test_dict.js]
[test_DirectoryLinksProvider.js]
[test_FileUtils.js]
[test_Http.js]
[test_Log.js]

View File

@ -49,8 +49,17 @@ public:
virtual void UpdateFBSurface(EGLDisplay dpy, EGLSurface sur) = 0;
/**
* Set FramebufferSurface ReleaseFence's file descriptor.
* ReleaseFence will be signaled after the HWC has finished reading
* from a buffer.
*/
virtual void SetFBReleaseFd(int fd) = 0;
/**
* Get FramebufferSurface AcquireFence's file descriptor
* AcquireFence will be signaled when a buffer's content is available.
*/
virtual int GetPrevFBAcquireFd() = 0;
float xdpi;

View File

@ -67,33 +67,52 @@ MaybeAlignAndClampDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics,
{
// Correct the display-port by the difference between the requested scroll
// offset and the resulting scroll offset after setting the requested value.
CSSRect& displayPort = aFrameMetrics.mDisplayPort;
displayPort += aFrameMetrics.GetScrollOffset() - aActualScrollOffset;
if (!aFrameMetrics.GetUseDisplayPortMargins()) {
CSSRect& displayPort = aFrameMetrics.mDisplayPort;
displayPort += aFrameMetrics.GetScrollOffset() - aActualScrollOffset;
// Expand the display port to the next tile boundaries, if tiled thebes layers
// are enabled.
if (gfxPrefs::LayersTilesEnabled()) {
// We don't use LayersPixelsPerCSSPixel() here as mCumulativeResolution on
// this FrameMetrics may be incorrect (and is about to be reset by mZoom).
displayPort =
ExpandDisplayPortToTileBoundaries(displayPort + aActualScrollOffset,
aFrameMetrics.GetZoom() *
ScreenToLayerScale(1.0))
- aActualScrollOffset;
// Expand the display port to the next tile boundaries, if tiled thebes layers
// are enabled.
if (gfxPrefs::LayersTilesEnabled()) {
// We don't use LayersPixelsPerCSSPixel() here as mCumulativeResolution on
// this FrameMetrics may be incorrect (and is about to be reset by mZoom).
displayPort =
ExpandDisplayPortToTileBoundaries(displayPort + aActualScrollOffset,
aFrameMetrics.GetZoom() *
ScreenToLayerScale(1.0))
- aActualScrollOffset;
}
// Finally, clamp the display port to the expanded scrollable rect.
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
displayPort = scrollableRect.Intersect(displayPort + aActualScrollOffset)
- aActualScrollOffset;
} else {
LayerPoint shift =
(aFrameMetrics.GetScrollOffset() - aActualScrollOffset) *
aFrameMetrics.LayersPixelsPerCSSPixel();
LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
margins.left -= shift.x;
margins.right += shift.x;
margins.top -= shift.y;
margins.bottom += shift.y;
aFrameMetrics.SetDisplayPortMargins(margins);
}
// Finally, clamp the display port to the expanded scrollable rect.
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
displayPort = scrollableRect.Intersect(displayPort + aActualScrollOffset)
- aActualScrollOffset;
}
static void
RecenterDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics)
{
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
aFrameMetrics.mDisplayPort.x = (compositionBounds.width - aFrameMetrics.mDisplayPort.width) / 2;
aFrameMetrics.mDisplayPort.y = (compositionBounds.height - aFrameMetrics.mDisplayPort.height) / 2;
if (!aFrameMetrics.GetUseDisplayPortMargins()) {
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
aFrameMetrics.mDisplayPort.x = (compositionBounds.width - aFrameMetrics.mDisplayPort.width) / 2;
aFrameMetrics.mDisplayPort.y = (compositionBounds.height - aFrameMetrics.mDisplayPort.height) / 2;
} else {
LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
margins.right = margins.left = margins.LeftRight() / 2;
margins.top = margins.bottom = margins.TopBottom() / 2;
aFrameMetrics.SetDisplayPortMargins(margins);
}
}
static CSSPoint
@ -205,11 +224,29 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
if (!element) {
return;
}
aUtils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
aMetrics.mDisplayPort.y,
aMetrics.mDisplayPort.width,
aMetrics.mDisplayPort.height,
element, 0);
if (!aMetrics.GetUseDisplayPortMargins()) {
aUtils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
aMetrics.mDisplayPort.y,
aMetrics.mDisplayPort.width,
aMetrics.mDisplayPort.height,
element, 0);
} else {
uint32_t alignment = gfxPrefs::LayersTilesEnabled()
? TILEDLAYERBUFFER_TILE_SIZE : 1;
LayerMargin margins = aMetrics.GetDisplayPortMargins();
aUtils->SetDisplayPortMarginsForElement(margins.left,
margins.top,
margins.right,
margins.bottom,
alignment,
element, 0);
CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),
baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(),
baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
nsLayoutUtils::SetDisplayPortBase(content, base);
}
}
void
@ -240,11 +277,29 @@ APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
RecenterDisplayPort(aMetrics);
}
MaybeAlignAndClampDisplayPort(aMetrics, actualScrollOffset);
utils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
aMetrics.mDisplayPort.y,
aMetrics.mDisplayPort.width,
aMetrics.mDisplayPort.height,
element, 0);
if (!aMetrics.GetUseDisplayPortMargins()) {
utils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
aMetrics.mDisplayPort.y,
aMetrics.mDisplayPort.width,
aMetrics.mDisplayPort.height,
element, 0);
} else {
uint32_t alignment = gfxPrefs::LayersTilesEnabled()
? TILEDLAYERBUFFER_TILE_SIZE : 1;
LayerMargin margins = aMetrics.GetDisplayPortMargins();
utils->SetDisplayPortMarginsForElement(margins.left,
margins.top,
margins.right,
margins.bottom,
alignment,
element, 0);
CSSRect baseCSS = aMetrics.mCompositionBounds / aMetrics.GetZoomToParent();
nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(),
baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(),
baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(),
baseCSS.height * nsPresContext::AppUnitsPerCSSPixel());
nsLayoutUtils::SetDisplayPortBase(aContent, base);
}
}
aMetrics.SetScrollOffset(actualScrollOffset);