am 3372cc25: resolved conflicts for merge of 03eccb66 to lmp-mr1-dev-plus-aosp

* commit '3372cc25df255b94e4eb75920afaf43ee5edc39f':
  SurfaceFlinger: Attempt to attribute fds to layers
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 61edbff..13d1a55 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -90,7 +90,7 @@
 endif
 
 LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
-LOCAL_CPPFLAGS := -std=c++11
+LOCAL_CPPFLAGS := -std=c++1y
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
@@ -110,6 +110,8 @@
 
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 
+include external/libcxx/libcxx.mk
+
 include $(BUILD_SHARED_LIBRARY)
 
 ###############################################################
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3419295..3077d0a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -78,6 +78,12 @@
 #include "RenderEngine/RenderEngine.h"
 #include <cutils/compiler.h>
 
+#include <map>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
 #define DISPLAY_COUNT       1
 
 /*
@@ -1807,6 +1813,17 @@
     hw->swapBuffers(getHwComposer());
 }
 
+static std::set<int> getOpenFds()
+{
+    std::set<int> fds;
+    for (int fd = 0; fd < 1024; ++fd) {
+        if (fcntl(fd, F_GETFD) != -1 || errno != EBADF) {
+            fds.insert(fd);
+        }
+    }
+    return fds;
+}
+
 bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
 {
     RenderEngine& engine(getRenderEngine());
@@ -1881,6 +1898,8 @@
      * and then, render the layers targeted at the framebuffer
      */
 
+    static std::set<std::string> previousLayers;
+    std::set<std::string> currentLayers;
     const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
     const size_t count = layers.size();
     const Transform& tr = hw->getTransform();
@@ -1890,6 +1909,7 @@
             const sp<Layer>& layer(layers[i]);
             const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
             if (!clip.isEmpty()) {
+                currentLayers.insert(layer->getName().string());
                 switch (cur->getCompositionType()) {
                     case HWC_CURSOR_OVERLAY:
                     case HWC_OVERLAY: {
@@ -1925,11 +1945,86 @@
             const Region clip(dirty.intersect(
                     tr.transform(layer->visibleRegion)));
             if (!clip.isEmpty()) {
+                currentLayers.insert(layer->getName().string());
                 layer->draw(hw, clip);
             }
         }
     }
 
+    std::set<std::string> newLayers;
+    for (auto layer : currentLayers) {
+        if (previousLayers.count(layer) == 0) {
+            newLayers.insert(layer);
+        }
+    }
+    std::set<std::string> deletedLayers;
+    for (auto layer : previousLayers) {
+        if (currentLayers.count(layer) == 0) {
+            deletedLayers.insert(layer);
+        }
+    }
+    previousLayers = std::move(currentLayers);
+
+    static std::set<int> previousFds;
+    static std::unordered_map<std::string, std::set<int>> initialFds;
+
+    for (auto layer : newLayers) {
+        initialFds[layer] = previousFds;
+    }
+
+    std::set<int> currentFds = getOpenFds();
+
+    if (!deletedLayers.empty()) {
+        std::unordered_map<int, std::set<std::string>> currentBlame;
+        static std::map<int, std::set<std::string>> persistentBlame;
+        for (auto layer : deletedLayers) {
+            std::vector<int> newFds;
+            auto& layerInitialFds = initialFds[layer];
+            std::set_difference(
+                    currentFds.cbegin(), currentFds.cend(),
+                    layerInitialFds.cbegin(), layerInitialFds.cend(),
+                    std::back_inserter(newFds));
+
+            for (auto fd : newFds) {
+                currentBlame[fd].insert(layer);
+            }
+
+            initialFds.erase(layer);
+        }
+
+        for (auto blame : currentBlame) {
+            persistentBlame[blame.first] = blame.second;
+        }
+
+        auto iter = persistentBlame.cbegin();
+        while (iter != persistentBlame.cend()) {
+            if (currentFds.count(iter->first) == 0) {
+                iter = persistentBlame.erase(iter);
+            } else {
+                ++iter;
+            }
+        }
+
+        std::map<std::set<std::string>, int> blameCounts;
+        for (auto blame : persistentBlame) {
+            ++blameCounts[blame.second];
+        }
+
+        ALOGI("FD Blame: %d open fds", currentFds.size());
+        for (auto blame : blameCounts) {
+            std::string layers;
+            for (auto layer : blame.first) {
+                if (!layers.empty()) {
+                    layers += ", ";
+                }
+                layers += layer;
+            }
+            ALOGI("  %s: %d", layers.c_str(), blame.second);
+        }
+    }
+
+    previousFds = std::move(currentFds);
+
     // disable scissor at the end of the frame
     engine.disableScissor();
     return true;