Bug 1323797 - Add compositor support for triangle layers (for BasicCompositor backend) - Part 3: Implement DrawPolygon() with Paths draft
authorMiko Mynttinen <mikokm@gmail.com>
Tue, 10 Jan 2017 20:48:44 +0200
changeset 460986 9c9c40d0f932d404f352d7daaf8db61347362e05
parent 460985 03ee53d7922c097b551d412871732a73d74c9daf
child 460987 a7670854f326e01a4c78dc2ab21636f2b896f2ce
push id41545
push userbmo:mikokm@gmail.com
push dateSat, 14 Jan 2017 16:23:29 +0000
bugs1323797
milestone53.0a1
Bug 1323797 - Add compositor support for triangle layers (for BasicCompositor backend) - Part 3: Implement DrawPolygon() with Paths MozReview-Commit-ID: FjxDlzdhqor
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/BasicCompositor.h
gfx/layers/basic/BasicLayersImpl.cpp
gfx/layers/basic/BasicLayersImpl.h
gfx/thebes/gfxPrefs.h
modules/libpref/init/all.js
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -351,25 +351,110 @@ BasicCompositor::CreateDataTextureSource
 }
 
 bool
 BasicCompositor::SupportsEffect(EffectTypes aEffect)
 {
   return aEffect != EffectTypes::YCBCR && aEffect != EffectTypes::COMPONENT_ALPHA;
 }
 
+bool
+BasicCompositor::SupportsLayerGeometry() const
+{
+  return gfxPrefs::BasicLayerGeometry();
+}
+
+static RefPtr<gfx::Path>
+BuildPathFromPolygon(const RefPtr<DrawTarget>& aDT,
+                     const gfx::Polygon& aPolygon)
+{
+  RefPtr<PathBuilder> pathBuilder = aDT->CreatePathBuilder();
+  const nsTArray<Point4D>& points = aPolygon.GetPoints();
+
+  pathBuilder->MoveTo(points[0].As2DPoint());
+
+  for (size_t i = 1; i < points.Length(); ++i) {
+    pathBuilder->LineTo(points[i].As2DPoint());
+  }
+
+  pathBuilder->Close();
+  return pathBuilder->Finish();
+}
+
 static void
