Bug 1445662 - Make the DPI non-static and bound to the controller thread. r=rhunt

Since we can have multiple browser windows on multiple different
displays with different DPIs, it doesn't make sense to have a single
static DPI value shared across all APZCTreeManagers. Instead, each
APZCTM should store its own DPI value for the display the window is on.
Since the DPI is only ever read from the controller thread, we can make
it bound to that thread, and update the setter code to also set it on
that thread.

As with the previous patch, the change in APZCTreeManagerParent is a
no-op but allows making some other thread in the GPU process the controller
thread. And the change in nsBaseWidget is a no-op everywhere except
Android.
This commit is contained in:
Kartikaya Gupta 2018-03-15 15:25:09 -04:00
Родитель d59c0946db
Коммит 9ab9425d9f
9 изменённых файлов: 86 добавлений и 29 удалений

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

@ -65,8 +65,6 @@ typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef CompositorBridgeParent::LayerTreeState LayerTreeState;
float APZCTreeManager::sDPI = 160.0;
struct APZCTreeManager::TreeBuildingState {
TreeBuildingState(uint64_t aRootLayersId,
bool aIsFirstPaint, uint64_t aOriginatingLayersId,
@ -230,7 +228,8 @@ APZCTreeManager::APZCTreeManager(uint64_t aRootLayersId)
mRetainedTouchIdentifier(-1),
mInScrollbarTouchDrag(false),
mApzcTreeLog("apzctree"),
mTestDataLock("APZTestDataLock")
mTestDataLock("APZTestDataLock"),
mDPI(160.0)
{
RefPtr<APZCTreeManager> self(this);
NS_DispatchToMainThread(
@ -3153,6 +3152,20 @@ APZCTreeManager::ComputeTransformForScrollThumb(
return transform;
}
void
APZCTreeManager::SetDPI(float aDpiValue)
{
APZThreadUtils::AssertOnControllerThread();
mDPI = aDpiValue;
}
float
APZCTreeManager::GetDPI() const
{
APZThreadUtils::AssertOnControllerThread();
return mDPI;
}
#if defined(MOZ_WIDGET_ANDROID)
AndroidDynamicToolbarAnimator*
APZCTreeManager::GetAndroidDynamicToolbarAnimator()

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

@ -340,15 +340,16 @@ public:
bool HitTestAPZC(const ScreenIntPoint& aPoint);
/**
* Sets the dpi value used by all AsyncPanZoomControllers.
* DPI defaults to 72 if not set using SetDPI() at any point.
* Sets the dpi value used by all AsyncPanZoomControllers attached to this
* tree manager.
* DPI defaults to 160 if not set using SetDPI() at any point.
*/
void SetDPI(float aDpiValue) override { sDPI = aDpiValue; }
void SetDPI(float aDpiValue) override;
/**
* Returns the current dpi value in use.
*/
static float GetDPI() { return sDPI; }
float GetDPI() const;
/**
* Find the hit testing node for the scrollbar thumb that matches these
@ -747,7 +748,8 @@ private:
std::unordered_map<uint64_t, UniquePtr<APZTestData>> mTestData;
mutable mozilla::Mutex mTestDataLock;
static float sDPI;
// This must only be touched on the controller thread.
float mDPI;
#if defined(MOZ_WIDGET_ANDROID)
public:

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

@ -868,16 +868,34 @@ AsyncPanZoomController::IsDestroyed() const
return mTreeManager == nullptr;
}
/* static */ScreenCoord
AsyncPanZoomController::GetTouchStartTolerance()
float
AsyncPanZoomController::GetDPI() const
{
return (gfxPrefs::APZTouchStartTolerance() * APZCTreeManager::GetDPI());
if (APZCTreeManager* localPtr = mTreeManager) {
return localPtr->GetDPI();
}
// If this APZC has been destroyed then this value is not going to be
// used for anything that the user will end up seeing, so we can just
// return 0.
return 0.0;
}
/* static */ScreenCoord
AsyncPanZoomController::GetSecondTapTolerance()
ScreenCoord
AsyncPanZoomController::GetTouchStartTolerance() const
{
return (gfxPrefs::APZSecondTapTolerance() * APZCTreeManager::GetDPI());
return (gfxPrefs::APZTouchStartTolerance() * GetDPI());
}
ScreenCoord
AsyncPanZoomController::GetTouchMoveTolerance() const
{
return (gfxPrefs::APZTouchMoveTolerance() * GetDPI());
}
ScreenCoord
AsyncPanZoomController::GetSecondTapTolerance() const
{
return (gfxPrefs::APZSecondTapTolerance() * GetDPI());
}
/* static */AsyncPanZoomController::AxisLockMode AsyncPanZoomController::GetAxisLockMode()
@ -2646,7 +2664,7 @@ void AsyncPanZoomController::HandlePanningUpdate(const ScreenPoint& aPanDistance
double angle = atan2(aPanDistance.y, aPanDistance.x); // range [-pi, pi]
angle = fabs(angle); // range [0, pi]
float breakThreshold = gfxPrefs::APZAxisBreakoutThreshold() * APZCTreeManager::GetDPI();
float breakThreshold = gfxPrefs::APZAxisBreakoutThreshold() * GetDPI();
if (fabs(aPanDistance.x) > breakThreshold || fabs(aPanDistance.y) > breakThreshold) {
if (mState == PANNING_LOCKED_X) {
@ -2667,13 +2685,13 @@ void AsyncPanZoomController::HandlePanningUpdate(const ScreenPoint& aPanDistance
void AsyncPanZoomController::HandlePinchLocking(ScreenCoord spanDistance, ScreenPoint focusChange) {
if (mPinchLocked) {
if (GetPinchLockMode() == PINCH_STICKY) {
ScreenCoord spanBreakoutThreshold = gfxPrefs::APZPinchLockSpanBreakoutThreshold() * APZCTreeManager::GetDPI();
ScreenCoord spanBreakoutThreshold = gfxPrefs::APZPinchLockSpanBreakoutThreshold() * GetDPI();
mPinchLocked = !(spanDistance > spanBreakoutThreshold);
}
} else {
if (GetPinchLockMode() != PINCH_FREE) {
ScreenCoord spanLockThreshold = gfxPrefs::APZPinchLockSpanLockThreshold() * APZCTreeManager::GetDPI();
ScreenCoord scrollLockThreshold = gfxPrefs::APZPinchLockScrollLockThreshold() * APZCTreeManager::GetDPI();
ScreenCoord spanLockThreshold = gfxPrefs::APZPinchLockSpanLockThreshold() * GetDPI();
ScreenCoord scrollLockThreshold = gfxPrefs::APZPinchLockScrollLockThreshold() * GetDPI();
if (spanDistance < spanLockThreshold && focusChange.Length() > scrollLockThreshold) {
mPinchLocked = true;

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

@ -152,6 +152,11 @@ public:
USE_GESTURE_DETECTOR
};
/**
* Gets the DPI from the tree manager.
*/
float GetDPI() const;
/**
* Constant describing the tolerance in distance we use, multiplied by the
* device DPI, before we start panning the screen. This is to prevent us from
@ -160,13 +165,19 @@ public:
* Note: It's an abuse of the 'Coord' class to use it to represent a 2D
* distance, but it's the closest thing we currently have.
*/
static ScreenCoord GetTouchStartTolerance();
ScreenCoord GetTouchStartTolerance() const;
/**
* Same as GetTouchStartTolerance, but the tolerance for how far the touch
* has to move before it starts allowing touchmove events to be dispatched
* to content, for non-scrollable content.
*/
ScreenCoord GetTouchMoveTolerance() const;
/**
* Same as GetTouchStartTolerance, but the tolerance for how close the second
* tap has to be to the first tap in order to be counted as part of a multi-tap
* gesture (double-tap or one-touch-pinch).
*/
static ScreenCoord GetSecondTapTolerance();
ScreenCoord GetSecondTapTolerance() const;
AsyncPanZoomController(uint64_t aLayersId,
APZCTreeManager* aTreeManager,

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

@ -60,7 +60,7 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController)
}
float Axis::ToLocalVelocity(float aVelocityInchesPerMs) const {
ScreenPoint velocity = MakePoint(aVelocityInchesPerMs * APZCTreeManager::GetDPI());
ScreenPoint velocity = MakePoint(aVelocityInchesPerMs * mAsyncPanZoomController->GetDPI());
// Use ToScreenCoordinates() to convert a point rather than a vector by
// treating the point as a vector, and using (0, 0) as the anchor.
ScreenPoint panStart = mAsyncPanZoomController->ToScreenCoordinates(

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

@ -263,7 +263,7 @@ bool GestureEventListener::MoveDistanceExceeds(ScreenCoord aThreshold) const
bool GestureEventListener::MoveDistanceIsLarge() const
{
return MoveDistanceExceeds(AsyncPanZoomController::GetTouchStartTolerance());
return MoveDistanceExceeds(mAsyncPanZoomController->GetTouchStartTolerance());
}
bool GestureEventListener::SecondTapIsFar() const
@ -271,7 +271,7 @@ bool GestureEventListener::SecondTapIsFar() const
// Allow a little more room here, because the is actually lifting their finger
// off the screen before replacing it, and that tends to have more error than
// wiggling the finger while on the screen.
return MoveDistanceExceeds(AsyncPanZoomController::GetSecondTapTolerance());
return MoveDistanceExceeds(mAsyncPanZoomController->GetSecondTapTolerance());
}
nsEventStatus GestureEventListener::HandleInputTouchMove()

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

@ -6,7 +6,6 @@
#include "InputBlockState.h"
#include "APZCTreeManager.h" // for APZCTreeManager::GetDPI
#include "AsyncPanZoomController.h" // for AsyncPanZoomController
#include "ScrollAnimationPhysics.h" // for kScrollSeriesTimeoutMs
#include "gfxPrefs.h" // for gfxPrefs
@ -890,9 +889,13 @@ TouchBlockState::UpdateSlopState(const MultiTouchInput& aInput,
return false;
}
if (mInSlop) {
ScreenCoord threshold = aApzcCanConsumeEvents
? AsyncPanZoomController::GetTouchStartTolerance()
: ScreenCoord(gfxPrefs::APZTouchMoveTolerance() * APZCTreeManager::GetDPI());
ScreenCoord threshold = 0;
// If the target was confirmed to null then the threshold doesn't
// matter anyway since the events will never be processed.
if (const RefPtr<AsyncPanZoomController>& apzc = GetTargetApzc()) {
threshold = aApzcCanConsumeEvents ? apzc->GetTouchStartTolerance()
: apzc->GetTouchMoveTolerance();
}
bool stayInSlop = (aInput.mType == MultiTouchInput::MULTITOUCH_MOVE) &&
(aInput.mTouches.Length() == 1) &&
((aInput.mTouches[0].mScreenPoint - mSlopOrigin).Length() < threshold);

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

@ -248,7 +248,11 @@ APZCTreeManagerParent::RecvUpdateZoomConstraints(
mozilla::ipc::IPCResult
APZCTreeManagerParent::RecvSetDPI(const float& aDpiValue)
{
mTreeManager->SetDPI(aDpiValue);
APZThreadUtils::RunOnControllerThread(NewRunnableMethod<float>(
"layers::IAPZCTreeManager::SetDPI",
mTreeManager,
&IAPZCTreeManager::SetDPI,
aDpiValue));
return IPC_OK();
}

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

@ -938,7 +938,13 @@ void nsBaseWidget::ConfigureAPZCTreeManager()
ConfigureAPZControllerThread();
mAPZC->SetDPI(GetDPI());
float dpi = GetDPI();
// On Android the main thread is not the controller thread
APZThreadUtils::RunOnControllerThread(NewRunnableMethod<float>(
"layers::IAPZCTreeManager::SetDPI",
mAPZC,
&IAPZCTreeManager::SetDPI,
dpi));
if (gfxPrefs::APZKeyboardEnabled()) {
KeyboardMap map = nsXBLWindowKeyHandler::CollectKeyboardShortcuts();