already_AddRefed<Layer> nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aContainerParameters) { int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); nsIntRect visibleRect = GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel); visibleRect += aContainerParameters.mOffset; RefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, visibleRect, this, aContainerParameters); if (layer && layer->AsContainerLayer()) { layer->AsContainerLayer()->SetEventRegionsOverride(mEventRegionsOverride); } return layer.forget(); }
TEST(Layers, RepositionChild) { const char* layerTreeSyntax = "c(ttt)"; nsTArray<RefPtr<Layer> > layers; RefPtr<LayerManager> lm; RefPtr<Layer> root = CreateLayerTree(layerTreeSyntax, nullptr, nullptr, lm, layers); ContainerLayer* parent = root->AsContainerLayer(); ValidateTreePointers(layers); // tree is currently like this (using indexes into layers): // 0 // 1 2 3 ASSERT_EQ(layers[2], layers[1]->GetNextSibling()); ASSERT_EQ(layers[3], layers[2]->GetNextSibling()); ASSERT_EQ(nullptr, layers[3]->GetNextSibling()); parent->RepositionChild(layers[1], layers[3]); ValidateTreePointers(layers); // now the tree is like this: // 0 // 2 3 1 ASSERT_EQ(layers[3], layers[2]->GetNextSibling()); ASSERT_EQ(layers[1], layers[3]->GetNextSibling()); ASSERT_EQ(nullptr, layers[1]->GetNextSibling()); parent->RepositionChild(layers[3], layers[2]); ValidateTreePointers(layers); // no change ASSERT_EQ(layers[3], layers[2]->GetNextSibling()); ASSERT_EQ(layers[1], layers[3]->GetNextSibling()); ASSERT_EQ(nullptr, layers[1]->GetNextSibling()); parent->RepositionChild(layers[3], layers[1]); ValidateTreePointers(layers); // 0 // 2 1 3 ASSERT_EQ(layers[1], layers[2]->GetNextSibling()); ASSERT_EQ(layers[3], layers[1]->GetNextSibling()); ASSERT_EQ(nullptr, layers[3]->GetNextSibling()); parent->RepositionChild(layers[3], nullptr); ValidateTreePointers(layers); // 0 // 3 2 1 ASSERT_EQ(layers[2], layers[3]->GetNextSibling()); ASSERT_EQ(layers[1], layers[2]->GetNextSibling()); ASSERT_EQ(nullptr, layers[1]->GetNextSibling()); }
already_AddRefed<Layer> CreateLayerTree( const char* aLayerTreeDescription, nsIntRegion* aVisibleRegions, const Matrix4x4* aTransforms, RefPtr<LayerManager>& manager, nsTArray<RefPtr<Layer> >& aLayersOut) { aLayersOut.Clear(); if (!manager) { manager = new TestLayerManager(); } RefPtr<Layer> rootLayer = nullptr; RefPtr<ContainerLayer> parentContainerLayer = nullptr; RefPtr<Layer> lastLayer = nullptr; int layerNumber = 0; for (size_t i = 0; i < strlen(aLayerTreeDescription); i++) { if (aLayerTreeDescription[i] == '(') { if (!lastLayer) { printf("Syntax error, likely '(' character isn't preceded by a container.\n"); MOZ_CRASH(); } parentContainerLayer = lastLayer->AsContainerLayer(); if (!parentContainerLayer) { printf("Layer before '(' must be a container.\n"); MOZ_CRASH(); } } else if (aLayerTreeDescription[i] == ')') { parentContainerLayer = parentContainerLayer->GetParent(); lastLayer = nullptr; } else { RefPtr<Layer> layer = CreateLayer(aLayerTreeDescription[i], manager.get()); if (aVisibleRegions) { layer->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(aVisibleRegions[layerNumber])); layer->SetEventRegions(EventRegions(aVisibleRegions[layerNumber])); } if (aTransforms) { layer->SetBaseTransform(aTransforms[layerNumber]); } aLayersOut.AppendElement(layer); layerNumber++; if (rootLayer && !parentContainerLayer) { MOZ_CRASH(); } if (!rootLayer) { rootLayer = layer; } if (parentContainerLayer) { parentContainerLayer->InsertAfter(layer, parentContainerLayer->GetLastChild()); layer->SetParent(parentContainerLayer); } lastLayer = layer; } } if (rootLayer) { rootLayer->ComputeEffectiveTransforms(Matrix4x4()); manager->SetRoot(rootLayer); if (rootLayer->AsLayerComposite()) { // Only perform this for LayerManagerComposite CompositorBridgeParent::SetShadowProperties(rootLayer); } } return rootLayer.forget(); }