-DrawSurfaceWithTextureCoords(DrawTarget *aDest,
+DrawSurface(gfx::DrawTarget* aDest,
+            const gfx::Rect& aDestRect,
+            const gfx::Rect& /* aClipRect */,
+            const gfx::Color& aColor,
+            const gfx::DrawOptions& aOptions,
+            gfx::SourceSurface* aMask,
+            const gfx::Matrix* aMaskTransform)
+{
+  FillRectWithMask(aDest, aDestRect, aColor,
+                   aOptions, aMask, aMaskTransform);
+}
+
+static void
+DrawSurface(gfx::DrawTarget* aDest,
+            const gfx::Polygon& aPolygon,
+            const gfx::Rect& aClipRect,
+            const gfx::Color& aColor,
+            const gfx::DrawOptions& aOptions,
+            gfx::SourceSurface* aMask,
+            const gfx::Matrix* aMaskTransform)
+{
+  RefPtr<Path> path = BuildPathFromPolygon(aDest, aPolygon);
+  FillPathWithMask(aDest, path, aClipRect, aColor,
+                   aOptions, aMask, aMaskTransform);
+}
+
+static void
+DrawTextureSurface(gfx::DrawTarget* aDest,
+                   const gfx::Rect& aDestRect,
+                   const gfx::Rect& /* aClipRect */,
+                   gfx::SourceSurface* aSource,
+                   gfx::SamplingFilter aSamplingFilter,
+                   const gfx::DrawOptions& aOptions,
+                   ExtendMode aExtendMode,
+                   gfx::SourceSurface* aMask,
+                   const gfx::Matrix* aMaskTransform,
+                   const Matrix* aSurfaceTransform)
+{
+  FillRectWithMask(aDest, aDestRect, aSource, aSamplingFilter, aOptions,
+                   aExtendMode, aMask, aMaskTransform, aSurfaceTransform);
+}
+
+static void
+DrawTextureSurface(gfx::DrawTarget* aDest,
+                   const gfx::Polygon& aPolygon,
+                   const gfx::Rect& aClipRect,
+                   gfx::SourceSurface* aSource,
+                   gfx::SamplingFilter aSamplingFilter,
+                   const gfx::DrawOptions& aOptions,
+                   ExtendMode aExtendMode,
+                   gfx::SourceSurface* aMask,
+                   const gfx::Matrix* aMaskTransform,
+                   const Matrix* aSurfaceTransform)
+{
+  RefPtr<Path> path = BuildPathFromPolygon(aDest, aPolygon);
+  FillPathWithMask(aDest, path, aClipRect, aSource, aSamplingFilter, aOptions,
+                   aExtendMode, aMask, aMaskTransform, aSurfaceTransform);
+}
+
+template<typename Geometry>
+static void
+DrawSurfaceWithTextureCoords(gfx::DrawTarget* aDest,
+                             const Geometry& aGeometry,
                              const gfx::Rect& aDestRect,
-                             SourceSurface *aSource,
+                             gfx::SourceSurface* aSource,
                              const gfx::Rect& aTextureCoords,
                              gfx::SamplingFilter aSamplingFilter,
-                             const DrawOptions& aOptions,
-                             SourceSurface *aMask,
-                             const Matrix* aMaskTransform)
+                             const gfx::DrawOptions& aOptions,
+                             gfx::SourceSurface* aMask,
+                             const gfx::Matrix* aMaskTransform)
 {
   if (!aSource) {
     gfxWarning() << "DrawSurfaceWithTextureCoords problem " << gfx::hexa(aSource) << " and " << gfx::hexa(aMask);
     return;
   }
 
   // Convert aTextureCoords into aSource's coordinate space
   gfxRect sourceRect(aTextureCoords.x * aSource->GetSize().width,
@@ -387,18 +472,18 @@ DrawSurfaceWithTextureCoords(DrawTarget 
                                   gfx::IntPoint::Truncate(aDestRect.x, aDestRect.y),
                                   gfx::IntPoint::Truncate(aDestRect.XMost(), aDestRect.y),
                                   gfx::IntPoint::Truncate(aDestRect.XMost(), aDestRect.YMost()));
 
   // Only use REPEAT if aTextureCoords is outside (0, 0, 1, 1).
   gfx::Rect unitRect(0, 0, 1, 1);
   ExtendMode mode = unitRect.Contains(aTextureCoords) ? ExtendMode::CLAMP : ExtendMode::REPEAT;
 
-  FillRectWithMask(aDest, aDestRect, aSource, aSamplingFilter, aOptions,
-                   mode, aMask, aMaskTransform, &matrix);
+  DrawTextureSurface(aDest, aGeometry, aDestRect, aSource, aSamplingFilter,
+                     aOptions, mode, aMask, aMaskTransform, &matrix);
 }
 
 static void
 SetupMask(const EffectChain& aEffectChain,
           DrawTarget* aDest,
           const IntPoint& aOffset,
           RefPtr<SourceSurface>& aMaskSurface,
           Matrix& aMaskTransform)
@@ -548,16 +633,45 @@ AttemptVideoConvertAndScale(TextureSourc
 void
 BasicCompositor::DrawQuad(const gfx::Rect& aRect,
                           const gfx::IntRect& aClipRect,
                           const EffectChain &aEffectChain,
                           gfx::Float aOpacity,
                           const gfx::Matrix4x4& aTransform,
                           const gfx::Rect& aVisibleRect)
 {
+  DrawGeometry(aRect, aRect, aClipRect, aEffectChain,
+               aOpacity, aTransform, aVisibleRect, true);
+}
+
+void
+BasicCompositor::DrawPolygon(const gfx::Polygon& aPolygon,
+                             const gfx::Rect& aRect,
+                             const gfx::IntRect& aClipRect,
+                             const EffectChain& aEffectChain,
+                             gfx::Float aOpacity,
+                             const gfx::Matrix4x4& aTransform,
+                             const gfx::Rect& aVisibleRect)
+{
+  DrawGeometry(aPolygon, aRect, aClipRect, aEffectChain,
+               aOpacity, aTransform, aVisibleRect, false);
+}
+
+
+template<typename Geometry>
+void
+BasicCompositor::DrawGeometry(const Geometry& aGeometry,
+                              const gfx::Rect& aRect,
+                              const gfx::IntRect& aClipRect,
+                              const EffectChain& aEffectChain,
+                              gfx::Float aOpacity,
+                              const gfx::Matrix4x4& aTransform,
+                              const gfx::Rect& aVisibleRect,
+                              const bool aEnableAA)
+{
   RefPtr<DrawTarget> buffer = mRenderTarget->mDrawTarget;
 
   // For 2D drawing, |dest| and |buffer| are the same surface. For 3D drawing,
   // |dest| is a temporary surface.
   RefPtr<DrawTarget> dest = buffer;
 
   AutoRestoreTransform autoRestoreTransform(dest);
 
@@ -608,28 +722,33 @@ BasicCompositor::DrawQuad(const gfx::Rec
     SetupMask(aEffectChain, dest, offset, sourceMask, maskTransform);
   }
 
   CompositionOp blendMode = CompositionOp::OP_OVER;
   if (Effect* effect = aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get()) {
     blendMode = static_cast<EffectBlendMode*>(effect)->mBlendMode;
   }
 
+  const AntialiasMode aaMode =
+    aEnableAA ? AntialiasMode::DEFAULT : AntialiasMode::NONE;
+
+  DrawOptions drawOptions(aOpacity, blendMode, aaMode);
+
   switch (aEffectChain.mPrimaryEffect->mType) {
     case EffectTypes::SOLID_COLOR: {
       EffectSolidColor* effectSolidColor =
         static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());
 
       bool unboundedOp = !IsOperatorBoundByMask(blendMode);
       if (unboundedOp) {
         dest->PushClipRect(aRect);
       }
 
-      FillRectWithMask(dest, aRect, effectSolidColor->mColor,
-                       DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform);
+      DrawSurface(dest, aGeometry, aRect, effectSolidColor->mColor,
+                  drawOptions, sourceMask, &maskTransform);
 
       if (unboundedOp) {
         dest->PopClip();
       }
       break;
     }
     case EffectTypes::RGB: {
       TexturedEffect* texturedEffect =
@@ -649,37 +768,37 @@ BasicCompositor::DrawQuad(const gfx::Rec
           gfxWarning() << "Failed to get YCbCr to rgb surface.";
         } else if (source->mFromYCBCR &&
             AttemptVideoScale(source, sourceMask, aOpacity, blendMode,
                               texturedEffect,
                               newTransform, aRect, transformedClipRect,
                               dest, buffer)) {
           // we succeeded in scaling
         } else {
-          DrawSurfaceWithTextureCoords(dest, aRect,
+          DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
                                        source->GetSurface(dest),
                                        texturedEffect->mTextureCoords,
                                        texturedEffect->mSamplingFilter,
-                                       DrawOptions(aOpacity, blendMode),
+                                       drawOptions,
                                        sourceMask, &maskTransform);
         }
       } else if (source) {
         SourceSurface* srcSurf = source->GetSurface(dest);
         if (srcSurf) {
           RefPtr<DataSourceSurface> srcData = srcSurf->GetDataSurface();
 
           // Yes, we re-create the premultiplied data every time.
           // This might be better with a cache, eventually.
           RefPtr<DataSourceSurface> premultData = gfxUtils::CreatePremultipliedDataSurface(srcData);
 
-          DrawSurfaceWithTextureCoords(dest, aRect,
+          DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
                                        premultData,
                                        texturedEffect->mTextureCoords,
                                        texturedEffect->mSamplingFilter,
-                                       DrawOptions(aOpacity, blendMode),
+                                       drawOptions,
                                        sourceMask, &maskTransform);
         }
       } else {
         gfxDevCrash(LogReason::IncompatibleBasicTexturedEffect) << "Bad for basic with " << texturedEffect->mTexture->Name() << " and " << gfx::hexa(sourceMask);
       }
 
       break;
     }
@@ -689,21 +808,21 @@ BasicCompositor::DrawQuad(const gfx::Rec
     }
     case EffectTypes::RENDER_TARGET: {
       EffectRenderTarget* effectRenderTarget =
         static_cast<EffectRenderTarget*>(aEffectChain.mPrimaryEffect.get());
       RefPtr<BasicCompositingRenderTarget> surface
         = static_cast<BasicCompositingRenderTarget*>(effectRenderTarget->mRenderTarget.get());
       RefPtr<SourceSurface> sourceSurf = surface->mDrawTarget->Snapshot();
 
-      DrawSurfaceWithTextureCoords(dest, aRect,
+      DrawSurfaceWithTextureCoords(dest, aGeometry, aRect,
                                    sourceSurf,
                                    effectRenderTarget->mTextureCoords,
                                    effectRenderTarget->mSamplingFilter,
-                                   DrawOptions(aOpacity, blendMode),
+                                   drawOptions,
                                    sourceMask, &maskTransform);
       break;
     }
     case EffectTypes::COMPONENT_ALPHA: {
       MOZ_CRASH("Can't (easily) support component alpha with BasicCompositor!");
       break;
     }
     default: {
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -4,16 +4,18 @@
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_BASICCOMPOSITOR_H
 #define MOZILLA_GFX_BASICCOMPOSITOR_H
 
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/TextureHost.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Triangle.h"
+#include "mozilla/gfx/Polygon.h"
 
 namespace mozilla {
 namespace layers {
 
 class BasicCompositingRenderTarget : public CompositingRenderTarget
 {
 public:
   BasicCompositingRenderTarget(gfx::DrawTarget* aDrawTarget, const gfx::IntRect& aRect)
@@ -75,16 +77,18 @@ public:
   virtual already_AddRefed<DataTextureSource>
   CreateDataTextureSourceAround(gfx::DataSourceSurface* aSurface) override;
 
   virtual already_AddRefed<DataTextureSource>
   CreateDataTextureSourceAroundYCbCr(TextureHost* aTexture) override;
 
   virtual bool SupportsEffect(EffectTypes aEffect) override;
 
+  bool SupportsLayerGeometry() const override;
+
   virtual void SetRenderTarget(CompositingRenderTarget *aSource) override
   {
     mRenderTarget = static_cast<BasicCompositingRenderTarget*>(aSource);
     mRenderTarget->BindRenderTarget();
   }
   virtual CompositingRenderTarget* GetCurrentRenderTarget() const override
   {
     return mRenderTarget;
@@ -106,17 +110,17 @@ public:
                           gfx::IntRect *aClipRectOut = nullptr,
                           gfx::IntRect *aRenderBoundsOut = nullptr) override;
   virtual void EndFrame() override;
 
   virtual bool SupportsPartialTextureUpdate() override { return true; }
   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override { return true; }
   virtual int32_t GetMaxTextureSize() const override;
   virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override { }
-  
+
   virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) override {
   }
 
   virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) override { }
 
 #ifdef MOZ_DUMP_PAINTING
   virtual const char* Name() const override { return "Basic"; }
 #endif // MOZ_DUMP_PAINTING
@@ -131,16 +135,34 @@ public:
   {
     return mIsPendingEndRemoteDrawing;
   }
 
   virtual void FinishPendingComposite() override;
 
 private:
 
+  template<typename Geometry>
+  void DrawGeometry(const Geometry& aGeometry,
+                    const gfx::Rect& aRect,
+                    const gfx::IntRect& aClipRect,
+                    const EffectChain& aEffectChain,
+                    gfx::Float aOpacity,
+                    const gfx::Matrix4x4& aTransform,
+                    const gfx::Rect& aVisibleRect,
+                    const bool aEnableAA);
+
+  virtual void DrawPolygon(const gfx::Polygon& aPolygon,
+                           const gfx::Rect& aRect,
+                           const gfx::IntRect& aClipRect,
+                           const EffectChain& aEffectChain,
+                           gfx::Float aOpacity,
+                           const gfx::Matrix4x4& aTransform,
+                           const gfx::Rect& aVisibleRect) override;
+
   void TryToEndRemoteDrawing(bool aForceToEnd = false);
 
   bool NeedsToDeferEndRemoteDrawing();
 
   // The final destination surface
   RefPtr<gfx::DrawTarget> mDrawTarget;
   // The current render target for drawing
   RefPtr<BasicCompositingRenderTarget> mRenderTarget;
--- a/gfx/layers/basic/BasicLayersImpl.cpp
+++ b/gfx/layers/basic/BasicLayersImpl.cpp
@@ -201,16 +201,78 @@ FillRectWithMask(DrawTarget* aDT,
                      mask.GetSurface(), &maskTransform);
     return;
   }
 
   FillRectWithMask(aDT, aRect, aSurface, aSamplingFilter, aOptions,
                    ExtendMode::CLAMP);
 }
 
+void
+FillPathWithMask(DrawTarget* aDT,
+                 const Path* aPath,
+                 const Rect& aClipRect,
+                 const Color& aColor,
+                 const DrawOptions& aOptions,
+                 SourceSurface* aMaskSource,
+                 const Matrix* aMaskTransform)
+{
+  if (aMaskSource && aMaskTransform) {
+    aDT->PushClipRect(aClipRect);
+    Matrix oldTransform = aDT->GetTransform();
+
+    aDT->SetTransform(*aMaskTransform);
+    aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
+    aDT->SetTransform(oldTransform);
+    aDT->PopClip();
+    return;
+  }
+
+  aDT->Fill(aPath, ColorPattern(aColor), aOptions);
+}
+
+void
+FillPathWithMask(DrawTarget* aDT,
+                 const Path* aPath,
+                 const Rect& aClipRect,
+                 SourceSurface* aSurface,
+                 SamplingFilter aSamplingFilter,
+                 const DrawOptions& aOptions,
+                 ExtendMode aExtendMode,
+                 SourceSurface* aMaskSource,
+                 const Matrix* aMaskTransform,
+                 const Matrix* aSurfaceTransform)
+{
+  if (aMaskSource && aMaskTransform) {
+    aDT->PushClipRect(aClipRect);
+    Matrix oldTransform = aDT->GetTransform();
+
+    Matrix inverseMask = *aMaskTransform;
+    inverseMask.Invert();
+
+    Matrix transform = oldTransform * inverseMask;
+    if (aSurfaceTransform) {
+      transform = (*aSurfaceTransform) * transform;
+    }
+
+    SurfacePattern source(aSurface, aExtendMode, transform, aSamplingFilter);
+
+    aDT->SetTransform(*aMaskTransform);
+    aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
+    aDT->SetTransform(oldTransform);
+    aDT->PopClip();
+    return;
+  }
+
+  aDT->Fill(aPath,
+            SurfacePattern(aSurface, aExtendMode,
+                           aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
+                           aSamplingFilter), aOptions);
+}
+
 BasicImplData*
 ToData(Layer* aLayer)
 {
   return static_cast<BasicImplData*>(aLayer->ImplData());
 }
 
 gfx::CompositionOp
 GetEffectiveOperator(Layer* aLayer)
--- a/gfx/layers/basic/BasicLayersImpl.h
+++ b/gfx/layers/basic/BasicLayersImpl.h
@@ -122,16 +122,36 @@ FillRectWithMask(gfx::DrawTarget* aDT,
 void
 FillRectWithMask(gfx::DrawTarget* aDT,
                  const gfx::Point& aDeviceOffset,
                  const gfx::Rect& aRect,
                  const gfx::Color& aColor,
                  const gfx::DrawOptions& aOptions,
                  Layer* aMaskLayer);
 
+void
+FillPathWithMask(gfx::DrawTarget* aDT,
+                 const gfx::Path* aPath,
+                 const gfx::Rect& aClipRect,
+                 const gfx::Color& aColor,
+                 const gfx::DrawOptions& aOptions,
+                 gfx::SourceSurface* aMaskSource = nullptr,
+                 const gfx::Matrix* aMaskTransform = nullptr);
+void
+FillPathWithMask(gfx::DrawTarget* aDT,
+                 const gfx::Path* aPath,
+                 const gfx::Rect& aClipRect,
+                 gfx::SourceSurface* aSurface,
+                 gfx::SamplingFilter aSamplingFilter,
+                 const gfx::DrawOptions& aOptions,
+                 gfx::ExtendMode aExtendMode,
+                 gfx::SourceSurface* aMaskSource,
+                 const gfx::Matrix* aMaskTransform,
+                 const gfx::Matrix* aSurfaceTransform);
+
 BasicImplData*
 ToData(Layer* aLayer);
 
 /**
  * Returns the operator to be used when blending and compositing this layer.
  * Currently there is no way to specify both a blending and a compositing
  * operator other than normal and source over respectively.
  *
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -522,16 +522,17 @@ private:
   DECL_GFX_PREF(Once, "layers.tiles.edge-padding",             TileEdgePaddingEnabled, bool, true);
   DECL_GFX_PREF(Live, "layers.tiles.fade-in.enabled",          LayerTileFadeInEnabled, bool, false);
   DECL_GFX_PREF(Live, "layers.tiles.fade-in.duration-ms",      LayerTileFadeInDuration, uint32_t, 250);
   DECL_GFX_PREF(Live, "layers.transaction.warning-ms",         LayerTransactionWarning, uint32_t, 200);
   DECL_GFX_PREF(Once, "layers.uniformity-info",                UniformityInfo, bool, false);
   DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces",   UseImageOffscreenSurfaces, bool, true);
   DECL_GFX_PREF(Live, "layers.draw-mask-debug",                DrawMaskLayer, bool, false);
   DECL_GFX_PREF(Live, "layers.geometry.opengl.enabled",        OGLLayerGeometry, bool, false);
+  DECL_GFX_PREF(Live, "layers.geometry.basic.enabled",         BasicLayerGeometry, bool, false);
 
   DECL_GFX_PREF(Live, "layout.animation.prerender.partial", PartiallyPrerenderAnimatedContent, bool, false);
   DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-x", AnimationPrerenderViewportRatioLimitX, float, 1.125f);
   DECL_GFX_PREF(Live, "layout.animation.prerender.viewport-ratio-limit-y", AnimationPrerenderViewportRatioLimitY, float, 1.125f);
   DECL_GFX_PREF(Live, "layout.animation.prerender.absolute-limit-x", AnimationPrerenderAbsoluteLimitX, uint32_t, 4096);
   DECL_GFX_PREF(Live, "layout.animation.prerender.absolute-limit-y", AnimationPrerenderAbsoluteLimitY, uint32_t, 4096);
 
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -604,16 +604,19 @@ pref("layers.amd-switchable-gfx.enabled"
 pref("layers.async-pan-zoom.enabled", true);
 
 // Whether to enable event region building during painting
 pref("layout.event-regions.enabled", false);
 
 // Whether to enable arbitrary layer geometry for OpenGL compositor
 pref("layers.geometry.opengl.enabled", true);
 
+// Whether to enable arbitrary layer geometry for Basic compositor
+pref("layers.geometry.basic.enabled", true);
+
 // APZ preferences. For documentation/details on what these prefs do, check
 // gfx/layers/apz/src/AsyncPanZoomController.cpp.
 pref("apz.allow_checkerboarding", true);
 pref("apz.allow_immediate_handoff", true);
 pref("apz.allow_zooming", false);
 
 // Whether to lock touch scrolling to one axis at a time
 // 0 = FREE (No locking at all)