SurfaceFlinger: Use traversal functions to iterate LayerList.
In preparation for the Layer hierarchy. There we will need
to use such a style to traverse the tree of layers.
Test: Just a refactoring. SurfaceFlinger still works.
Change-Id: I84dcd82e713f1bdbe911658793ce11460267a956
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index fcc9241..1cd9215 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -15,6 +15,7 @@
Layer.cpp \
LayerDim.cpp \
LayerRejecter.cpp \
+ LayerVector.cpp \
MessageQueue.cpp \
MonitoredProducer.cpp \
SurfaceFlingerConsumer.cpp \
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5f32119..5b61c25 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -903,7 +903,7 @@
// figure out if there is something below us
Region under;
- const SurfaceFlinger::LayerVector& drawingLayers(
+ const LayerVector& drawingLayers(
mFlinger->mDrawingState.layersSortedByZ);
const size_t count = drawingLayers.size();
for (size_t i=0 ; i<count ; ++i) {
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
new file mode 100644
index 0000000..6ac4b14
--- /dev/null
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LayerVector.h"
+#include "Layer.h"
+
+namespace android {
+LayerVector::LayerVector(const LayerVector& rhs) : SortedVector<sp<Layer>>(rhs) {
+}
+
+int LayerVector::do_compare(const void* lhs, const void* rhs) const
+{
+ // sort layers per layer-stack, then by z-order and finally by sequence
+ const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);
+ const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);
+
+ uint32_t ls = l->getCurrentState().layerStack;
+ uint32_t rs = r->getCurrentState().layerStack;
+ if (ls != rs)
+ return ls - rs;
+
+ uint32_t lz = l->getCurrentState().z;
+ uint32_t rz = r->getCurrentState().z;
+ if (lz != rz)
+ return lz - rz;
+
+ return l->sequence - r->sequence;
+}
+
+void LayerVector::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
+ const size_t n = size();
+ for (size_t i = 0; i < n; i++) {
+ consume((*this)[i].get());
+ }
+}
+
+void LayerVector::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
+ for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
+ consume((*this)[i].get());
+ }
+}
+} // namespace android
diff --git a/services/surfaceflinger/LayerVector.h b/services/surfaceflinger/LayerVector.h
new file mode 100644
index 0000000..7dfa4a0
--- /dev/null
+++ b/services/surfaceflinger/LayerVector.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SURFACE_FLINGER_LAYER_VECTOR_H
+#define ANDROID_SURFACE_FLINGER_LAYER_VECTOR_H
+
+#include <utils/SortedVector.h>
+#include <utils/RefBase.h>
+
+#include <functional>
+
+namespace android {
+class Layer;
+
+/*
+ * Used by the top-level SurfaceFlinger state and individual layers
+ * to track layers they own sorted according to Z-order. Provides traversal
+ * functions for traversing all owned layers, and their descendents.
+ */
+class LayerVector : public SortedVector<sp<Layer>> {
+public:
+ LayerVector() = default;
+ LayerVector(const LayerVector& rhs);
+ // Sorts layer by layer-stack, Z order, and finally creation order (sequence).
+ int do_compare(const void* lhs, const void* rhs) const override;
+
+ void traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const;
+ void traverseInZOrder(const std::function<void(Layer*)>& consume) const;
+};
+}
+
+#endif /* ANDROID_SURFACE_FLINGER_LAYER_VECTOR_H_ */
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8b10344..510a3e1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1211,13 +1211,12 @@
ALOGV("preComposition");
bool needExtraInvalidate = false;
- const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- if (layers[i]->onPreComposition(refreshStartTime)) {
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
+ if (layer->onPreComposition(refreshStartTime)) {
needExtraInvalidate = true;
}
- }
+ });
+
if (needExtraInvalidate) {
signalLayerUpdate();
}
@@ -1258,18 +1257,14 @@
} else {
retireFenceTime = &displayFenceTime;
}
-
- const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- bool frameLatched =
- layers[i]->onPostComposition(glCompositionDoneFenceTime,
- *presentFenceTime, *retireFenceTime);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
+ bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
+ *presentFenceTime, *retireFenceTime);
if (frameLatched) {
- recordBufferingStats(layers[i]->getName().string(),
- layers[i]->getOccupancyHistory(false));
+ recordBufferingStats(layer->getName().string(),
+ layer->getOccupancyHistory(false));
}
- }
+ });
if (displayFence->isValid()) {
if (mPrimaryDispSync.addPresentFence(displayFence)) {
@@ -1332,7 +1327,6 @@
mVisibleRegionsDirty = false;
invalidateHwcGeometry();
- const LayerVector& layers(mDrawingState.layersSortedByZ);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
Region opaqueRegion;
Region dirtyRegion;
@@ -1341,13 +1335,11 @@
const Transform& tr(displayDevice->getTransform());
const Rect bounds(displayDevice->getBounds());
if (displayDevice->isDisplayOn()) {
- SurfaceFlinger::computeVisibleRegions(layers,
+ computeVisibleRegions(
displayDevice->getLayerStack(), dirtyRegion,
opaqueRegion);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& s(layer->getDrawingState());
if (s.layerStack == displayDevice->getLayerStack()) {
Region drawRegion(tr.transform(
@@ -1362,7 +1354,7 @@
nullptr);
}
}
- }
+ });
}
displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
displayDevice->undefinedRegion.set(bounds);
@@ -1569,12 +1561,11 @@
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
- const size_t count = currentLayers.size();
// Notify all layers of available frames
- for (size_t i = 0; i < count; ++i) {
- currentLayers[i]->notifyAvailableFrames();
- }
+ mCurrentState.traverseInZOrder([](Layer* layer) {
+ layer->notifyAvailableFrames();
+ });
/*
* Traversal of the children
@@ -1582,15 +1573,14 @@
*/
if (transactionFlags & eTraversalNeeded) {
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
- if (!trFlags) continue;
+ if (!trFlags) return;
const uint32_t flags = layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty = true;
- }
+ });
}
/*
@@ -1783,13 +1773,13 @@
//
sp<const DisplayDevice> disp;
uint32_t currentlayerStack = 0;
- for (size_t i=0; i<count; i++) {
+ bool first = true;
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
// NOTE: we rely on the fact that layers are sorted by
// layerStack first (so we don't have to traverse the list
// of displays for every layer).
- const sp<Layer>& layer(currentLayers[i]);
uint32_t layerStack = layer->getDrawingState().layerStack;
- if (i==0 || currentlayerStack != layerStack) {
+ if (first || currentlayerStack != layerStack) {
currentlayerStack = layerStack;
// figure out if this layerstack is mirrored
// (more than one display) if so, pick the default display,
@@ -1817,14 +1807,15 @@
disp = getDefaultDisplayDevice();
}
layer->updateTransformHint(disp);
- }
+
+ first = false;
+ });
}
/*
* Perform our own transaction if needed
*/
-
const LayerVector& layers(mDrawingState.layersSortedByZ);
if (currentLayers.size() > layers.size()) {
// layers have been added
@@ -1836,9 +1827,7 @@
if (mLayersRemoved) {
mLayersRemoved = false;
mVisibleRegionsDirty = true;
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
if (currentLayers.indexOf(layer) < 0) {
// this layer is not visible anymore
// TODO: we could traverse the tree from front to back and
@@ -1849,7 +1838,7 @@
Region(Rect(s.active.w, s.active.h)));
invalidateLayerStack(s.layerStack, visibleReg);
}
- }
+ });
}
commitTransaction();
@@ -1893,8 +1882,7 @@
mTransactionCV.broadcast();
}
-void SurfaceFlinger::computeVisibleRegions(
- const LayerVector& currentLayers, uint32_t layerStack,
+void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
Region& outDirtyRegion, Region& outOpaqueRegion)
{
ATRACE_CALL();
@@ -1906,16 +1894,13 @@
outDirtyRegion.clear();
- size_t i = currentLayers.size();
- while (i--) {
- const sp<Layer>& layer = currentLayers[i];
-
+ mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
// start with the whole surface at its current location
const Layer::State& s(layer->getDrawingState());
// only consider the layers on the given layer stack
if (s.layerStack != layerStack)
- continue;
+ return;
/*
* opaqueRegion: area of a surface that is fully opaque.
@@ -2024,7 +2009,7 @@
layer->setCoveredRegion(coveredRegion);
layer->setVisibleNonTransparentRegion(
visibleRegion.subtract(transparentRegion));
- }
+ });
outOpaqueRegion = aboveOpaqueLayers;
}
@@ -2046,7 +2031,6 @@
nsecs_t latchTime = systemTime();
bool visibleRegions = false;
- const LayerVector& layers(mDrawingState.layersSortedByZ);
bool frameQueued = false;
// Store the set of layers that need updates. This set must not change as
@@ -2058,19 +2042,19 @@
// 3.) Layer 1 is latched.
// Display is now waiting on Layer 1's frame, which is behind layer 0's
// second frame. But layer 0's second frame could be waiting on display.
- for (size_t i = 0, count = layers.size(); i<count ; i++) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->hasQueuedFrame()) {
frameQueued = true;
if (layer->shouldPresentNow(mPrimaryDispSync)) {
- mLayersWithQueuedFrames.push_back(layer.get());
+ mLayersWithQueuedFrames.push_back(layer);
} else {
layer->useEmptyDamage();
}
} else {
layer->useEmptyDamage();
}
- }
+ });
+
for (auto& layer : mLayersWithQueuedFrames) {
const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
layer->useSurfaceDamage();
@@ -2892,12 +2876,9 @@
void SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
size_t& /* index */, String8& result) const
{
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
result.appendFormat("%s\n", layer->getName().string());
- }
+ });
}
void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
@@ -2916,14 +2897,11 @@
if (name.isEmpty()) {
mAnimFrameTracker.dumpStats(result);
} else {
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
if (name == layer->getName()) {
layer->dumpFrameStats(result);
}
- }
+ });
}
}
@@ -2936,14 +2914,11 @@
index++;
}
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
if (name.isEmpty() || (name == layer->getName())) {
layer->clearFrameStats();
}
- }
+ });
mAnimFrameTracker.clearStats();
}
@@ -2951,12 +2926,9 @@
// This should only be called from the main thread. Otherwise it would need
// the lock and should use mCurrentState rather than mDrawingState.
void SurfaceFlinger::logFrameStats() {
- const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
- const size_t count = drawingLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(drawingLayers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
layer->logFrameStats();
- }
+ });
mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
}
@@ -3118,10 +3090,9 @@
colorizer.bold(result);
result.appendFormat("Visible layers (count = %zu)\n", count);
colorizer.reset(result);
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
layer->dump(result, colorizer);
- }
+ });
/*
* Dump Display state
@@ -3727,10 +3698,7 @@
// redraw the screen entirely...
engine.clearWithColor(0, 0, 0, 1);
- const LayerVector& layers( mDrawingState.layersSortedByZ );
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& state(layer->getDrawingState());
if (state.layerStack == hw->getLayerStack()) {
if (state.z >= minLayerZ && state.z <= maxLayerZ) {
@@ -3741,7 +3709,7 @@
}
}
}
- }
+ });
hw->setViewportAndProjection();
}
@@ -3775,17 +3743,14 @@
reqHeight = (!reqHeight) ? hw_h : reqHeight;
bool secureLayerIsVisible = false;
- const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t count = layers.size();
- for (size_t i = 0 ; i < count ; ++i) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& state(layer->getDrawingState());
if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
state.z <= maxLayerZ && layer->isVisible() &&
layer->isSecure()) {
secureLayerIsVisible = true;
}
- }
+ });
if (!isLocalScreenshot && secureLayerIsVisible) {
ALOGW("FB is protected: PERMISSION_DENIED");
@@ -3923,49 +3888,29 @@
ALOGE("*** we just took a black screenshot ***\n"
"requested minz=%d, maxz=%d, layerStack=%d",
minLayerZ, maxLayerZ, hw->getLayerStack());
- const LayerVector& layers( mDrawingState.layersSortedByZ );
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<Layer>& layer(layers[i]);
+ size_t i = 0;
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& state(layer->getDrawingState());
const bool visible = (state.layerStack == hw->getLayerStack())
&& (state.z >= minLayerZ && state.z <= maxLayerZ)
&& (layer->isVisible());
ALOGE("%c index=%zu, name=%s, layerStack=%d, z=%d, visible=%d, flags=%x, alpha=%.3f",
visible ? '+' : '-',
- i, layer->getName().string(), state.layerStack, state.z,
+ i, layer->getName().string(), state.layerStack, state.z,
layer->isVisible(), state.flags, state.alpha);
- }
+ i++;
+ });
}
}
// ---------------------------------------------------------------------------
-SurfaceFlinger::LayerVector::LayerVector() {
+void SurfaceFlinger::State::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
+ layersSortedByZ.traverseInZOrder(consume);
}
-SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
- : SortedVector<sp<Layer> >(rhs) {
-}
-
-int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
- const void* rhs) const
-{
- // sort layers per layer-stack, then by z-order and finally by sequence
- const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
- const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
-
- uint32_t ls = l->getCurrentState().layerStack;
- uint32_t rs = r->getCurrentState().layerStack;
- if (ls != rs)
- return ls - rs;
-
- uint32_t lz = l->getCurrentState().z;
- uint32_t rz = r->getCurrentState().z;
- if (lz != rz)
- return lz - rz;
-
- return l->sequence - r->sequence;
+void SurfaceFlinger::State::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
+ layersSortedByZ.traverseInReverseZOrder(consume);
}
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index bb44a36..d573f1a 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -55,6 +55,7 @@
#include "DisplayDevice.h"
#include "DispSync.h"
#include "FrameTracker.h"
+#include "LayerVector.h"
#include "MessageQueue.h"
#include "SurfaceInterceptor.h"
@@ -168,16 +169,13 @@
* Internal data structures
*/
- class LayerVector : public SortedVector< sp<Layer> > {
+ class State {
public:
- LayerVector();
- LayerVector(const LayerVector& rhs);
- virtual int do_compare(const void* lhs, const void* rhs) const;
- };
-
- struct State {
LayerVector layersSortedByZ;
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
+
+ void traverseInZOrder(const std::function<void(Layer*)>& consume) const;
+ void traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const;
};
/* ------------------------------------------------------------------------
@@ -397,8 +395,7 @@
* Compositing
*/
void invalidateHwcGeometry();
- static void computeVisibleRegions(
- const LayerVector& currentLayers, uint32_t layerStack,
+ void computeVisibleRegions(uint32_t layerStack,
Region& dirtyRegion, Region& opaqueRegion);
void preComposition(nsecs_t refreshStartTime);
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 217ba1b..5bfc10b 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -1126,13 +1126,12 @@
void SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
{
bool needExtraInvalidate = false;
- const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- if (layers[i]->onPreComposition(refreshStartTime)) {
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
+ if (layer->onPreComposition(refreshStartTime)) {
needExtraInvalidate = true;
}
- }
+ });
+
if (needExtraInvalidate) {
signalLayerUpdate();
}
@@ -1159,16 +1158,15 @@
mDisplayTimeline.push(retireFenceTime);
mDisplayTimeline.updateSignalTimes();
- const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- bool frameLatched = layers[i]->onPostComposition(
- glCompositionDoneFenceTime, presentFenceTime, retireFenceTime);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
+ bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
+ presentFenceTime, retireFenceTime);
+
if (frameLatched) {
- recordBufferingStats(layers[i]->getName().string(),
- layers[i]->getOccupancyHistory(false));
+ recordBufferingStats(layer->getName().string(),
+ layer->getOccupancyHistory(false));
}
- }
+ });
if (displayFence->isValid()) {
if (mPrimaryDispSync.addPresentFence(displayFence)) {
@@ -1226,7 +1224,6 @@
mVisibleRegionsDirty = false;
invalidateHwcGeometry();
- const LayerVector& layers(mDrawingState.layersSortedByZ);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
Region opaqueRegion;
Region dirtyRegion;
@@ -1235,12 +1232,10 @@
const Transform& tr(hw->getTransform());
const Rect bounds(hw->getBounds());
if (hw->isDisplayOn()) {
- SurfaceFlinger::computeVisibleRegions(layers,
- hw->getLayerStack(), dirtyRegion, opaqueRegion);
+ computeVisibleRegions(hw->getLayerStack(), dirtyRegion,
+ opaqueRegion);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& s(layer->getDrawingState());
if (s.layerStack == hw->getLayerStack()) {
Region drawRegion(tr.transform(
@@ -1250,7 +1245,7 @@
layersSortedByZ.add(layer);
}
}
- }
+ });
}
hw->setVisibleLayersSortedByZ(layersSortedByZ);
hw->undefinedRegion.set(bounds);
@@ -1474,12 +1469,11 @@
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
- const size_t count = currentLayers.size();
// Notify all layers of available frames
- for (size_t i = 0; i < count; ++i) {
- currentLayers[i]->notifyAvailableFrames();
- }
+ mCurrentState.traverseInZOrder([](Layer* layer) {
+ layer->notifyAvailableFrames();
+ });
/*
* Traversal of the children
@@ -1487,15 +1481,14 @@
*/
if (transactionFlags & eTraversalNeeded) {
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
- if (!trFlags) continue;
+ if (!trFlags) return;
const uint32_t flags = layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty = true;
- }
+ });
}
/*
@@ -1682,13 +1675,13 @@
//
sp<const DisplayDevice> disp;
uint32_t currentlayerStack = 0;
- for (size_t i=0; i<count; i++) {
+ bool first = true;
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
// NOTE: we rely on the fact that layers are sorted by
// layerStack first (so we don't have to traverse the list
// of displays for every layer).
- const sp<Layer>& layer(currentLayers[i]);
uint32_t layerStack = layer->getDrawingState().layerStack;
- if (i==0 || currentlayerStack != layerStack) {
+ if (first || currentlayerStack != layerStack) {
currentlayerStack = layerStack;
// figure out if this layerstack is mirrored
// (more than one display) if so, pick the default display,
@@ -1716,14 +1709,15 @@
disp = getDefaultDisplayDevice();
}
layer->updateTransformHint(disp);
- }
+
+ first = false;
+ });
}
/*
* Perform our own transaction if needed
*/
-
const LayerVector& layers(mDrawingState.layersSortedByZ);
if (currentLayers.size() > layers.size()) {
// layers have been added
@@ -1735,9 +1729,7 @@
if (mLayersRemoved) {
mLayersRemoved = false;
mVisibleRegionsDirty = true;
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
if (currentLayers.indexOf(layer) < 0) {
// this layer is not visible anymore
// TODO: we could traverse the tree from front to back and
@@ -1748,7 +1740,7 @@
Region(Rect(s.active.w, s.active.h)));
invalidateLayerStack(s.layerStack, visibleReg);
}
- }
+ });
}
commitTransaction();
@@ -1804,8 +1796,7 @@
mTransactionCV.broadcast();
}
-void SurfaceFlinger::computeVisibleRegions(
- const LayerVector& currentLayers, uint32_t layerStack,
+void SurfaceFlinger::computeVisibleRegions(uint32_t layerStack,
Region& outDirtyRegion, Region& outOpaqueRegion)
{
ATRACE_CALL();
@@ -1816,16 +1807,13 @@
outDirtyRegion.clear();
- size_t i = currentLayers.size();
- while (i--) {
- const sp<Layer>& layer = currentLayers[i];
-
+ mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
// start with the whole surface at its current location
const Layer::State& s(layer->getDrawingState());
// only consider the layers on the given layer stack
if (s.layerStack != layerStack)
- continue;
+ return;
/*
* opaqueRegion: area of a surface that is fully opaque.
@@ -1934,7 +1922,7 @@
layer->setCoveredRegion(coveredRegion);
layer->setVisibleNonTransparentRegion(
visibleRegion.subtract(transparentRegion));
- }
+ });
outOpaqueRegion = aboveOpaqueLayers;
}
@@ -1955,7 +1943,6 @@
Region dirtyRegion;
bool visibleRegions = false;
- const LayerVector& layers(mDrawingState.layersSortedByZ);
bool frameQueued = false;
// Store the set of layers that need updates. This set must not change as
@@ -1968,19 +1955,18 @@
// Display is now waiting on Layer 1's frame, which is behind layer 0's
// second frame. But layer 0's second frame could be waiting on display.
Vector<Layer*> layersWithQueuedFrames;
- for (size_t i = 0, count = layers.size(); i<count ; i++) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->hasQueuedFrame()) {
frameQueued = true;
if (layer->shouldPresentNow(mPrimaryDispSync)) {
- layersWithQueuedFrames.push_back(layer.get());
+ layersWithQueuedFrames.push_back(layer);
} else {
layer->useEmptyDamage();
}
} else {
layer->useEmptyDamage();
}
- }
+ });
for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
Layer* layer = layersWithQueuedFrames[i];
const Region dirty(layer->latchBuffer(visibleRegions, latchTime));
@@ -2797,12 +2783,9 @@
void SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
size_t& /* index */, String8& result) const
{
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
result.appendFormat("%s\n", layer->getName().string());
- }
+ });
}
void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
@@ -2821,14 +2804,11 @@
if (name.isEmpty()) {
mAnimFrameTracker.dumpStats(result);
} else {
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
if (name == layer->getName()) {
layer->dumpFrameStats(result);
}
- }
+ });
}
}
@@ -2841,14 +2821,11 @@
index++;
}
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
if (name.isEmpty() || (name == layer->getName())) {
layer->clearFrameStats();
}
- }
+ });
mAnimFrameTracker.clearStats();
}
@@ -2856,12 +2833,9 @@
// This should only be called from the main thread. Otherwise it would need
// the lock and should use mCurrentState rather than mDrawingState.
void SurfaceFlinger::logFrameStats() {
- const LayerVector& drawingLayers = mDrawingState.layersSortedByZ;
- const size_t count = drawingLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(drawingLayers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
layer->logFrameStats();
- }
+ });
mAnimFrameTracker.logAndResetStats(String8("<win-anim>"));
}
@@ -3020,10 +2994,9 @@
colorizer.bold(result);
result.appendFormat("Visible layers (count = %zu)\n", count);
colorizer.reset(result);
- for (size_t i=0 ; i<count ; i++) {
- const sp<Layer>& layer(currentLayers[i]);
+ mCurrentState.traverseInZOrder([&](Layer* layer) {
layer->dump(result, colorizer);
- }
+ });
/*
* Dump Display state
@@ -3603,10 +3576,7 @@
// redraw the screen entirely...
engine.clearWithColor(0, 0, 0, 1);
- const LayerVector& layers( mDrawingState.layersSortedByZ );
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& state(layer->getDrawingState());
if (state.layerStack == hw->getLayerStack()) {
if (state.z >= minLayerZ && state.z <= maxLayerZ) {
@@ -3617,7 +3587,7 @@
}
}
}
- }
+ });
// compositionComplete is needed for older driver
hw->compositionComplete();
@@ -3653,17 +3623,14 @@
reqHeight = (!reqHeight) ? hw_h : reqHeight;
bool secureLayerIsVisible = false;
- const LayerVector& layers(mDrawingState.layersSortedByZ);
- const size_t count = layers.size();
- for (size_t i = 0 ; i < count ; ++i) {
- const sp<Layer>& layer(layers[i]);
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& state(layer->getDrawingState());
if (state.layerStack == hw->getLayerStack() && state.z >= minLayerZ &&
state.z <= maxLayerZ && layer->isVisible() &&
layer->isSecure()) {
secureLayerIsVisible = true;
}
- }
+ });
if (!isLocalScreenshot && secureLayerIsVisible) {
ALOGW("FB is protected: PERMISSION_DENIED");
@@ -3793,10 +3760,8 @@
ALOGE("*** we just took a black screenshot ***\n"
"requested minz=%d, maxz=%d, layerStack=%d",
minLayerZ, maxLayerZ, hw->getLayerStack());
- const LayerVector& layers( mDrawingState.layersSortedByZ );
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<Layer>& layer(layers[i]);
+ size_t i = 0;
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
const Layer::State& state(layer->getDrawingState());
const bool visible = (state.layerStack == hw->getLayerStack())
&& (state.z >= minLayerZ && state.z <= maxLayerZ)
@@ -3805,37 +3770,19 @@
visible ? '+' : '-',
i, layer->getName().string(), state.layerStack, state.z,
layer->isVisible(), state.flags, state.alpha);
- }
+ i++;
+ });
}
}
// ---------------------------------------------------------------------------
-SurfaceFlinger::LayerVector::LayerVector() {
+void SurfaceFlinger::State::traverseInZOrder(const std::function<void(Layer*)>& consume) const {
+ layersSortedByZ.traverseInZOrder(consume);
}
-SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
- : SortedVector<sp<Layer> >(rhs) {
-}
-
-int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
- const void* rhs) const
-{
- // sort layers per layer-stack, then by z-order and finally by sequence
- const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
- const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
-
- uint32_t ls = l->getCurrentState().layerStack;
- uint32_t rs = r->getCurrentState().layerStack;
- if (ls != rs)
- return ls - rs;
-
- uint32_t lz = l->getCurrentState().z;
- uint32_t rz = r->getCurrentState().z;
- if (lz != rz)
- return lz - rz;
-
- return l->sequence - r->sequence;
+void SurfaceFlinger::State::traverseInReverseZOrder(const std::function<void(Layer*)>& consume) const {
+ layersSortedByZ.traverseInReverseZOrder(consume);
}
}; // namespace android