Bug 1351783 part 10 - Create and sync the current FocusTarget on each layer transaction. r=kats,botond

This commit modifies PresShell and nsDisplayList to send a FocusTarget update on
every layer transaction. Ideally we would like to send updates as often as possible,
but this seems like it works well. This can be iterated on later, if necessary.

MozReview-Commit-ID: 8PFqIOhzH77

--HG--
extra : rebase_source : 1e2c3b5620f5d7e6e789848da57b2486c3d74f14
This commit is contained in:
Ryan Hunt 2017-06-13 02:00:49 -04:00
Родитель 3332ba9ac0
Коммит a6a2b4f7c4
15 изменённых файлов: 146 добавлений и 10 удалений

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

@ -97,6 +97,7 @@ class ReadbackLayer;
class ReadbackProcessor;
class RefLayer;
class HostLayer;
class FocusTarget;
class KnowsCompositor;
class ShadowableLayer;
class ShadowLayerForwarder;
@ -599,6 +600,11 @@ public:
*/
virtual void SetIsFirstPaint() {}
/**
* Set the current focus target to be sent with the next paint.
*/
virtual void SetFocusTarget(const FocusTarget& aFocusTarget) {}
/**
* Make sure that the previous transaction has been entirely
* completed.

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

@ -129,5 +129,22 @@ FocusTarget::FocusTarget(nsIPresShell* aRootPresShell)
nsLayoutUtils::FindIDForScrollableFrame(vertical);
}
bool
FocusTarget::operator==(const FocusTarget& aRhs) const
{
if (mFocusHasKeyEventListeners != aRhs.mFocusHasKeyEventListeners ||
mType != aRhs.mType) {
return false;
}
if (mType == FocusTarget::eRefLayer) {
return mData.mRefLayerId == aRhs.mData.mRefLayerId;
} else if (mType == FocusTarget::eScrollLayer) {
return mData.mScrollTargets.mHorizontal == aRhs.mData.mScrollTargets.mHorizontal &&
mData.mScrollTargets.mVertical == aRhs.mData.mScrollTargets.mVertical;
}
return true;
}
} // namespace layers
} // namespace mozilla

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

@ -52,6 +52,8 @@ public:
*/
FocusTarget(nsIPresShell* aRootPresShell);
bool operator==(const FocusTarget& aRhs) const;
public:
// Whether there are keydown, keypress, or keyup event listeners
// in the event target chain of the focused element

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

