Bug 1056427 - Stop PRenderFrame from managing PLayerTransaction since it hasn't worked since the layers refactoring. r=roc

--HG--
extra : rebase_source : 38c86648bb8e59a6b992bd377acb9aacb418c98b
This commit is contained in:
Matt Woodrow 2014-08-22 12:16:44 +12:00
parent e9fb2caf27
commit c2d79a26ff
16 changed files with 62 additions and 901 deletions

View File

@ -146,10 +146,6 @@ nsContentView::Update(const ViewConfig& aConfig)
}
}
if (RenderFrameParent* rfp = mFrameLoader->GetCurrentRemoteFrame()) {
rfp->ContentViewScaleChanged(this);
}
return NS_OK;
}
@ -2394,34 +2390,8 @@ nsFrameLoader::GetContentViewsIn(float aXPx, float aYPx,
uint32_t* aLength,
nsIContentView*** aResult)
{
nscoord x = nsPresContext::CSSPixelsToAppUnits(aXPx - aLeftSize);
nscoord y = nsPresContext::CSSPixelsToAppUnits(aYPx - aTopSize);
nscoord w = nsPresContext::CSSPixelsToAppUnits(aLeftSize + aRightSize) + 1;
nscoord h = nsPresContext::CSSPixelsToAppUnits(aTopSize + aBottomSize) + 1;
nsRect target(x, y, w, h);
nsIFrame* frame = GetPrimaryFrameOfOwningContent();
nsTArray<ViewID> ids;
nsLayoutUtils::GetRemoteContentIds(frame, target, ids, true);
if (ids.Length() == 0 || !GetCurrentRemoteFrame()) {
*aResult = nullptr;
*aLength = 0;
return NS_OK;
}
nsIContentView** result = reinterpret_cast<nsIContentView**>(
NS_Alloc(ids.Length() * sizeof(nsIContentView*)));
for (uint32_t i = 0; i < ids.Length(); i++) {
nsIContentView* view = GetCurrentRemoteFrame()->GetContentView(ids[i]);
NS_ABORT_IF_FALSE(view, "Retrieved ID from RenderFrameParent, it should be valid!");
nsRefPtr<nsIContentView>(view).forget(&result[i]);
}
*aResult = result;
*aLength = ids.Length();
*aResult = nullptr;
*aLength = 0;
return NS_OK;
}

View File

