layout/ipc/RenderFrameParent.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=8 et :
     3  */
     4 /* This Source Code Form is subject to the terms of the Mozilla Public
     5  * License, v. 2.0. If a copy of the MPL was not distributed with this
     6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     8 #include "base/basictypes.h"
    10 #include "BasicLayers.h"
    11 #include "gfx3DMatrix.h"
    12 #ifdef MOZ_ENABLE_D3D9_LAYER
    13 # include "LayerManagerD3D9.h"
    14 #endif //MOZ_ENABLE_D3D9_LAYER
    15 #include "mozilla/BrowserElementParent.h"
    16 #include "mozilla/dom/TabParent.h"
    17 #include "mozilla/layers/APZCTreeManager.h"
    18 #include "mozilla/layers/CompositorParent.h"
    19 #include "mozilla/layers/LayerTransactionParent.h"
    20 #include "nsContentUtils.h"
    21 #include "nsFrameLoader.h"
    22 #include "nsIObserver.h"
    23 #include "nsSubDocumentFrame.h"
    24 #include "nsView.h"
    25 #include "nsViewportFrame.h"
    26 #include "RenderFrameParent.h"
    27 #include "mozilla/layers/LayerManagerComposite.h"
    28 #include "mozilla/layers/CompositorChild.h"
    29 #include "ClientLayerManager.h"
    31 typedef nsContentView::ViewConfig ViewConfig;
    32 using namespace mozilla::dom;
    33 using namespace mozilla::layers;
    35 namespace mozilla {
    36 namespace layout {
    38 typedef FrameMetrics::ViewID ViewID;
    39 typedef RenderFrameParent::ViewMap ViewMap;
    41 // Represents (affine) transforms that are calculated from a content view.
    42 struct ViewTransform {
    43   ViewTransform(nsIntPoint aTranslation = nsIntPoint(0, 0), float aXScale = 1, float aYScale = 1)
    44     : mTranslation(aTranslation)
    45     , mXScale(aXScale)
    46     , mYScale(aYScale)
    47   {}
    49   operator gfx3DMatrix() const
    50   {
    51     return
    52       gfx3DMatrix::Translation(mTranslation.x, mTranslation.y, 0) *
    53       gfx3DMatrix::ScalingMatrix(mXScale, mYScale, 1);
    54   }
    56   nsIntPoint mTranslation;
    57   float mXScale;
    58   float mYScale;
    59 };
    61 // Matrix helpers
    62 // For our simple purposes, these helpers apply to 2D affine transformations
    63 // that can be represented by a scale and a translation. This makes the math
    64 // much easier because we only expect the diagonals and the translation
    65 // coordinates of the matrix to be non-zero.
    67 static double GetXScale(const gfx3DMatrix& aTransform)
    68 {
    69   return aTransform._11;
    70 }
    72 static double GetYScale(const gfx3DMatrix& aTransform)
    73 {
    74   return aTransform._22;
    75 }
    77 static void Scale(gfx3DMatrix& aTransform, double aXScale, double aYScale)
    78 {
    79   aTransform._11 *= aXScale;
    80   aTransform._22 *= aYScale;
    81 }
    83 static void ReverseTranslate(gfx3DMatrix& aTransform, const gfxPoint& aOffset)
    84 {
    85   aTransform._41 -= aOffset.x;
    86   aTransform._42 -= aOffset.y;
    87 }
    90 static void ApplyTransform(nsRect& aRect,
    91                            gfx3DMatrix& aTransform,
    92                            nscoord auPerDevPixel)
    93 {
    94   aRect.x = aRect.x * aTransform._11 + aTransform._41 * auPerDevPixel;
    95   aRect.y = aRect.y * aTransform._22 + aTransform._42 * auPerDevPixel;
    96   aRect.width = aRect.width * aTransform._11;
    97   aRect.height = aRect.height * aTransform._22;
    98 }
   100 static void
   101 AssertInTopLevelChromeDoc(ContainerLayer* aContainer,
   102                           nsIFrame* aContainedFrame)
   103 {
   104   NS_ASSERTION(
   105     (aContainer->Manager()->GetBackendType() != mozilla::layers::LayersBackend::LAYERS_BASIC) ||
   106     (aContainedFrame->GetNearestWidget() ==
   107      static_cast<BasicLayerManager*>(aContainer->Manager())->GetRetainerWidget()),
   108     "Expected frame to be in top-level chrome document");
   109 }
   111 // Return view for given ID in aMap, nullptr if not found.
   112 static nsContentView*
   113 FindViewForId(const ViewMap& aMap, ViewID aId)
   114 {
   115   ViewMap::const_iterator iter = aMap.find(aId);
   116   return iter != aMap.end() ? iter->second : nullptr;
   117 }
   119 // Return the root content view in aMap, nullptr if not found.
   120 static nsContentView*
   121 FindRootView(const ViewMap& aMap)
   122 {
   123   for (ViewMap::const_iterator iter = aMap.begin(), end = aMap.end();
   124        iter != end;
   125        ++iter) {
   126     if (iter->second->IsRoot())
   127       return iter->second;
   128   }
   129   return nullptr;
   130 }
   132 static const FrameMetrics*
   133 GetFrameMetrics(Layer* aLayer)
   134 {
   135   ContainerLayer* container = aLayer->AsContainerLayer();
   136   return container ? &container->GetFrameMetrics() : nullptr;
   137 }
   139 /**
   140  * Gets the layer-pixel offset of aContainerFrame's content rect top-left
   141  * from the nearest display item reference frame (which we assume will be inducing
   142  * a ContainerLayer).
   143  */
   144 static nsIntPoint
   145 GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder)
   146 {
   147   nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
   149   // Offset to the content rect in case we have borders or padding
   150   // Note that aContainerFrame could be a reference frame itself, so
   151   // we need to be careful here to ensure that we call ToReferenceFrame
   152   // on aContainerFrame and not its parent.
   153   nsPoint frameOffset = aBuilder->ToReferenceFrame(aContainerFrame) +
   154     (aContainerFrame->GetContentRect().TopLeft() - aContainerFrame->GetPosition());
   156   return frameOffset.ToNearestPixels(auPerDevPixel);
   157 }
   159 // Compute the transform of the shadow tree contained by
   160 // |aContainerFrame| to widget space.  We transform because the
   161 // subprocess layer manager renders to a different top-left than where
   162 // the shadow tree is drawn here and because a scale can be set on the
   163 // shadow tree.
   164 static ViewTransform
   165 ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
   166                            nsFrameLoader* aRootFrameLoader,
   167                            const FrameMetrics* aMetrics,
   168                            const ViewConfig& aConfig,
   169                            float aTempScaleX = 1.0,
   170                            float aTempScaleY = 1.0)
   171 {
   172   // |aMetrics->mViewportScrollOffset| The frame's scroll offset when it was
   173   //                                   painted, in content document pixels.
   174   // |aConfig.mScrollOffset|           What our user expects, or wants, the
   175   //                                   frame scroll offset to be in chrome
   176   //                                   document app units.
   177   //
   178   // So we set a compensating translation that moves the content document
   179   // pixels to where the user wants them to be.
   180   //
   181   nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
   182   nsIntPoint scrollOffset =
   183     aConfig.mScrollOffset.ToNearestPixels(auPerDevPixel);
   184   LayerIntPoint metricsScrollOffset = RoundedToInt(aMetrics->GetScrollOffsetInLayerPixels());
   186   if (aRootFrameLoader->AsyncScrollEnabled() && !aMetrics->mDisplayPort.IsEmpty()) {
   187     // Only use asynchronous scrolling if it is enabled and there is a
   188     // displayport defined. It is useful to have a scroll layer that is
   189     // synchronously scrolled for identifying a scroll area before it is
   190     // being actively scrolled.
   191     nsIntPoint scrollCompensation(
   192       (scrollOffset.x / aTempScaleX - metricsScrollOffset.x),
   193       (scrollOffset.y / aTempScaleY - metricsScrollOffset.y));
   195     return ViewTransform(-scrollCompensation, aConfig.mXScale, aConfig.mYScale);
   196   } else {
   197     return ViewTransform(nsIntPoint(0, 0), 1, 1);
   198   }
   199 }
   201 // Use shadow layer tree to build display list for the browser's frame.
   202 static void
   203 BuildListForLayer(Layer* aLayer,
   204                   nsFrameLoader* aRootFrameLoader,
   205                   const gfx3DMatrix& aTransform,
   206                   nsDisplayListBuilder* aBuilder,
   207                   nsDisplayList& aShadowTree,
   208                   nsIFrame* aSubdocFrame)
   209 {
   210   const FrameMetrics* metrics = GetFrameMetrics(aLayer);
   212   gfx3DMatrix transform;
   214   if (metrics && metrics->IsScrollable()) {
   215     const ViewID scrollId = metrics->GetScrollId();
   217     // We need to figure out the bounds of the scrollable region using the
   218     // shadow layer tree from the remote process. The metrics viewport is
   219     // defined based on all the transformations of its parent layers and
   220     // the scale of the current layer.
   222     // Calculate transform for this layer.
   223     nsContentView* view =
   224       aRootFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId);
   225     // XXX why don't we include aLayer->GetTransform() in the inverse-scale here?
   226     // This seems wrong, but it doesn't seem to cause bugs!
   227     gfx3DMatrix applyTransform = ComputeShadowTreeTransform(
   228       aSubdocFrame, aRootFrameLoader, metrics, view->GetViewConfig(),
   229       1 / GetXScale(aTransform), 1 / GetYScale(aTransform));
   230     gfx3DMatrix layerTransform;
   231     To3DMatrix(aLayer->GetTransform(), layerTransform);
   232     transform = applyTransform * layerTransform * aTransform;
   234     // As mentioned above, bounds calculation also depends on the scale
   235     // of this layer.
   236     gfx3DMatrix tmpTransform = aTransform;
   237     Scale(tmpTransform, GetXScale(applyTransform), GetYScale(applyTransform));
   239     // Calculate rect for this layer based on aTransform.
   240     nsRect bounds;
   241     {
   242       bounds = CSSRect::ToAppUnits(metrics->mViewport);
   243       nscoord auPerDevPixel = aSubdocFrame->PresContext()->AppUnitsPerDevPixel();
   244       ApplyTransform(bounds, tmpTransform, auPerDevPixel);
   245     }
   247     aShadowTree.AppendToTop(
   248       new (aBuilder) nsDisplayRemoteShadow(aBuilder, aSubdocFrame, bounds, scrollId));
   250   } else {
   251     gfx3DMatrix layerTransform;
   252     To3DMatrix(aLayer->GetTransform(), layerTransform);
   253     transform = layerTransform * aTransform;
   254   }
   256   for (Layer* child = aLayer->GetFirstChild(); child;
   257        child = child->GetNextSibling()) {
   258     BuildListForLayer(child, aRootFrameLoader, transform,
   259                       aBuilder, aShadowTree, aSubdocFrame);
   260   }
   261 }
   263 // Go down shadow layer tree and apply transformations for scrollable layers.
   264 static void
   265 TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
   266                     nsIFrame* aFrame, Layer* aLayer,
   267                     const ViewTransform& aTransform,
   268                     float aTempScaleDiffX = 1.0,
   269                     float aTempScaleDiffY = 1.0)
   270 {
   271   LayerComposite* shadow = aLayer->AsLayerComposite();
   272   shadow->SetShadowClipRect(aLayer->GetClipRect());
   273   shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
   274   shadow->SetShadowOpacity(aLayer->GetOpacity());
   276   const FrameMetrics* metrics = GetFrameMetrics(aLayer);
   278   gfx3DMatrix shadowTransform;
   279   To3DMatrix(aLayer->GetTransform(), shadowTransform);
   280   ViewTransform layerTransform = aTransform;
   282   if (metrics && metrics->IsScrollable()) {
   283     const ViewID scrollId = metrics->GetScrollId();
   284     const nsContentView* view =
   285       aFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId);
   286     NS_ABORT_IF_FALSE(view, "Array of views should be consistent with layer tree");
   287     gfx3DMatrix currentTransform;
   288     To3DMatrix(aLayer->GetTransform(), currentTransform);
   290     const ViewConfig& config = view->GetViewConfig();
   291     // With temporary scale we should compensate translation
   292     // using temporary scale value
   293     aTempScaleDiffX *= GetXScale(shadowTransform) * config.mXScale;
   294     aTempScaleDiffY *= GetYScale(shadowTransform) * config.mYScale;
   295     ViewTransform viewTransform = ComputeShadowTreeTransform(
   296       aFrame, aFrameLoader, metrics, view->GetViewConfig(),
   297       aTempScaleDiffX, aTempScaleDiffY
   298     );
   300     // Apply the layer's own transform *before* the view transform
   301     shadowTransform = gfx3DMatrix(viewTransform) * currentTransform;
   303     layerTransform = viewTransform;
   304     if (metrics->IsRootScrollable()) {
   305       // Apply the translation *before* we do the rest of the transforms.
   306       nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
   307       shadowTransform = shadowTransform *
   308           gfx3DMatrix::Translation(float(offset.x), float(offset.y), 0.0);
   309     }
   310   }
   312   if (aLayer->GetIsFixedPosition() &&
   313       !aLayer->GetParent()->GetIsFixedPosition()) {
   314     // Alter the shadow transform of fixed position layers in the situation
   315     // that the view transform's scroll position doesn't match the actual
   316     // scroll position, due to asynchronous layer scrolling.
   317     float offsetX = layerTransform.mTranslation.x;
   318     float offsetY = layerTransform.mTranslation.y;
   319     ReverseTranslate(shadowTransform, gfxPoint(offsetX, offsetY));
   320     const nsIntRect* clipRect = shadow->GetShadowClipRect();
   321     if (clipRect) {
   322       nsIntRect transformedClipRect(*clipRect);
   323       transformedClipRect.MoveBy(-offsetX, -offsetY);
   324       shadow->SetShadowClipRect(&transformedClipRect);
   325     }
   326   }
   328   // The transform already takes the resolution scale into account.  Since we
   329   // will apply the resolution scale again when computing the effective
   330   // transform, we must apply the inverse resolution scale here.
   331   if (ContainerLayer* c = aLayer->AsContainerLayer()) {
   332     shadowTransform.Scale(1.0f/c->GetPreXScale(),
   333                           1.0f/c->GetPreYScale(),
   334                           1);
   335   }
   336   shadowTransform.ScalePost(1.0f/aLayer->GetPostXScale(),
   337                             1.0f/aLayer->GetPostYScale(),
   338                             1);
   340   gfx::Matrix4x4 realShadowTransform;
   341   ToMatrix4x4(shadowTransform, realShadowTransform);
   342   shadow->SetShadowTransform(realShadowTransform);
   343   for (Layer* child = aLayer->GetFirstChild();
   344        child; child = child->GetNextSibling()) {
   345     TransformShadowTree(aBuilder, aFrameLoader, aFrame, child, layerTransform,
   346                         aTempScaleDiffX, aTempScaleDiffY);
   347   }
   348 }
   350 static void
   351 ClearContainer(ContainerLayer* aContainer)
   352 {
   353   while (Layer* layer = aContainer->GetFirstChild()) {
   354     aContainer->RemoveChild(layer);
   355   }
   356 }
   358 // Return true iff |aManager| is a "temporary layer manager".  They're
   359 // used for small software rendering tasks, like drawWindow.  That's
   360 // currently implemented by a BasicLayerManager without a backing
   361 // widget, and hence in non-retained mode.
   362 inline static bool
   363 IsTempLayerManager(LayerManager* aManager)
   364 {
   365   return (mozilla::layers::LayersBackend::LAYERS_BASIC == aManager->GetBackendType() &&
   366           !static_cast<BasicLayerManager*>(aManager)->IsRetained());
   367 }
   369 // Recursively create a new array of scrollables, preserving any scrollables
   370 // that are still in the layer tree.
   371 //
   372 // aXScale and aYScale are used to calculate any values that need to be in
   373 // chrome-document CSS pixels and aren't part of the rendering loop, such as
   374 // the initial scroll offset for a new view.
   375 static void
   376 BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
   377              nsFrameLoader* aFrameLoader, Layer* aLayer,
   378              float aXScale = 1, float aYScale = 1,
   379              float aAccConfigXScale = 1, float aAccConfigYScale = 1)
   380 {
   381   ContainerLayer* container = aLayer->AsContainerLayer();
   382   if (!container)
   383     return;
   384   const FrameMetrics metrics = container->GetFrameMetrics();
   385   const ViewID scrollId = metrics.GetScrollId();
   386   gfx3DMatrix transform;
   387   To3DMatrix(aLayer->GetTransform(), transform);
   388   aXScale *= GetXScale(transform);
   389   aYScale *= GetYScale(transform);
   391   if (metrics.IsScrollable()) {
   392     nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent()
   393                                         ->PresContext()->AppUnitsPerDevPixel();
   394     nscoord auPerCSSPixel = auPerDevPixel * metrics.mDevPixelsPerCSSPixel.scale;
   395     nsContentView* view = FindViewForId(oldContentViews, scrollId);
   396     if (view) {
   397       // View already exists. Be sure to propagate scales for any values
   398       // that need to be calculated something in chrome-doc CSS pixels.
   399       ViewConfig config = view->GetViewConfig();
   400       aXScale *= config.mXScale;
   401       aYScale *= config.mYScale;
   402       view->mFrameLoader = aFrameLoader;
   403       // If scale has changed, then we should update
   404       // current scroll offset to new scaled value
   405       if (aAccConfigXScale != view->mParentScaleX ||
   406           aAccConfigYScale != view->mParentScaleY) {
   407         float xscroll = 0, yscroll = 0;
   408         view->GetScrollX(&xscroll);
   409         view->GetScrollY(&yscroll);
   410         xscroll = xscroll * (aAccConfigXScale / view->mParentScaleX);
   411         yscroll = yscroll * (aAccConfigYScale / view->mParentScaleY);
   412         view->ScrollTo(xscroll, yscroll);
   413         view->mParentScaleX = aAccConfigXScale;
   414         view->mParentScaleY = aAccConfigYScale;
   415       }
   416       // Collect only config scale values for scroll compensation
   417       aAccConfigXScale *= config.mXScale;
   418       aAccConfigYScale *= config.mYScale;
   419     } else {
   420       // View doesn't exist, so generate one. We start the view scroll offset at
   421       // the same position as the framemetric's scroll offset from the layer.
   422       // The default scale is 1, so no need to propagate scale down.
   423       ViewConfig config;
   424       config.mScrollOffset = nsPoint(
   425         NSIntPixelsToAppUnits(metrics.GetScrollOffset().x, auPerCSSPixel) * aXScale,
   426         NSIntPixelsToAppUnits(metrics.GetScrollOffset().y, auPerCSSPixel) * aYScale);
   427       view = new nsContentView(aFrameLoader, scrollId, metrics.mIsRoot, config);
   428       view->mParentScaleX = aAccConfigXScale;
   429       view->mParentScaleY = aAccConfigYScale;
   430     }
   432     // I don't know what units mViewportSize is in, hence use ToUnknownRect
   433     // here to mark the current frontier in type info propagation
   434     gfx::Rect viewport = metrics.mViewport.ToUnknownRect();
   435     view->mViewportSize = nsSize(
   436       NSIntPixelsToAppUnits(viewport.width, auPerDevPixel) * aXScale,
   437       NSIntPixelsToAppUnits(viewport.height, auPerDevPixel) * aYScale);
   438     view->mContentSize = nsSize(
   439       NSFloatPixelsToAppUnits(metrics.mScrollableRect.width, auPerCSSPixel) * aXScale,
   440       NSFloatPixelsToAppUnits(metrics.mScrollableRect.height, auPerCSSPixel) * aYScale);
   442     newContentViews[scrollId] = view;
   443   }
   445   for (Layer* child = aLayer->GetFirstChild();
   446        child; child = child->GetNextSibling()) {
   447     BuildViewMap(oldContentViews, newContentViews, aFrameLoader, child,
   448                  aXScale, aYScale, aAccConfigXScale, aAccConfigYScale);
   449   }
   450 }
   452 static void
   453 BuildBackgroundPatternFor(ContainerLayer* aContainer,
   454                           Layer* aShadowRoot,
   455                           const ViewConfig& aConfig,
   456                           const gfxRGBA& aColor,
   457                           LayerManager* aManager,
   458                           nsIFrame* aFrame)
   459 {
   460   LayerComposite* shadowRoot = aShadowRoot->AsLayerComposite();
   461   gfx::Matrix t;
   462   if (!shadowRoot->GetShadowTransform().Is2D(&t)) {
   463     return;
   464   }
   466   // Get the rect bounding the shadow content, transformed into the
   467   // same space as |aFrame|
   468   nsIntRect contentBounds = shadowRoot->GetShadowVisibleRegion().GetBounds();
   469   gfxRect contentVis(contentBounds.x, contentBounds.y,
   470                      contentBounds.width, contentBounds.height);
   471   gfxRect localContentVis(gfx::ThebesMatrix(t).Transform(contentVis));
   472   // Round *in* here because this area is punched out of the background
   473   localContentVis.RoundIn();
   474   nsIntRect localIntContentVis(localContentVis.X(), localContentVis.Y(),
   475                                localContentVis.Width(), localContentVis.Height());
   477   // Get the frame's rect
   478   nscoord auPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
   479   nsIntRect frameRect = aFrame->GetRect().ToOutsidePixels(auPerDevPixel);
   481   // If the shadow tree covers the frame rect, don't bother building
   482   // the background, it wouldn't be visible
   483   if (localIntContentVis.Contains(frameRect)) {
   484     return;
   485   }
   486   nsRefPtr<ColorLayer> layer = aManager->CreateColorLayer();
   487   layer->SetColor(aColor);
   489   // The visible area of the background is the frame's area minus the
   490   // content area
   491   nsIntRegion bgRgn(frameRect);
   492   bgRgn.Sub(bgRgn, localIntContentVis);
   493   bgRgn.MoveBy(-frameRect.TopLeft());
   494   layer->SetVisibleRegion(bgRgn);
   496   aContainer->InsertAfter(layer, nullptr);
   497 }
   499 already_AddRefed<LayerManager>
   500 GetFrom(nsFrameLoader* aFrameLoader)
   501 {
   502   nsIDocument* doc = aFrameLoader->GetOwnerDoc();
   503   return nsContentUtils::LayerManagerForDocument(doc);
   504 }
   506 class RemoteContentController : public GeckoContentController {
   507 public:
   508   RemoteContentController(RenderFrameParent* aRenderFrame)
   509     : mUILoop(MessageLoop::current())
   510     , mRenderFrame(aRenderFrame)
   511     , mHaveZoomConstraints(false)
   512   { }
   514   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) MOZ_OVERRIDE
   515   {
   516     // We always need to post requests into the "UI thread" otherwise the
   517     // requests may get processed out of order.
   518     mUILoop->PostTask(
   519       FROM_HERE,
   520       NewRunnableMethod(this, &RemoteContentController::DoRequestContentRepaint,
   521                         aFrameMetrics));
   522   }
   524   virtual void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
   525                                        const uint32_t& aScrollGeneration) MOZ_OVERRIDE
   526   {
   527     if (MessageLoop::current() != mUILoop) {
   528       // We have to send this message from the "UI thread" (main
   529       // thread).
   530       mUILoop->PostTask(
   531         FROM_HERE,
   532         NewRunnableMethod(this, &RemoteContentController::AcknowledgeScrollUpdate,
   533                           aScrollId, aScrollGeneration));
   534       return;
   535     }
   536     if (mRenderFrame) {
   537       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   538       browser->AcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
   539     }
   540   }
   542   virtual void HandleDoubleTap(const CSSPoint& aPoint,
   543                                int32_t aModifiers,
   544                                const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE
   545   {
   546     if (MessageLoop::current() != mUILoop) {
   547       // We have to send this message from the "UI thread" (main
   548       // thread).
   549       mUILoop->PostTask(
   550         FROM_HERE,
   551         NewRunnableMethod(this, &RemoteContentController::HandleDoubleTap,
   552                           aPoint, aModifiers, aGuid));
   553       return;
   554     }
   555     if (mRenderFrame) {
   556       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   557       browser->HandleDoubleTap(aPoint, aModifiers, aGuid);
   558     }
   559   }
   561   virtual void HandleSingleTap(const CSSPoint& aPoint,
   562                                int32_t aModifiers,
   563                                const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE
   564   {
   565     if (MessageLoop::current() != mUILoop) {
   566       // We have to send this message from the "UI thread" (main
   567       // thread).
   568       mUILoop->PostTask(
   569         FROM_HERE,
   570         NewRunnableMethod(this, &RemoteContentController::HandleSingleTap,
   571                           aPoint, aModifiers, aGuid));
   572       return;
   573     }
   574     if (mRenderFrame) {
   575       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   576       browser->HandleSingleTap(aPoint, aModifiers, aGuid);
   577     }
   578   }
   580   virtual void HandleLongTap(const CSSPoint& aPoint,
   581                              int32_t aModifiers,
   582                              const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE
   583   {
   584     if (MessageLoop::current() != mUILoop) {
   585       // We have to send this message from the "UI thread" (main
   586       // thread).
   587       mUILoop->PostTask(
   588         FROM_HERE,
   589         NewRunnableMethod(this, &RemoteContentController::HandleLongTap,
   590                           aPoint, aModifiers, aGuid));
   591       return;
   592     }
   593     if (mRenderFrame) {
   594       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   595       browser->HandleLongTap(aPoint, aModifiers, aGuid);
   596     }
   597   }
   599   virtual void HandleLongTapUp(const CSSPoint& aPoint,
   600                                int32_t aModifiers,
   601                                const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE
   602   {
   603     if (MessageLoop::current() != mUILoop) {
   604       // We have to send this message from the "UI thread" (main
   605       // thread).
   606       mUILoop->PostTask(
   607         FROM_HERE,
   608         NewRunnableMethod(this, &RemoteContentController::HandleLongTapUp,
   609                           aPoint, aModifiers, aGuid));
   610       return;
   611     }
   612     if (mRenderFrame) {
   613       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   614       browser->HandleLongTapUp(aPoint, aModifiers, aGuid);
   615     }
   616   }
   618   void ClearRenderFrame() { mRenderFrame = nullptr; }
   620   virtual void SendAsyncScrollDOMEvent(bool aIsRoot,
   621                                        const CSSRect& aContentRect,
   622                                        const CSSSize& aContentSize) MOZ_OVERRIDE
   623   {
   624     if (MessageLoop::current() != mUILoop) {
   625       mUILoop->PostTask(
   626         FROM_HERE,
   627         NewRunnableMethod(this,
   628                           &RemoteContentController::SendAsyncScrollDOMEvent,
   629                           aIsRoot, aContentRect, aContentSize));
   630       return;
   631     }
   632     if (mRenderFrame && aIsRoot) {
   633       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   634       BrowserElementParent::DispatchAsyncScrollEvent(browser, aContentRect,
   635                                                      aContentSize);
   636     }
   637   }
   639   virtual void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE
   640   {
   641     MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
   642   }
   644   virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints)
   645   {
   646     if (mHaveZoomConstraints && aOutConstraints) {
   647       *aOutConstraints = mZoomConstraints;
   648     }
   649     return mHaveZoomConstraints;
   650   }
   652   virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion)
   653   {
   654     if (mTouchSensitiveRegion.IsEmpty())
   655       return false;
   657     *aOutRegion = CSSRect::FromAppUnits(mTouchSensitiveRegion.GetBounds());
   658     return true;
   659   }
   661   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
   662                                     APZStateChange aChange,
   663                                     int aArg)
   664   {
   665     if (MessageLoop::current() != mUILoop) {
   666       mUILoop->PostTask(
   667         FROM_HERE,
   668         NewRunnableMethod(this, &RemoteContentController::NotifyAPZStateChange,
   669                           aGuid, aChange, aArg));
   670       return;
   671     }
   672     if (mRenderFrame) {
   673       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   674       browser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
   675     }
   676   }
   678   // Methods used by RenderFrameParent to set fields stored here.
   680   void SaveZoomConstraints(const ZoomConstraints& aConstraints)
   681   {
   682     mHaveZoomConstraints = true;
   683     mZoomConstraints = aConstraints;
   684   }
   686   void SetTouchSensitiveRegion(const nsRegion& aRegion)
   687   {
   688     mTouchSensitiveRegion = aRegion;
   689   }
   690 private:
   691   void DoRequestContentRepaint(const FrameMetrics& aFrameMetrics)
   692   {
   693     if (mRenderFrame) {
   694       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
   695       browser->UpdateFrame(aFrameMetrics);
   696     }
   697   }
   699   MessageLoop* mUILoop;
   700   RenderFrameParent* mRenderFrame;
   702   bool mHaveZoomConstraints;
   703   ZoomConstraints mZoomConstraints;
   704   nsRegion mTouchSensitiveRegion;
   705 };
   707 RenderFrameParent::RenderFrameParent()
   708   : mLayersId(0)
   709   , mFrameLoaderDestroyed(false)
   710   , mBackgroundColor(gfxRGBA(1, 1, 1))
   711 {
   712 }
   714 void
   715 RenderFrameParent::Init(nsFrameLoader* aFrameLoader,
   716                         ScrollingBehavior aScrollingBehavior,
   717                         TextureFactoryIdentifier* aTextureFactoryIdentifier,
   718                         uint64_t* aId)
   719 {
   720   mFrameLoader = aFrameLoader;
   722   *aId = 0;
   724   nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
   725   // Perhaps the document containing this frame currently has no presentation?
   726   if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
   727     *aTextureFactoryIdentifier =
   728       static_cast<ClientLayerManager*>(lm.get())->GetTextureFactoryIdentifier();
   729   } else {
   730     *aTextureFactoryIdentifier = TextureFactoryIdentifier();
   731   }
   733   if (lm && lm->GetRoot() && lm->GetRoot()->AsContainerLayer()) {
   734     ViewID rootScrollId = lm->GetRoot()->AsContainerLayer()->GetFrameMetrics().GetScrollId();
   735     if (rootScrollId != FrameMetrics::NULL_SCROLL_ID) {
   736       mContentViews[rootScrollId] = new nsContentView(aFrameLoader, rootScrollId, true);
   737     }
   738   }
   740   if (CompositorParent::CompositorLoop()) {
   741     // Our remote frame will push layers updates to the compositor,
   742     // and we'll keep an indirect reference to that tree.
   743     *aId = mLayersId = CompositorParent::AllocateLayerTreeId();
   744     if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
   745       ClientLayerManager *clientManager = static_cast<ClientLayerManager*>(lm.get());
   746       clientManager->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId);
   747     }
   748     if (aScrollingBehavior == ASYNC_PAN_ZOOM) {
   749       mContentController = new RemoteContentController(this);
   750       CompositorParent::SetControllerForLayerTree(mLayersId, mContentController);
   751     }
   752   }
   753   // Set a default RenderFrameParent
   754   mFrameLoader->SetCurrentRemoteFrame(this);
   755 }
   757 APZCTreeManager*
   758 RenderFrameParent::GetApzcTreeManager()
   759 {
   760   // We can't get a ref to the APZCTreeManager until after the child is
   761   // created and the static getter knows which CompositorParent is
   762   // instantiated with this layers ID. That's why try to fetch it when
   763   // we first need it and cache the result.
   764   if (!mApzcTreeManager) {
   765     mApzcTreeManager = CompositorParent::GetAPZCTreeManager(mLayersId);
   766   }
   767   return mApzcTreeManager.get();
   768 }
   770 RenderFrameParent::~RenderFrameParent()
   771 {}
   773 void
   774 RenderFrameParent::Destroy()
   775 {
   776   size_t numChildren = ManagedPLayerTransactionParent().Length();
   777   NS_ABORT_IF_FALSE(0 == numChildren || 1 == numChildren,
   778                     "render frame must only have 0 or 1 layer manager");
   780   if (numChildren) {
   781     LayerTransactionParent* layers =
   782       static_cast<LayerTransactionParent*>(ManagedPLayerTransactionParent()[0]);
   783     layers->Destroy();
   784   }
   786   mFrameLoaderDestroyed = true;
   787 }
   789 nsContentView*
   790 RenderFrameParent::GetContentView(ViewID aId)
   791 {
   792   return FindViewForId(mContentViews, aId);
   793 }
   795 nsContentView*
   796 RenderFrameParent::GetRootContentView()
   797 {
   798   return FindRootView(mContentViews);
   799 }
   801 void
   802 RenderFrameParent::ContentViewScaleChanged(nsContentView* aView)
   803 {
   804   // Since the scale has changed for a view, it and its descendents need their
   805   // shadow-space attributes updated. It's easiest to rebuild the view map.
   806   BuildViewMap();
   807 }
   809 void
   810 RenderFrameParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
   811                                        const TargetConfig& aTargetConfig,
   812                                        bool aIsFirstPaint,
   813                                        bool aScheduleComposite)
   814 {
   815   // View map must only contain views that are associated with the current
   816   // shadow layer tree. We must always update the map when shadow layers
   817   // are updated.
   818   BuildViewMap();
   820   TriggerRepaint();
   821 }
   823 already_AddRefed<Layer>
   824 RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
   825                               nsIFrame* aFrame,
   826                               LayerManager* aManager,
   827                               const nsIntRect& aVisibleRect,
   828                               nsDisplayItem* aItem,
   829                               const ContainerLayerParameters& aContainerParameters)
   830 {
   831   NS_ABORT_IF_FALSE(aFrame,
   832                     "makes no sense to have a shadow tree without a frame");
   833   NS_ABORT_IF_FALSE(!mContainer ||
   834                     IsTempLayerManager(aManager) ||
   835                     mContainer->Manager() == aManager,
   836                     "retaining manager changed out from under us ... HELP!");
   838   if (IsTempLayerManager(aManager) ||
   839       (mContainer && mContainer->Manager() != aManager)) {
   840     // This can happen if aManager is a "temporary" manager, or if the
   841     // widget's layer manager changed out from under us.  We need to
   842     // FIXME handle the former case somehow, probably with an API to
   843     // draw a manager's subtree.  The latter is bad bad bad, but the
   844     // the NS_ABORT_IF_FALSE() above will flag it.  Returning nullptr
   845     // here will just cause the shadow subtree not to be rendered.
   846     NS_WARNING("Remote iframe not rendered");
   847     return nullptr;
   848   }
   850   uint64_t id = GetLayerTreeId();
   851   if (0 != id) {
   852     MOZ_ASSERT(!GetRootLayer());
   854     nsRefPtr<Layer> layer =
   855       (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
   856     if (!layer) {
   857       layer = aManager->CreateRefLayer();
   858     }
   859     if (!layer) {
   860       // Probably a temporary layer manager that doesn't know how to
   861       // use ref layers.
   862       return nullptr;
   863     }
   864     static_cast<RefLayer*>(layer.get())->SetReferentId(id);
   865     nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
   866     layer->SetVisibleRegion(aVisibleRect - offset);
   867     // We can only have an offset if we're a child of an inactive
   868     // container, but our display item is LAYER_ACTIVE_FORCE which
   869     // forces all layers above to be active.
   870     MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
   871     gfx::Matrix4x4 m;
   872     m.Translate(offset.x, offset.y, 0.0);
   873     // Remote content can't be repainted by us, so we multiply down
   874     // the resolution that our container expects onto our container.
   875     m.Scale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
   876     layer->SetBaseTransform(m);
   878     return layer.forget();
   879   }
   881   if (mContainer) {
   882     ClearContainer(mContainer);
   883     mContainer->SetPreScale(1.0f, 1.0f);
   884     mContainer->SetPostScale(1.0f, 1.0f);
   885     mContainer->SetInheritedScale(1.0f, 1.0f);
   886   }
   888   Layer* shadowRoot = GetRootLayer();
   889   if (!shadowRoot) {
   890     mContainer = nullptr;
   891     return nullptr;
   892   }
   894   NS_ABORT_IF_FALSE(!shadowRoot || shadowRoot->Manager() == aManager,
   895                     "retaining manager changed out from under us ... HELP!");
   897   // Wrap the shadow layer tree in mContainer.
   898   if (!mContainer) {
   899     mContainer = aManager->CreateContainerLayer();
   900   }
   901   NS_ABORT_IF_FALSE(!mContainer->GetFirstChild(),
   902                     "container of shadow tree shouldn't have a 'root' here");
   904   mContainer->InsertAfter(shadowRoot, nullptr);
   906   AssertInTopLevelChromeDoc(mContainer, aFrame);
   907   ViewTransform transform;
   908   TransformShadowTree(aBuilder, mFrameLoader, aFrame, shadowRoot, transform);
   909   mContainer->SetClipRect(nullptr);
   911   if (mFrameLoader->AsyncScrollEnabled()) {
   912     const nsContentView* view = GetRootContentView();
   913     BuildBackgroundPatternFor(mContainer,
   914                               shadowRoot,
   915                               view->GetViewConfig(),
   916                               mBackgroundColor,
   917                               aManager, aFrame);
   918   }
   919   mContainer->SetVisibleRegion(aVisibleRect);
   921   return nsRefPtr<Layer>(mContainer).forget();
   922 }
   924 void
   925 RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
   926 {
   927   NS_ABORT_IF_FALSE(mFrameLoader->GetOwnerContent() == aContent,
   928                     "Don't build new map if owner is same!");
   929   BuildViewMap();
   930 }
   932 void
   933 RenderFrameParent::NotifyInputEvent(WidgetInputEvent& aEvent,
   934                                     ScrollableLayerGuid* aOutTargetGuid)
   935 {
   936   if (GetApzcTreeManager()) {
   937     GetApzcTreeManager()->ReceiveInputEvent(aEvent, aOutTargetGuid);
   938   }
   939 }
   941 void
   942 RenderFrameParent::ActorDestroy(ActorDestroyReason why)
   943 {
   944   if (mLayersId != 0) {
   945     CompositorParent::DeallocateLayerTreeId(mLayersId);
   946     if (mContentController) {
   947       // Stop our content controller from requesting repaints of our
   948       // content.
   949       mContentController->ClearRenderFrame();
   950       // TODO: notify the compositor?
   951     }
   952   }
   954   if (mFrameLoader && mFrameLoader->GetCurrentRemoteFrame() == this) {
   955     // XXX this might cause some weird issues ... we'll just not
   956     // redraw the part of the window covered by this until the "next"
   957     // remote frame has a layer-tree transaction.  For
   958     // why==NormalShutdown, we'll definitely want to do something
   959     // better, especially as nothing guarantees another Update() from
   960     // the "next" remote layer tree.
   961     mFrameLoader->SetCurrentRemoteFrame(nullptr);
   962   }
   963   mFrameLoader = nullptr;
   964 }
   966 bool
   967 RenderFrameParent::RecvNotifyCompositorTransaction()
   968 {
   969   TriggerRepaint();
   970   return true;
   971 }
   973 bool
   974 RenderFrameParent::RecvUpdateHitRegion(const nsRegion& aRegion)
   975 {
   976   mTouchRegion = aRegion;
   977   if (mContentController) {
   978     // Tell the content controller about the touch-sensitive region, so
   979     // that it can provide it to APZ. This is required for APZ to do
   980     // correct hit testing for a remote 'mozpasspointerevents' iframe
   981     // until bug 928833 is fixed.
   982     mContentController->SetTouchSensitiveRegion(aRegion);
   983   }
   984   return true;
   985 }
   987 PLayerTransactionParent*
   988 RenderFrameParent::AllocPLayerTransactionParent()
   989 {
   990   if (!mFrameLoader || mFrameLoaderDestroyed) {
   991     return nullptr;
   992   }
   993   nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
   994   LayerTransactionParent* result = new LayerTransactionParent(lm->AsLayerManagerComposite(), this, 0);
   995   result->AddIPDLReference();
   996   return result;
   997 }
   999 bool
  1000 RenderFrameParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
  1002   static_cast<LayerTransactionParent*>(aLayers)->ReleaseIPDLReference();
  1003   return true;
  1006 void
  1007 RenderFrameParent::BuildViewMap()
  1009   ViewMap newContentViews;
  1010   // BuildViewMap assumes we have a primary frame, which may not be the case.
  1011   if (GetRootLayer() && mFrameLoader->GetPrimaryFrameOfOwningContent()) {
  1012     // Some of the content views in our hash map may no longer be active. To
  1013     // tag them as inactive and to remove any chance of them using a dangling
  1014     // pointer, we set mContentView to nullptr.
  1015     //
  1016     // BuildViewMap will restore mFrameLoader if the content view is still
  1017     // in our hash table.
  1019     for (ViewMap::const_iterator iter = mContentViews.begin();
  1020          iter != mContentViews.end();
  1021          ++iter) {
  1022       iter->second->mFrameLoader = nullptr;
  1025     mozilla::layout::BuildViewMap(mContentViews, newContentViews, mFrameLoader, GetRootLayer());
  1028   // Here, we guarantee that *only* the root view is preserved in
  1029   // case we couldn't build a new view map above. This is important because
  1030   // the content view map should only contain the root view and content
  1031   // views that are present in the layer tree.
  1032   if (newContentViews.empty()) {
  1033     nsContentView* rootView = FindRootView(mContentViews);
  1034     if (rootView)
  1035       newContentViews[rootView->GetId()] = rootView;
  1038   mContentViews = newContentViews;
  1041 void
  1042 RenderFrameParent::TriggerRepaint()
  1044   mFrameLoader->SetCurrentRemoteFrame(this);
  1046   nsIFrame* docFrame = mFrameLoader->GetPrimaryFrameOfOwningContent();
  1047   if (!docFrame) {
  1048     // Bad, but nothing we can do about it (XXX/cjones: or is there?
  1049     // maybe bug 589337?).  When the new frame is created, we'll
  1050     // probably still be the current render frame and will get to draw
  1051     // our content then.  Or, we're shutting down and this update goes
  1052     // to /dev/null.
  1053     return;
  1056   docFrame->InvalidateLayer(nsDisplayItem::TYPE_REMOTE);
  1059 LayerTransactionParent*
  1060 RenderFrameParent::GetShadowLayers() const
  1062   const InfallibleTArray<PLayerTransactionParent*>& shadowParents = ManagedPLayerTransactionParent();
  1063   NS_ABORT_IF_FALSE(shadowParents.Length() <= 1,
  1064                     "can only support at most 1 LayerTransactionParent");
  1065   return (shadowParents.Length() == 1) ?
  1066     static_cast<LayerTransactionParent*>(shadowParents[0]) : nullptr;
  1069 uint64_t
  1070 RenderFrameParent::GetLayerTreeId() const
  1072   return mLayersId;
  1075 Layer*
  1076 RenderFrameParent::GetRootLayer() const
  1078   LayerTransactionParent* shadowLayers = GetShadowLayers();
  1079   return shadowLayers ? shadowLayers->GetRoot() : nullptr;
  1082 void
  1083 RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
  1084                                     nsSubDocumentFrame* aFrame,
  1085                                     const nsRect& aDirtyRect,
  1086                                     const nsDisplayListSet& aLists)
  1088   // We're the subdoc for <browser remote="true"> and it has
  1089   // painted content.  Display its shadow layer tree.
  1090   DisplayListClipState::AutoSaveRestore clipState(aBuilder);
  1092   nsPoint offset = aBuilder->ToReferenceFrame(aFrame);
  1093   nsRect bounds = aFrame->EnsureInnerView()->GetBounds() + offset;
  1094   clipState.ClipContentDescendants(bounds);
  1096   Layer* container = GetRootLayer();
  1097   if (aBuilder->IsForEventDelivery() && container) {
  1098     ViewTransform offset =
  1099       ViewTransform(GetContentRectLayerOffset(aFrame, aBuilder));
  1100     BuildListForLayer(container, mFrameLoader, offset,
  1101                       aBuilder, *aLists.Content(), aFrame);
  1102   } else {
  1103     aLists.Content()->AppendToTop(
  1104       new (aBuilder) nsDisplayRemote(aBuilder, aFrame, this));
  1108 void
  1109 RenderFrameParent::ZoomToRect(uint32_t aPresShellId, ViewID aViewId,
  1110                               const CSSRect& aRect)
  1112   if (GetApzcTreeManager()) {
  1113     GetApzcTreeManager()->ZoomToRect(ScrollableLayerGuid(mLayersId, aPresShellId, aViewId),
  1114                                      aRect);
  1118 void
  1119 RenderFrameParent::ContentReceivedTouch(const ScrollableLayerGuid& aGuid,
  1120                                         bool aPreventDefault)
  1122   if (aGuid.mLayersId != mLayersId) {
  1123     // Guard against bad data from hijacked child processes
  1124     NS_ERROR("Unexpected layers id in ContentReceivedTouch; dropping message...");
  1125     return;
  1127   if (GetApzcTreeManager()) {
  1128     GetApzcTreeManager()->ContentReceivedTouch(aGuid, aPreventDefault);
  1132 void
  1133 RenderFrameParent::UpdateZoomConstraints(uint32_t aPresShellId,
  1134                                          ViewID aViewId,
  1135                                          bool aIsRoot,
  1136                                          const ZoomConstraints& aConstraints)
  1138   if (mContentController && aIsRoot) {
  1139     mContentController->SaveZoomConstraints(aConstraints);
  1141   if (GetApzcTreeManager()) {
  1142     GetApzcTreeManager()->UpdateZoomConstraints(ScrollableLayerGuid(mLayersId, aPresShellId, aViewId),
  1143                                                 aConstraints);
  1147 bool
  1148 RenderFrameParent::HitTest(const nsRect& aRect)
  1150   return mTouchRegion.Contains(aRect);
  1153 }  // namespace layout
  1154 }  // namespace mozilla
  1156 already_AddRefed<Layer>
  1157 nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
  1158                             LayerManager* aManager,
  1159                             const ContainerLayerParameters& aContainerParameters)
  1161   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
  1162   nsIntRect visibleRect = GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
  1163   visibleRect += aContainerParameters.mOffset;
  1164   nsRefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, visibleRect, this, aContainerParameters);
  1165   return layer.forget();
  1168 void
  1169 nsDisplayRemote::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1170                          HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
  1172   if (mRemoteFrame->HitTest(aRect)) {
  1173     aOutFrames->AppendElement(mFrame);
  1177 void
  1178 nsDisplayRemoteShadow::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
  1179                          HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
  1181   // If we are here, then rects have intersected.
  1182   //
  1183   // XXX I think iframes and divs can be rounded like anything else but we don't
  1184   //     cover that case here.
  1185   //
  1186   if (aState->mShadows) {
  1187     aState->mShadows->AppendElement(mId);

mercurial