@ -811,6 +811,12 @@ ClientLayerManager::SetIsFirstPaint()
mForwarder->SetIsFirstPaint();
}
void
ClientLayerManager::SetFocusTarget(const FocusTarget& aFocusTarget)
{
mForwarder->SetFocusTarget(aFocusTarget);
}
void
ClientLayerManager::ClearCachedResources(Layer* aSubtree)
{

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

@ -14,6 +14,7 @@
#include "mozilla/WidgetUtils.h" // for ScreenRotation
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/FocusTarget.h" // for FocusTarget
#include "mozilla/layers/LayersTypes.h" // for BufferMode, LayersBackend, etc
#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder, etc
#include "mozilla/layers/APZTestData.h" // for APZTestData
@ -133,6 +134,8 @@ public:
virtual void SetIsFirstPaint() override;
virtual void SetFocusTarget(const FocusTarget& aFocusTarget) override;
/**
* Pass through call to the forwarder for nsPresContext's
* CollectPluginGeometryUpdates. Passes widget configuration information

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

@ -859,6 +859,7 @@ CompositorBridgeParent::UpdatePaintTime(LayerTransactionParent* aLayerTree,
void
CompositorBridgeParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint,
const FocusTarget& aFocusTarget,
bool aScheduleComposite, uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction, bool aHitTestUpdate)
{
@ -879,9 +880,13 @@ CompositorBridgeParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstP
}
#endif
if (mApzcTreeManager && aHitTestUpdate) {
mApzcTreeManager->UpdateHitTestingTree(mRootLayerTreeID,
mLayerManager->GetRoot(), aIsFirstPaint, aId, aPaintSequenceNumber);
if (mApzcTreeManager) {
mApzcTreeManager->UpdateFocusState(mRootLayerTreeID, aId,
aFocusTarget);
if (aHitTestUpdate) {
mApzcTreeManager->UpdateHitTestingTree(mRootLayerTreeID,
mLayerManager->GetRoot(), aIsFirstPaint, aId, aPaintSequenceNumber);
}
}
mLayerManager->NotifyShadowTreeTransaction();
@ -1232,12 +1237,18 @@ CompositorBridgeParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
Layer* root = aLayerTree->GetRoot();
mLayerManager->SetRoot(root);
if (mApzcTreeManager && !aInfo.isRepeatTransaction() && aHitTestUpdate) {
AutoResolveRefLayers resolve(mCompositionManager);
if (mApzcTreeManager && !aInfo.isRepeatTransaction()) {
mApzcTreeManager->UpdateFocusState(mRootLayerTreeID,
mRootLayerTreeID,
aInfo.focusTarget());
mApzcTreeManager->UpdateHitTestingTree(
mRootLayerTreeID, root, aInfo.isFirstPaint(),
mRootLayerTreeID, aInfo.paintSequenceNumber());
if (aHitTestUpdate) {
AutoResolveRefLayers resolve(mCompositionManager);
mApzcTreeManager->UpdateHitTestingTree(
mRootLayerTreeID, root, aInfo.isFirstPaint(),
mRootLayerTreeID, aInfo.paintSequenceNumber());
}
}
// The transaction ID might get reset to 1 if the page gets reloaded, see

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

@ -30,6 +30,7 @@
#include "mozilla/layers/CompositorController.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/CompositorVsyncSchedulerOwner.h"
#include "mozilla/layers/FocusState.h"
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for ShmemAllocator
#include "mozilla/layers/LayersMessages.h" // for TargetConfig
@ -303,6 +304,7 @@ public:
virtual void ScheduleComposition();
void NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint,
const FocusTarget& aFocusTarget,
bool aScheduleComposite, uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction, bool aHitTestUpdate);

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

@ -299,6 +299,7 @@ CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
state->mParent->NotifyShadowTreeTransaction(
id,
aInfo.isFirstPaint(),
aInfo.focusTarget(),
aInfo.scheduleComposite(),
aInfo.paintSequenceNumber(),
aInfo.isRepeatTransaction(),

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

@ -17,6 +17,7 @@
#include "mozilla/layers/AsyncDragMetrics.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/FocusTarget.h"
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/layers/Keyboard.h"
#include "mozilla/layers/LayerAttributes.h"
@ -420,6 +421,65 @@ struct ParamTraits<mozilla::layers::EventRegions>
}
};
template <>
struct ParamTraits<mozilla::layers::FocusTarget::ScrollTargets>
{
typedef mozilla::layers::FocusTarget::ScrollTargets paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mHorizontal);
WriteParam(aMsg, aParam.mVertical);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mHorizontal) &&
ReadParam(aMsg, aIter, &aResult->mVertical);
}
};
template <>
struct ParamTraits<mozilla::layers::FocusTarget::FocusTargetType>
: public ContiguousEnumSerializer<
mozilla::layers::FocusTarget::FocusTargetType,
mozilla::layers::FocusTarget::eNone,
mozilla::layers::FocusTarget::eSentinel>
{};
template <>
struct ParamTraits<mozilla::layers::FocusTarget>
{
typedef mozilla::layers::FocusTarget paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mFocusHasKeyEventListeners);
WriteParam(aMsg, aParam.mType);
if (aParam.mType == mozilla::layers::FocusTarget::eRefLayer) {
WriteParam(aMsg, aParam.mData.mRefLayerId);
} else if (aParam.mType == mozilla::layers::FocusTarget::eScrollLayer) {
WriteParam(aMsg, aParam.mData.mScrollTargets);
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &aResult->mFocusHasKeyEventListeners) ||
!ReadParam(aMsg, aIter, &aResult->mType)) {
return false;
}
if (aResult->mType == mozilla::layers::FocusTarget::eRefLayer) {
return ReadParam(aMsg, aIter, &aResult->mData.mRefLayerId);
} else if (aResult->mType == mozilla::layers::FocusTarget::eScrollLayer) {
return ReadParam(aMsg, aIter, &aResult->mData.mScrollTargets);
}
return true;
}
};
template <>
struct ParamTraits<mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType>
: public ContiguousEnumSerializer<

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

@ -40,6 +40,7 @@ using mozilla::layers::ScaleMode from "mozilla/layers/LayersTypes.h";
using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h";
using mozilla::layers::EventRegionsOverride from "mozilla/layers/LayersTypes.h";
using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
using mozilla::layers::FocusTarget from "mozilla/layers/FocusTarget.h";
using struct mozilla::layers::ScrollMetadata from "FrameMetrics.h";
using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
@ -569,6 +570,7 @@ struct TransactionInfo
TargetConfig targetConfig;
PluginWindowData[] plugins;
bool isFirstPaint;
FocusTarget focusTarget;
bool scheduleComposite;
uint32_t paintSequenceNumber;
bool isRepeatTransaction;

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

@ -733,6 +733,7 @@ ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear,
info.id() = aId;
info.plugins() = mPluginWindowData;
info.isFirstPaint() = mIsFirstPaint;
info.focusTarget() = mFocusTarget;
info.scheduleComposite() = aScheduleComposite;
info.paintSequenceNumber() = aPaintSequenceNumber;
info.isRepeatTransaction() = aIsRepeatTransaction;
@ -777,6 +778,7 @@ ShadowLayerForwarder::EndTransaction(const nsIntRegion& aRegionToClear,
*aSent = true;
mIsFirstPaint = false;
mFocusTarget = FocusTarget();
MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
return true;
}

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

@ -17,6 +17,7 @@
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/FocusTarget.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/TextureForwarder.h"
#include "mozilla/layers/CompositorTypes.h" // for OpenMode, etc
@ -371,6 +372,11 @@ public:
*/
void SetIsFirstPaint() { mIsFirstPaint = true; }
/**
* Set the current focus target to be sent with the next paint.
*/
void SetFocusTarget(const FocusTarget& aFocusTarget) { mFocusTarget = aFocusTarget; }
void SetLayerObserverEpoch(uint64_t aLayerObserverEpoch);
static void PlatformSyncBeforeUpdate();
@ -448,6 +454,7 @@ private:
MessageLoop* mMessageLoop;
DiagnosticTypes mDiagnosticTypes;
bool mIsFirstPaint;
FocusTarget mFocusTarget;
bool mWindowOverlayChanged;
InfallibleTArray<PluginWindowData> mPluginWindowData;
UniquePtr<ActiveResourceTracker> mActiveResourceTracker;

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

@ -191,6 +191,7 @@
#include "nsLayoutStylesheetCache.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/ScrollInputMethods.h"
#include "mozilla/layers/FocusTarget.h"
#include "nsStyleSet.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
@ -6336,6 +6337,11 @@ PresShell::Paint(nsView* aViewToPaint,
return;
}
// Update the focus target for async keyboard scrolling. This will be forwarded
// to APZ by nsDisplayList::PaintRoot. We need to to do this before we enter
// the paint phase because dispatching eVoid events can cause layout to happen.
mAPZFocusTarget = FocusTarget(this);
nsPresContext* presContext = GetPresContext();
AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);

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