@ -1452,12 +1452,6 @@ TabChild::DestroyWindow()
}
}
bool
TabChild::UseDirectCompositor()
{
return !!CompositorChild::Get();
}
void
TabChild::ActorDestroy(ActorDestroyReason why)
{
@ -2569,28 +2563,23 @@ TabChild::InitRenderingState()
return false;
}
PLayerTransactionChild* shadowManager = nullptr;
if (id != 0) {
// Pushing layers transactions directly to a separate
// compositor context.
PCompositorChild* compositorChild = CompositorChild::Get();
if (!compositorChild) {
NS_WARNING("failed to get CompositorChild instance");
return false;
}
nsTArray<LayersBackend> backends;
backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
bool success;
shadowManager =
compositorChild->SendPLayerTransactionConstructor(backends,
id, &mTextureFactoryIdentifier, &success);
if (!success) {
NS_WARNING("failed to properly allocate layer transaction");
return false;
}
} else {
// Pushing transactions to the parent content.
shadowManager = remoteFrame->SendPLayerTransactionConstructor();
MOZ_ASSERT(id != 0);
// Pushing layers transactions directly to a separate
// compositor context.
PCompositorChild* compositorChild = CompositorChild::Get();
if (!compositorChild) {
NS_WARNING("failed to get CompositorChild instance");
return false;
}
nsTArray<LayersBackend> backends;
backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
PLayerTransactionChild* shadowManager =
compositorChild->SendPLayerTransactionConstructor(backends,
id, &mTextureFactoryIdentifier, &success);
if (!success) {
NS_WARNING("failed to properly allocate layer transaction");
return false;
}
if (!shadowManager) {
@ -2672,7 +2661,7 @@ TabChild::GetDefaultScale(double* aScale)
void
TabChild::NotifyPainted()
{
if (UseDirectCompositor() && !mNotified) {
if (!mNotified) {
mRemoteFrame->SendNotifyCompositorTransaction();
mNotified = true;
}

View File

@ -517,8 +517,6 @@ private:
// call this during Init().
void NotifyTabContextUpdated();
bool UseDirectCompositor();
void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
enum FrameScriptLoading { DONT_LOAD_SCRIPTS, DEFAULT_LOAD_SCRIPTS };

View File

@ -451,7 +451,7 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
// forward this transaction's changeset to our LayerManagerComposite
bool sent;
AutoInfallibleTArray<EditReply, 10> replies;
if (HasShadowManager() && mForwarder->EndTransaction(&replies, mRegionToClear,
if (mForwarder->EndTransaction(&replies, mRegionToClear,
mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber,
mIsRepeatTransaction, &sent)) {
for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
@ -507,16 +507,17 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
if (sent) {
mNeedsComposite = false;
}
if (!sent || mForwarder->GetShadowManager()->HasNoCompositor()) {
// Clear the transaction id so that it doesn't get returned
// unless we forwarded to somewhere that doesn't actually
// have a compositor.
mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId);
}
} else if (HasShadowManager()) {
NS_WARNING("failed to forward Layers transaction");
}
if (!sent) {
// Clear the transaction id so that it doesn't get returned
// unless we forwarded to somewhere that doesn't actually
// have a compositor.
mTransactionIdAllocator->RevokeTransactionId(mLatestTransactionId);
}
mForwarder->RemoveTexturesIfNecessary();
mForwarder->SendPendingAsyncMessge();
mPhase = PHASE_NONE;

View File

@ -41,9 +41,6 @@ public:
bool IPCOpen() const { return mIPCOpen; }
void SetHasNoCompositor() { mHasNoCompositor = true; }
bool HasNoCompositor() { return mHasNoCompositor; }
void SetForwarder(ShadowLayerForwarder* aForwarder)
{
mForwarder = aForwarder;
@ -58,7 +55,6 @@ protected:
: mForwarder(nullptr)
, mIPCOpen(false)
, mDestroyed(false)
, mHasNoCompositor(false)
{}
~LayerTransactionChild() { }
@ -93,7 +89,6 @@ protected:
ShadowLayerForwarder* mForwarder;
bool mIPCOpen;
bool mDestroyed;
bool mHasNoCompositor;
};
} // namespace layers

View File

@ -37,7 +37,7 @@ union MaybeTransform {
};
sync protocol PLayerTransaction {
manager PCompositor or PRenderFrame;
manager PCompositor;
manages PLayer;
manages PCompositable;
manages PTexture;

View File

@ -505,8 +505,7 @@ gfxPlatform::InitLayersIPC()
AsyncTransactionTrackersHolder::Initialize();
if (UsesOffMainThreadCompositing() &&
XRE_GetProcessType() == GeckoProcessType_Default)
if (XRE_GetProcessType() == GeckoProcessType_Default)
{
mozilla::layers::CompositorParent::StartUp();
#ifndef MOZ_WIDGET_GONK
@ -528,8 +527,7 @@ gfxPlatform::ShutdownLayersIPC()
}
sLayersIPCIsUp = false;
if (UsesOffMainThreadCompositing() &&
XRE_GetProcessType() == GeckoProcessType_Default)
if (XRE_GetProcessType() == GeckoProcessType_Default)
{
// This must happen after the shutdown of media and widgets, which
// are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.

View File

@ -838,11 +838,7 @@ public:
#include "nsDisplayItemTypes.h"
struct HitTestState {
typedef nsTArray<ViewID> ShadowArray;
explicit HitTestState(ShadowArray* aShadows = nullptr)
: mShadows(aShadows) {
}
explicit HitTestState() {}
~HitTestState() {
NS_ASSERTION(mItemBuffer.Length() == 0,
@ -850,11 +846,6 @@ public:
}
nsAutoTArray<nsDisplayItem*, 100> mItemBuffer;
// It is sometimes useful to hit test for frames that are not in this
// process. Display items may append IDs into this array if it is
// non-null.
ShadowArray* mShadows;
};
/**

View File

@ -2618,36 +2618,6 @@ static bool gDumpEventList = false;
int gPaintCount = 0;
#endif
nsresult
nsLayoutUtils::GetRemoteContentIds(nsIFrame* aFrame,
const nsRect& aTarget,
nsTArray<ViewID> &aOutIDs,
bool aIgnoreRootScrollFrame)
{
nsDisplayListBuilder builder(aFrame, nsDisplayListBuilder::EVENT_DELIVERY,
false);
nsDisplayList list;
if (aIgnoreRootScrollFrame) {
nsIFrame* rootScrollFrame =
aFrame->PresContext()->PresShell()->GetRootScrollFrame();
if (rootScrollFrame) {
builder.SetIgnoreScrollFrame(rootScrollFrame);
}
}
builder.EnterPresShell(aFrame, aTarget);
aFrame->BuildDisplayListForStackingContext(&builder, aTarget, &list);
builder.LeavePresShell(aFrame, aTarget);
nsAutoTArray<nsIFrame*,8> outFrames;
nsDisplayItem::HitTestState hitTestState(&aOutIDs);
list.HitTest(&builder, aTarget, &hitTestState, &outFrames);
list.DeleteAll();
return NS_OK;
}
nsIFrame*
nsLayoutUtils::GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt, uint32_t aFlags)
{

View File

@ -663,23 +663,6 @@ public:
nsIWidget* aWidget, nsIntPoint aPt,
nsView* aView);
/**
* Find IDs corresponding to a scrollable content element in the child process.
* In correspondence with the shadow layer tree, you can use this to perform a
* hit test that corresponds to a specific shadow layer that you can then perform
* transformations on to do parent-side scrolling.
*
* @param aFrame The root frame of a stack context
* @param aTarget The rect to hit test relative to the frame origin
* @param aOutIDs All found IDs are added here
* @param aIgnoreRootScrollFrame a boolean to control if the display list
* builder should ignore the root scroll frame
*/
static nsresult GetRemoteContentIds(nsIFrame* aFrame,
const nsRect& aTarget,
nsTArray<ViewID> &aOutIDs,
bool aIgnoreRootScrollFrame);
enum FrameForPointFlags {
/**
* When set, paint suppression is ignored, so we'll return non-root page

View File

@ -26,38 +26,13 @@ namespace layout {
sync protocol PRenderFrame
{
manager PBrowser;
manages PLayerTransaction;
parent:
/**
* Shadow layer trees can be grafted into the parent's in one of
* two ways
* - direct shadow tree: updates are sent to parent
* - indirect: the parent holds a reference (ID) to a shadow tree
* that's managed by the compositor. During composition, the
* shadow tree is looked up and grafted appropriately
*
* |id| is set to 0 in the "direct" case, and to a whole number
* in the "indirect" case.
*/
async PLayerTransaction();
async NotifyCompositorTransaction();
async UpdateHitRegion(nsRegion aRegion);
async __delete__();
state EMPTY_OR_DIRECT_COMPOSITOR:
recv PLayerTransaction goto HAVE_CONTENT;
recv NotifyCompositorTransaction goto EMPTY_OR_DIRECT_COMPOSITOR;
recv UpdateHitRegion goto EMPTY_OR_DIRECT_COMPOSITOR;
recv __delete__;
state HAVE_CONTENT:
recv NotifyCompositorTransaction goto HAVE_CONTENT;
recv UpdateHitRegion goto HAVE_CONTENT;
recv __delete__;
};
} // namespace layout

View File

@ -17,40 +17,9 @@ namespace layout {
void
RenderFrameChild::Destroy()
{
size_t numChildren = ManagedPLayerTransactionChild().Length();
NS_ABORT_IF_FALSE(0 == numChildren || 1 == numChildren,
"render frame must only have 0 or 1 layer forwarder");
if (numChildren) {
LayerTransactionChild* layers =
static_cast<LayerTransactionChild*>(ManagedPLayerTransactionChild()[0]);
layers->Destroy();
// |layers| was just deleted, take care
}
Send__delete__(this);
// WARNING: |this| is dead, hands off
}
PLayerTransactionChild*
RenderFrameChild::AllocPLayerTransactionChild()
{
LayerTransactionChild* c = new LayerTransactionChild();
c->AddIPDLReference();
// We only create PLayerTransaction objects through PRenderFrame when we don't
// have a PCompositor. This means that the child process content will never
// get drawn to the screen, but some tests rely on it pretending to function
// for now.
c->SetHasNoCompositor();
return c;
}
bool
RenderFrameChild::DeallocPLayerTransactionChild(PLayerTransactionChild* aLayers)
{
static_cast<LayerTransactionChild*>(aLayers)->ReleaseIPDLReference();
return true;
}
} // namespace layout
} // namespace mozilla

View File

@ -20,10 +20,6 @@ public:
virtual ~RenderFrameChild() {}
void Destroy();
protected:
virtual PLayerTransactionChild* AllocPLayerTransactionChild() MOZ_OVERRIDE;
virtual bool DeallocPLayerTransactionChild(PLayerTransactionChild* aLayers) MOZ_OVERRIDE;
};
} // namespace layout

View File

@ -38,105 +38,6 @@ namespace mozilla {
namespace layout {
typedef FrameMetrics::ViewID ViewID;
typedef RenderFrameParent::ViewMap ViewMap;
// Represents (affine) transforms that are calculated from a content view.
struct ViewTransform {
ViewTransform(nsIntPoint aTranslation = nsIntPoint(0, 0), float aXScale = 1, float aYScale = 1)
: mTranslation(aTranslation)
, mXScale(aXScale)
, mYScale(aYScale)
{}
operator Matrix4x4() const
{
return
Matrix4x4().Translate(mTranslation.x, mTranslation.y, 0) *
Matrix4x4().Scale(mXScale, mYScale, 1);
}
nsIntPoint mTranslation;
float mXScale;
float mYScale;
};
// Matrix helpers
// For our simple purposes, these helpers apply to 2D affine transformations
// that can be represented by a scale and a translation. This makes the math
// much easier because we only expect the diagonals and the translation
// coordinates of the matrix to be non-zero.
static double GetXScale(const Matrix4x4& aTransform)
{
return aTransform._11;
}
static double GetYScale(const Matrix4x4& aTransform)
{
return aTransform._22;
}
static void Scale(Matrix4x4& aTransform, double aXScale, double aYScale)
{
aTransform._11 *= aXScale;
aTransform._22 *= aYScale;
}
static void ReverseTranslate(Matrix4x4& aTransform, const gfxPoint& aOffset)
{
aTransform._41 -= aOffset.x;
aTransform._42 -= aOffset.y;
}
static void ApplyTransform(nsRect& aRect,
Matrix4x4& aTransform,
nscoord auPerDevPixel)
{
aRect.x = aRect.x * aTransform._11 + aTransform._41 * auPerDevPixel;
aRect.y = aRect.y * aTransform._22 + aTransform._42 * auPerDevPixel;
aRect.width = aRect.width * aTransform._11;
aRect.height = aRect.height * aTransform._22;
}
static void
AssertInTopLevelChromeDoc(ContainerLayer* aContainer,
nsIFrame* aContainedFrame)
{
NS_ASSERTION(
(aContainer->Manager()->GetBackendType() != mozilla::layers::LayersBackend::LAYERS_BASIC) ||
(aContainedFrame->GetNearestWidget() ==
static_cast<BasicLayerManager*>(aContainer->Manager())->GetRetainerWidget()),
"Expected frame to be in top-level chrome document");
}
// Return view for given ID in aMap, nullptr if not found.
static nsContentView*
FindViewForId(const ViewMap& aMap, ViewID aId)
{
ViewMap::const_iterator iter = aMap.find(aId);
return iter != aMap.end() ? iter->second : nullptr;
}
// Return the root content view in aMap, nullptr if not found.
static nsContentView*
FindRootView(const ViewMap& aMap)
{
for (ViewMap::const_iterator iter = aMap.begin(), end = aMap.end();
iter != end;
++iter) {
if (iter->second->IsRoot())
return iter->second;
}
return nullptr;
}
static const FrameMetrics*
GetFrameMetrics(Layer* aLayer)
{
ContainerLayer* container = aLayer->AsContainerLayer();
return container ? &container->GetFrameMetrics() : nullptr;
}
/**
* Gets the layer-pixel offset of aContainerFrame's content rect top-left
@ -158,197 +59,6 @@ GetContentRectLayerOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuil
return frameOffset.ToNearestPixels(auPerDevPixel);
}
// Compute the transform of the shadow tree contained by
// |aContainerFrame| to widget space. We transform because the
// subprocess layer manager renders to a different top-left than where
// the shadow tree is drawn here and because a scale can be set on the
// shadow tree.
static ViewTransform
ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
nsFrameLoader* aRootFrameLoader,
const FrameMetrics* aMetrics,
const ViewConfig& aConfig,
float aTempScaleX = 1.0,
float aTempScaleY = 1.0)
{
// |aMetrics->mViewportScrollOffset| The frame's scroll offset when it was
// painted, in content document pixels.
// |aConfig.mScrollOffset| What our user expects, or wants, the
// frame scroll offset to be in chrome
// document app units.
//
// So we set a compensating translation that moves the content document
// pixels to where the user wants them to be.
//
nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
nsIntPoint scrollOffset =
aConfig.mScrollOffset.ToNearestPixels(auPerDevPixel);
LayerIntPoint metricsScrollOffset = RoundedToInt(aMetrics->GetScrollOffsetInLayerPixels());
if (aRootFrameLoader->AsyncScrollEnabled() && !aMetrics->mDisplayPort.IsEmpty()) {
// Only use asynchronous scrolling if it is enabled and there is a
// displayport defined. It is useful to have a scroll layer that is
// synchronously scrolled for identifying a scroll area before it is
// being actively scrolled.
nsIntPoint scrollCompensation(
(scrollOffset.x / aTempScaleX - metricsScrollOffset.x),
(scrollOffset.y / aTempScaleY - metricsScrollOffset.y));
return ViewTransform(-scrollCompensation, aConfig.mXScale, aConfig.mYScale);
} else {
return ViewTransform(nsIntPoint(0, 0), 1, 1);
}
}
// Use shadow layer tree to build display list for the browser's frame.
static void
BuildListForLayer(Layer* aLayer,
nsFrameLoader* aRootFrameLoader,
const Matrix4x4& aTransform,
nsDisplayListBuilder* aBuilder,
nsDisplayList& aShadowTree,
nsIFrame* aSubdocFrame)
{
const FrameMetrics* metrics = GetFrameMetrics(aLayer);
Matrix4x4 transform;
if (metrics && metrics->IsScrollable()) {
const ViewID scrollId = metrics->GetScrollId();
// We need to figure out the bounds of the scrollable region using the
// shadow layer tree from the remote process. The metrics viewport is
// defined based on all the transformations of its parent layers and
// the scale of the current layer.
// Calculate transform for this layer.
nsContentView* view =
aRootFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId);
// XXX why don't we include aLayer->GetTransform() in the inverse-scale here?
// This seems wrong, but it doesn't seem to cause bugs!
Matrix4x4 applyTransform = ComputeShadowTreeTransform(
aSubdocFrame, aRootFrameLoader, metrics, view->GetViewConfig(),
1 / GetXScale(aTransform), 1 / GetYScale(aTransform));
transform = applyTransform * aLayer->GetTransform() * aTransform;
// As mentioned above, bounds calculation also depends on the scale
// of this layer.
Matrix4x4 tmpTransform = aTransform;
Scale(tmpTransform, GetXScale(applyTransform), GetYScale(applyTransform));
// Calculate rect for this layer based on aTransform.
nsRect bounds;
{
bounds = CSSRect::ToAppUnits(metrics->mViewport);
nscoord auPerDevPixel = aSubdocFrame->PresContext()->AppUnitsPerDevPixel();
ApplyTransform(bounds, tmpTransform, auPerDevPixel);
}
aShadowTree.AppendToTop(
new (aBuilder) nsDisplayRemoteShadow(aBuilder, aSubdocFrame, bounds, scrollId));
} else {
transform = aLayer->GetTransform() * aTransform;
}
for (Layer* child = aLayer->GetFirstChild(); child;
child = child->GetNextSibling()) {
BuildListForLayer(child, aRootFrameLoader, transform,
aBuilder, aShadowTree, aSubdocFrame);
}
}
// Go down shadow layer tree and apply transformations for scrollable layers.
static void
TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
nsIFrame* aFrame, Layer* aLayer,
const ViewTransform& aTransform,
float aTempScaleDiffX = 1.0,
float aTempScaleDiffY = 1.0)
{
LayerComposite* shadow = aLayer->AsLayerComposite();
shadow->SetShadowClipRect(aLayer->GetClipRect());
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
shadow->SetShadowOpacity(aLayer->GetOpacity());
const FrameMetrics* metrics = GetFrameMetrics(aLayer);
Matrix4x4 shadowTransform = aLayer->GetTransform();
ViewTransform layerTransform = aTransform;
if (metrics && metrics->IsScrollable()) {
const ViewID scrollId = metrics->GetScrollId();
const nsContentView* view =
aFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId);
NS_ABORT_IF_FALSE(view, "Array of views should be consistent with layer tree");
Matrix4x4 currentTransform = aLayer->GetTransform();
const ViewConfig& config = view->GetViewConfig();
// With temporary scale we should compensate translation
// using temporary scale value
aTempScaleDiffX *= GetXScale(shadowTransform) * config.mXScale;
aTempScaleDiffY *= GetYScale(shadowTransform) * config.mYScale;
ViewTransform viewTransform = ComputeShadowTreeTransform(
aFrame, aFrameLoader, metrics, view->GetViewConfig(),
aTempScaleDiffX, aTempScaleDiffY
);
// Apply the layer's own transform *before* the view transform
shadowTransform = Matrix4x4(viewTransform) * currentTransform;
layerTransform = viewTransform;
if (metrics->IsRootScrollable()) {
// Apply the translation *before* we do the rest of the transforms.
nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
shadowTransform = shadowTransform *
Matrix4x4().Translate(float(offset.x), float(offset.y), 0.0);
}
}
if (aLayer->GetIsFixedPosition() &&
!aLayer->GetParent()->GetIsFixedPosition()) {
// Alter the shadow transform of fixed position layers in the situation
// that the view transform's scroll position doesn't match the actual
// scroll position, due to asynchronous layer scrolling.
float offsetX = layerTransform.mTranslation.x;
float offsetY = layerTransform.mTranslation.y;
ReverseTranslate(shadowTransform, gfxPoint(offsetX, offsetY));
const nsIntRect* clipRect = shadow->GetShadowClipRect();
if (clipRect) {
nsIntRect transformedClipRect(*clipRect);
transformedClipRect.MoveBy(-offsetX, -offsetY);
shadow->SetShadowClipRect(&transformedClipRect);
}
}
// The transform already takes the resolution scale into account. Since we
// will apply the resolution scale again when computing the effective
// transform, we must apply the inverse resolution scale here.
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
shadowTransform.Scale(1.0f/c->GetPreXScale(),
1.0f/c->GetPreYScale(),
1);
}
shadowTransform.ScalePost(1.0f/aLayer->GetPostXScale(),
1.0f/aLayer->GetPostYScale(),
1);
shadow->SetShadowTransform(shadowTransform);
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
TransformShadowTree(aBuilder, aFrameLoader, aFrame, child, layerTransform,
aTempScaleDiffX, aTempScaleDiffY);
}
}
static void
ClearContainer(ContainerLayer* aContainer)
{
while (Layer* layer = aContainer->GetFirstChild()) {
aContainer->RemoveChild(layer);
}
}
// Return true iff |aManager| is a "temporary layer manager". They're
// used for small software rendering tasks, like drawWindow. That's
// currently implemented by a BasicLayerManager without a backing
@ -360,135 +70,6 @@ IsTempLayerManager(LayerManager* aManager)
!static_cast<BasicLayerManager*>(aManager)->IsRetained());
}
// Recursively create a new array of scrollables, preserving any scrollables
// that are still in the layer tree.
//
// aXScale and aYScale are used to calculate any values that need to be in
// chrome-document CSS pixels and aren't part of the rendering loop, such as
// the initial scroll offset for a new view.
static void
BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
nsFrameLoader* aFrameLoader, Layer* aLayer,
float aXScale = 1, float aYScale = 1,
float aAccConfigXScale = 1, float aAccConfigYScale = 1)
{
ContainerLayer* container = aLayer->AsContainerLayer();
if (!container)
return;
const FrameMetrics metrics = container->GetFrameMetrics();
const ViewID scrollId = metrics.GetScrollId();
Matrix4x4 transform = aLayer->GetTransform();
aXScale *= GetXScale(transform);
aYScale *= GetYScale(transform);
if (metrics.IsScrollable()) {
nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent()
->PresContext()->AppUnitsPerDevPixel();
nscoord auPerCSSPixel = auPerDevPixel * metrics.mDevPixelsPerCSSPixel.scale;
nsContentView* view = FindViewForId(oldContentViews, scrollId);
if (view) {
// View already exists. Be sure to propagate scales for any values
// that need to be calculated something in chrome-doc CSS pixels.
ViewConfig config = view->GetViewConfig();
aXScale *= config.mXScale;
aYScale *= config.mYScale;
view->mFrameLoader = aFrameLoader;
// If scale has changed, then we should update
// current scroll offset to new scaled value
if (aAccConfigXScale != view->mParentScaleX ||
aAccConfigYScale != view->mParentScaleY) {
float xscroll = 0, yscroll = 0;
view->GetScrollX(&xscroll);
view->GetScrollY(&yscroll);
xscroll = xscroll * (aAccConfigXScale / view->mParentScaleX);
yscroll = yscroll * (aAccConfigYScale / view->mParentScaleY);
view->ScrollTo(xscroll, yscroll);
view->mParentScaleX = aAccConfigXScale;
view->mParentScaleY = aAccConfigYScale;
}
// Collect only config scale values for scroll compensation
aAccConfigXScale *= config.mXScale;
aAccConfigYScale *= config.mYScale;
} else {
// View doesn't exist, so generate one. We start the view scroll offset at
// the same position as the framemetric's scroll offset from the layer.
// The default scale is 1, so no need to propagate scale down.
ViewConfig config;
config.mScrollOffset = nsPoint(
NSIntPixelsToAppUnits(metrics.GetScrollOffset().x, auPerCSSPixel) * aXScale,
NSIntPixelsToAppUnits(metrics.GetScrollOffset().y, auPerCSSPixel) * aYScale);
view = new nsContentView(aFrameLoader, scrollId, metrics.mIsRoot, config);
view->mParentScaleX = aAccConfigXScale;
view->mParentScaleY = aAccConfigYScale;
}
// I don't know what units mViewportSize is in, hence use ToUnknownRect
// here to mark the current frontier in type info propagation
gfx::Rect viewport = metrics.mViewport.ToUnknownRect();
view->mViewportSize = nsSize(
NSIntPixelsToAppUnits(viewport.width, auPerDevPixel) * aXScale,
NSIntPixelsToAppUnits(viewport.height, auPerDevPixel) * aYScale);
view->mContentSize = nsSize(
NSFloatPixelsToAppUnits(metrics.mScrollableRect.width, auPerCSSPixel) * aXScale,
NSFloatPixelsToAppUnits(metrics.mScrollableRect.height, auPerCSSPixel) * aYScale);
newContentViews[scrollId] = view;
}
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
BuildViewMap(oldContentViews, newContentViews, aFrameLoader, child,
aXScale, aYScale, aAccConfigXScale, aAccConfigYScale);
}
}
static void
BuildBackgroundPatternFor(ContainerLayer* aContainer,
Layer* aShadowRoot,
const ViewConfig& aConfig,
const gfxRGBA& aColor,
LayerManager* aManager,
nsIFrame* aFrame)
{
LayerComposite* shadowRoot = aShadowRoot->AsLayerComposite();
gfx::Matrix t;
if (!shadowRoot->GetShadowTransform().Is2D(&t)) {
return;
}
// Get the rect bounding the shadow content, transformed into the
// same space as |aFrame|
nsIntRect contentBounds = shadowRoot->GetShadowVisibleRegion().GetBounds();
gfxRect contentVis(contentBounds.x, contentBounds.y,
contentBounds.width, contentBounds.height);
gfxRect localContentVis(gfx::ThebesMatrix(t).Transform(contentVis));
// Round *in* here because this area is punched out of the background
localContentVis.RoundIn();
nsIntRect localIntContentVis(localContentVis.X(), localContentVis.Y(),
localContentVis.Width(), localContentVis.Height());
// Get the frame's rect
nscoord auPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
nsIntRect frameRect = aFrame->GetRect().ToOutsidePixels(auPerDevPixel);
// If the shadow tree covers the frame rect, don't bother building
// the background, it wouldn't be visible
if (localIntContentVis.Contains(frameRect)) {
return;
}
nsRefPtr<ColorLayer> layer = aManager->CreateColorLayer();
layer->SetColor(aColor);
// The visible area of the background is the frame's area minus the
// content area
nsIntRegion bgRgn(frameRect);
bgRgn.Sub(bgRgn, localIntContentVis);
bgRgn.MoveBy(-frameRect.TopLeft());
layer->SetVisibleRegion(bgRgn);
aContainer->InsertAfter(layer, nullptr);
}
already_AddRefed<LayerManager>
GetFrom(nsFrameLoader* aFrameLoader)
{
@ -726,12 +307,11 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
if (lm && lm->GetRoot() && lm->GetRoot()->AsContainerLayer()) {
ViewID rootScrollId = lm->GetRoot()->AsContainerLayer()->GetFrameMetrics().GetScrollId();
if (rootScrollId != FrameMetrics::NULL_SCROLL_ID) {
mContentViews[rootScrollId] = new nsContentView(aFrameLoader, rootScrollId, true);
mRootContentView = new nsContentView(aFrameLoader, rootScrollId, true);
}
}
if (gfxPlatform::UsesOffMainThreadCompositing() &&
XRE_GetProcessType() == GeckoProcessType_Default) {
if (XRE_GetProcessType() == GeckoProcessType_Default) {
// Our remote frame will push layers updates to the compositor,
// and we'll keep an indirect reference to that tree.
*aId = mLayersId = CompositorParent::AllocateLayerTreeId();
@ -773,54 +353,13 @@ RenderFrameParent::~RenderFrameParent()
void
RenderFrameParent::Destroy()
{
size_t numChildren = ManagedPLayerTransactionParent().Length();
NS_ABORT_IF_FALSE(0 == numChildren || 1 == numChildren,
"render frame must only have 0 or 1 layer manager");
if (numChildren) {
LayerTransactionParent* layers =
static_cast<LayerTransactionParent*>(ManagedPLayerTransactionParent()[0]);
layers->Destroy();
}
mFrameLoaderDestroyed = true;
}
nsContentView*
RenderFrameParent::GetContentView(ViewID aId)
{
return FindViewForId(mContentViews, aId);
}
nsContentView*
RenderFrameParent::GetRootContentView()
{
return FindRootView(mContentViews);
}
void
RenderFrameParent::ContentViewScaleChanged(nsContentView* aView)
{
// Since the scale has changed for a view, it and its descendents need their
// shadow-space attributes updated. It's easiest to rebuild the view map.
BuildViewMap();
}
void
RenderFrameParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
const uint64_t& aTransactionId,
const TargetConfig& aTargetConfig,
bool aIsFirstPaint,
bool aScheduleComposite,
uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction)
{
// View map must only contain views that are associated with the current
// shadow layer tree. We must always update the map when shadow layers
// are updated.
BuildViewMap();
TriggerRepaint();
return mRootContentView;
}
already_AddRefed<Layer>
@ -851,75 +390,34 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
}
uint64_t id = GetLayerTreeId();
if (0 != id) {
MOZ_ASSERT(!GetRootLayer());
nsRefPtr<Layer> layer =
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
if (!layer) {
layer = aManager->CreateRefLayer();
}
if (!layer) {
// Probably a temporary layer manager that doesn't know how to
// use ref layers.
return nullptr;
}
static_cast<RefLayer*>(layer.get())->SetReferentId(id);
nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
// We can only have an offset if we're a child of an inactive
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
gfx::Matrix4x4 m;
m.Translate(offset.x, offset.y, 0.0);
// Remote content can't be repainted by us, so we multiply down
// the resolution that our container expects onto our container.
m.Scale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
layer->SetBaseTransform(m);
return layer.forget();
}
if (mContainer) {
ClearContainer(mContainer);
mContainer->SetPreScale(1.0f, 1.0f);
mContainer->SetPostScale(1.0f, 1.0f);
mContainer->SetInheritedScale(1.0f, 1.0f);
}
Layer* shadowRoot = GetRootLayer();
if (!shadowRoot) {
mContainer = nullptr;
if (!id) {
return nullptr;
}
NS_ABORT_IF_FALSE(!shadowRoot || shadowRoot->Manager() == aManager,
"retaining manager changed out from under us ... HELP!");
// Wrap the shadow layer tree in mContainer.
if (!mContainer) {
mContainer = aManager->CreateContainerLayer();
nsRefPtr<Layer> layer =
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
if (!layer) {
layer = aManager->CreateRefLayer();
}
NS_ABORT_IF_FALSE(!mContainer->GetFirstChild(),
"container of shadow tree shouldn't have a 'root' here");
mContainer->InsertAfter(shadowRoot, nullptr);
AssertInTopLevelChromeDoc(mContainer, aFrame);
ViewTransform transform;
TransformShadowTree(aBuilder, mFrameLoader, aFrame, shadowRoot, transform);
mContainer->SetClipRect(nullptr);
if (mFrameLoader->AsyncScrollEnabled()) {
const nsContentView* view = GetRootContentView();
BuildBackgroundPatternFor(mContainer,
shadowRoot,
view->GetViewConfig(),
mBackgroundColor,
aManager, aFrame);
if (!layer) {
// Probably a temporary layer manager that doesn't know how to
// use ref layers.
return nullptr;
}
static_cast<RefLayer*>(layer.get())->SetReferentId(id);
nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder);
// We can only have an offset if we're a child of an inactive
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
gfx::Matrix4x4 m;
m.Translate(offset.x, offset.y, 0.0);
// Remote content can't be repainted by us, so we multiply down
// the resolution that our container expects onto our container.
m.Scale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);
layer->SetBaseTransform(m);
return nsRefPtr<Layer>(mContainer).forget();
return layer.forget();
}
void
@ -927,7 +425,6 @@ RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
{
NS_ABORT_IF_FALSE(mFrameLoader->GetOwnerContent() == aContent,
"Don't build new map if owner is same!");
BuildViewMap();
}
nsEventStatus
@ -990,60 +487,6 @@ RenderFrameParent::RecvUpdateHitRegion(const nsRegion& aRegion)
return true;
}
PLayerTransactionParent*
RenderFrameParent::AllocPLayerTransactionParent()
{
if (!mFrameLoader || mFrameLoaderDestroyed) {
return nullptr;
}
nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
LayerTransactionParent* result = new LayerTransactionParent(lm->AsLayerManagerComposite(), this, 0, 0);
result->AddIPDLReference();
return result;
}
bool
RenderFrameParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
{
static_cast<LayerTransactionParent*>(aLayers)->ReleaseIPDLReference();
return true;
}
void
RenderFrameParent::BuildViewMap()
{
ViewMap newContentViews;
// BuildViewMap assumes we have a primary frame, which may not be the case.
if (GetRootLayer() && mFrameLoader->GetPrimaryFrameOfOwningContent()) {
// Some of the content views in our hash map may no longer be active. To
// tag them as inactive and to remove any chance of them using a dangling
// pointer, we set mContentView to nullptr.
//
// BuildViewMap will restore mFrameLoader if the content view is still
// in our hash table.
for (ViewMap::const_iterator iter = mContentViews.begin();
iter != mContentViews.end();
++iter) {
iter->second->mFrameLoader = nullptr;
}
mozilla::layout::BuildViewMap(mContentViews, newContentViews, mFrameLoader, GetRootLayer());
}
// Here, we guarantee that *only* the root view is preserved in
// case we couldn't build a new view map above. This is important because
// the content view map should only contain the root view and content
// views that are present in the layer tree.
if (newContentViews.empty()) {
nsContentView* rootView = FindRootView(mContentViews);
if (rootView)
newContentViews[rootView->GetId()] = rootView;
}
mContentViews = newContentViews;
}
void
RenderFrameParent::TriggerRepaint()
{
@ -1062,29 +505,12 @@ RenderFrameParent::TriggerRepaint()
docFrame->InvalidateLayer(nsDisplayItem::TYPE_REMOTE);
}
LayerTransactionParent*
RenderFrameParent::GetShadowLayers() const
{
const InfallibleTArray<PLayerTransactionParent*>& shadowParents = ManagedPLayerTransactionParent();
NS_ABORT_IF_FALSE(shadowParents.Length() <= 1,
"can only support at most 1 LayerTransactionParent");
return (shadowParents.Length() == 1) ?
static_cast<LayerTransactionParent*>(shadowParents[0]) : nullptr;
}
uint64_t
RenderFrameParent::GetLayerTreeId() const
{
return mLayersId;
}
Layer*
RenderFrameParent::GetRootLayer() const
{
LayerTransactionParent* shadowLayers = GetShadowLayers();
return shadowLayers ? shadowLayers->GetRoot() : nullptr;
}
void
RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame,
@ -1099,16 +525,8 @@ RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsRect bounds = aFrame->EnsureInnerView()->GetBounds() + offset;
clipState.ClipContentDescendants(bounds);
Layer* container = GetRootLayer();
if (aBuilder->IsForEventDelivery() && container) {
ViewTransform offset =
ViewTransform(GetContentRectLayerOffset(aFrame, aBuilder));
BuildListForLayer(container, mFrameLoader, offset,
aBuilder, *aLists.Content(), aFrame);
} else {
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayRemote(aBuilder, aFrame, this));
}
aLists.Content()->AppendToTop(
new (aBuilder) nsDisplayRemote(aBuilder, aFrame, this));
}
void
@ -1180,16 +598,3 @@ nsDisplayRemote::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
}
}
void
nsDisplayRemoteShadow::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
{
// If we are here, then rects have intersected.
//
// XXX I think iframes and divs can be rounded like anything else but we don't
// cover that case here.
//
if (aState->mShadows) {
aState->mShadows->AppendElement(mId);
}
}

View File

@ -12,7 +12,6 @@
#include <map>
#include "mozilla/layout/PRenderFrameParent.h"
#include "mozilla/layers/ShadowLayersManager.h"
#include "nsDisplayList.h"
#include "RenderFrameUtils.h"
@ -37,8 +36,7 @@ namespace layout {
class RemoteContentController;
class RenderFrameParent : public PRenderFrameParent,
public mozilla::layers::ShadowLayersManager
class RenderFrameParent : public PRenderFrameParent
{
typedef mozilla::layers::FrameMetrics FrameMetrics;
typedef mozilla::layers::ContainerLayer ContainerLayer;
@ -53,7 +51,6 @@ class RenderFrameParent : public PRenderFrameParent,
typedef FrameMetrics::ViewID ViewID;
public:
typedef std::map<ViewID, nsRefPtr<nsContentView> > ViewMap;
/**
@ -73,19 +70,8 @@ public:
* Helper functions for getting a non-owning reference to a scrollable.
* @param aId The ID of the frame.
*/
nsContentView* GetContentView(ViewID aId);
nsContentView* GetRootContentView();
void ContentViewScaleChanged(nsContentView* aView);
virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
const uint64_t& aTransactionId,
const TargetConfig& aTargetConfig,
bool aIsFirstPaint,
bool aScheduleComposite,
uint32_t aPaintSequenceNumber,
bool aIsRepeatTransaction) MOZ_OVERRIDE;
void BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsSubDocumentFrame* aFrame,
const nsRect& aDirtyRect,
@ -133,17 +119,11 @@ protected:
virtual bool RecvUpdateHitRegion(const nsRegion& aRegion) MOZ_OVERRIDE;
virtual PLayerTransactionParent* AllocPLayerTransactionParent() MOZ_OVERRIDE;
virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) MOZ_OVERRIDE;
private:
void BuildViewMap();
void TriggerRepaint();
void DispatchEventForPanZoomController(const InputEvent& aEvent);
LayerTransactionParent* GetShadowLayers() const;
uint64_t GetLayerTreeId() const;
Layer* GetRootLayer() const;
// When our child frame is pushing transactions directly to the
// compositor, this is the ID of its layer tree in the compositor's
@ -162,7 +142,7 @@ private:
// This contains the views for all the scrollable frames currently in the
// painted region of our remote content.
ViewMap mContentViews;
nsRefPtr<nsContentView> mRootContentView;
// True after Destroy() has been called, which is triggered
// originally by nsFrameLoader::Destroy(). After this point, we can
@ -222,48 +202,5 @@ private:
RenderFrameParent* mRemoteFrame;
};
/**
* nsDisplayRemoteShadow is a way of adding display items for frames in a
* separate process, for hit testing only. After being processed, the hit
* test state will contain IDs for any remote frames that were hit.
*
* The frame should be its respective render frame parent.
*/
class nsDisplayRemoteShadow : public nsDisplayItem
{
typedef mozilla::layout::RenderFrameParent RenderFrameParent;
typedef mozilla::layers::FrameMetrics::ViewID ViewID;
public:
nsDisplayRemoteShadow(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsRect aRect,
ViewID aId)
: nsDisplayItem(aBuilder, aFrame)
, mRect(aRect)
, mId(aId)
{}
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
{
*aSnap = false;
return mRect;
}
virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE
{
NS_ABORT();
return 0;
}
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("Remote-Shadow", TYPE_REMOTE_SHADOW)
private:
nsRect mRect;
ViewID mId;
};
#endif // mozilla_layout_RenderFrameParent_h

View File

@ -9,9 +9,6 @@
#include "ClientLayerManager.h"
#include "gfxPlatform.h"
#if defined(MOZ_ENABLE_D3D10_LAYER)
# include "LayerManagerD3D10.h"
#endif
#include "mozilla/dom/TabChild.h"
#include "mozilla/Hal.h"
#include "mozilla/IMEStateManager.h"
@ -365,20 +362,7 @@ PuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
bool* aAllowRetaining)
{
if (!mLayerManager) {
// The backend hint is a temporary placeholder until Azure, when
// all content-process layer managers will be BasicLayerManagers.
#if defined(MOZ_ENABLE_D3D10_LAYER)
if (mozilla::layers::LayersBackend::LAYERS_D3D10 == aBackendHint) {
nsRefPtr<LayerManagerD3D10> m = new LayerManagerD3D10(this);
m->AsShadowForwarder()->SetShadowManager(aShadowManager);
if (m->Initialize()) {
mLayerManager = m;
}
}
#endif
if (!mLayerManager) {
mLayerManager = new ClientLayerManager(this);
}
mLayerManager = new ClientLayerManager(this);
}
ShadowLayerForwarder* lf = mLayerManager->AsShadowForwarder();
if (!lf->HasShadowManager() && aShadowManager) {