@ -23,6 +23,7 @@
#include "mozilla/ArenaObjectID.h"
#include "mozilla/EventForwards.h"
#include "mozilla/FlushType.h"
#include "mozilla/layers/FocusTarget.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/StyleSetHandle.h"
@ -180,6 +181,7 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRESSHELL_IID)
protected:
typedef mozilla::layers::FocusTarget FocusTarget;
typedef mozilla::layers::LayerManager LayerManager;
typedef mozilla::gfx::SourceSurface SourceSurface;
@ -1526,6 +1528,11 @@ public:
uint32_t GetPresShellId() { return mPresShellId; }
/**
* Get the APZ FocusTarget used for async keyboard scrolling.
*/
const FocusTarget& GetAPZFocusTarget() const { return mAPZFocusTarget; }
/**
* Dispatch a mouse move event based on the most recent mouse position if
* this PresShell is visible. This is used when the contents of the page
@ -1836,7 +1843,6 @@ protected:
nsTHashtable<nsPtrHashKey<void>> mAllocatedPointers;
#endif
// Count of the number of times this presshell has been painted to a window.
uint64_t mPaintCount;
@ -1899,6 +1905,9 @@ protected:
uint32_t mPresShellId;
// The focus information needed for async keyboard scrolling
FocusTarget mAPZFocusTarget;
static nsIContent* gKeyDownTarget;
// Cached font inflation values. This is done to prevent changing of font

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

@ -2206,7 +2206,6 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
content = document->GetDocumentElement();
}
if (ensureMetricsForRootId && content) {
ViewID scrollId = nsLayoutUtils::FindOrCreateIDFor(content);
if (nsLayoutUtils::ContainsMetricsWithId(root, scrollId)) {
@ -2227,6 +2226,9 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
isRootContent, containerParameters));
}
// Send an updated focus target with this transaction
layerManager->SetFocusTarget(presShell->GetAPZFocusTarget());
// NS_WARNING is debug-only, so don't even bother checking the conditions in
// a release build.
#ifdef DEBUG