Merge "Fix implicit fallthrough warnings." am: 591171a659
am: 9232ca3782

Change-Id: I5f4b3377360d20c2f7adfa7d4eff4dda3b412da8
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 69f8535..fd785df 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -53,6 +53,7 @@
         camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
         mDevice(device),
         mDeviceVersion(device->common.version),
+        mFreeBufEarly(shouldFreeBufEarly()),
         mIsAELockAvailable(false),
         mDerivePostRawSensKey(false),
         mNumPartialResults(1),
@@ -129,6 +130,10 @@
     return false;
 }
 
+bool CameraDeviceSession::shouldFreeBufEarly() {
+    return property_get_bool("ro.vendor.camera.free_buf_early", 0) == 1;
+}
+
 CameraDeviceSession::~CameraDeviceSession() {
     if (!isClosed()) {
         ALOGE("CameraDeviceSession deleted before close!");
@@ -887,6 +892,24 @@
         (*streams)[i] = &mStreamMap[id];
     }
 
+    if (mFreeBufEarly) {
+        // Remove buffers of deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                // Unmap all buffers of deleted stream
+                cleanupBuffersLocked(id);
+            }
+        }
+    }
+
     return true;
 }
 
@@ -908,7 +931,9 @@
             // Unmap all buffers of deleted stream
             // in case the configuration call succeeds and HAL
             // is able to release the corresponding resources too.
-            cleanupBuffersLocked(id);
+            if (!mFreeBufEarly) {
+                cleanupBuffersLocked(id);
+            }
             it = mStreamMap.erase(it);
         } else {
             ++it;
@@ -927,6 +952,27 @@
     mResultBatcher.setBatchedStreams(mVideoStreamIds);
 }
 
+
+void CameraDeviceSession::postProcessConfigurationFailureLocked(
+        const StreamConfiguration& requestedConfiguration) {
+    if (mFreeBufEarly) {
+        // Re-build the buf cache entry for deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                mCirculatingBuffers.emplace(id, CirculatingBuffers{});
+            }
+        }
+    }
+}
+
 Return<void> CameraDeviceSession::configureStreams(
         const StreamConfiguration& requestedConfiguration,
         ICameraDeviceSession::configureStreams_cb _hidl_cb)  {
@@ -979,6 +1025,8 @@
     // the corresponding resources of the deleted streams.
     if (ret == OK) {
         postProcessConfigurationLocked(requestedConfiguration);
+    } else {
+        postProcessConfigurationFailureLocked(requestedConfiguration);
     }
 
     if (ret == -EINVAL) {
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index af90e5a..bcee259 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -120,6 +120,8 @@
             hidl_vec<camera3_stream_t*> *streams /*out*/);
     void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration);
 
+    void postProcessConfigurationFailureLocked(const StreamConfiguration& requestedConfiguration);
+
 protected:
 
     // protecting mClosed/mDisconnected/mInitFail
@@ -142,6 +144,7 @@
 
     camera3_device_t* mDevice;
     const uint32_t mDeviceVersion;
+    const bool mFreeBufEarly;
     bool mIsAELockAvailable;
     bool mDerivePostRawSensKey;
     uint32_t mNumPartialResults;
@@ -293,6 +296,8 @@
 
     bool initialize();
 
+    static bool shouldFreeBufEarly();
+
     Status initStatus() const;
 
     // Validate and import request's input buffer and acquire fence
diff --git a/camera/device/3.3/default/CameraDeviceSession.cpp b/camera/device/3.3/default/CameraDeviceSession.cpp
index d36e9ed..60174fb 100644
--- a/camera/device/3.3/default/CameraDeviceSession.cpp
+++ b/camera/device/3.3/default/CameraDeviceSession.cpp
@@ -92,6 +92,8 @@
     // the corresponding resources of the deleted streams.
     if (ret == OK) {
         postProcessConfigurationLocked(requestedConfiguration);
+    } else {
+        postProcessConfigurationFailureLocked(requestedConfiguration);
     }
 
     if (ret == -EINVAL) {
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index 6a18161..f2e031c 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -154,6 +154,8 @@
     // the corresponding resources of the deleted streams.
     if (ret == OK) {
         postProcessConfigurationLocked_3_4(requestedConfiguration);
+    } else {
+        postProcessConfigurationFailureLocked_3_4(requestedConfiguration);
     }
 
     if (ret == -EINVAL) {
@@ -215,6 +217,23 @@
         (*streams)[i] = &mStreamMap[id];
     }
 
+    if (mFreeBufEarly) {
+        // Remove buffers of deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.v3_2.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                // Unmap all buffers of deleted stream
+                cleanupBuffersLocked(id);
+            }
+        }
+    }
     return true;
 }
 
@@ -236,7 +255,9 @@
             // Unmap all buffers of deleted stream
             // in case the configuration call succeeds and HAL
             // is able to release the corresponding resources too.
-            cleanupBuffersLocked(id);
+            if (!mFreeBufEarly) {
+                cleanupBuffersLocked(id);
+            }
             it = mStreamMap.erase(it);
         } else {
             ++it;
@@ -255,6 +276,26 @@
     mResultBatcher_3_4.setBatchedStreams(mVideoStreamIds);
 }
 
+void CameraDeviceSession::postProcessConfigurationFailureLocked_3_4(
+        const StreamConfiguration& requestedConfiguration) {
+    if (mFreeBufEarly) {
+        // Re-build the buf cache entry for deleted streams
+        for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) {
+            int id = it->first;
+            bool found = false;
+            for (const auto& stream : requestedConfiguration.streams) {
+                if (id == stream.v3_2.id) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                mCirculatingBuffers.emplace(id, CirculatingBuffers{});
+            }
+        }
+    }
+}
+
 Return<void> CameraDeviceSession::processCaptureRequest_3_4(
         const hidl_vec<V3_4::CaptureRequest>& requests,
         const hidl_vec<V3_2::BufferCache>& cachesToRemove,
diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
index 5d6a112..fdc8a5a 100644
--- a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
+++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
@@ -84,6 +84,8 @@
             camera3_stream_configuration_t *stream_list /*out*/,
             hidl_vec<camera3_stream_t*> *streams /*out*/);
     void postProcessConfigurationLocked_3_4(const StreamConfiguration& requestedConfiguration);
+    void postProcessConfigurationFailureLocked_3_4(
+            const StreamConfiguration& requestedConfiguration);
 
     Return<void> processCaptureRequest_3_4(
             const hidl_vec<V3_4::CaptureRequest>& requests,
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
index 7c9e651..0f50577 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp
@@ -32,6 +32,8 @@
 #include <log/log.h>
 #include <sync/sync.h>
 
+using namespace HWC2;
+
 namespace android {
 
 namespace {
@@ -629,9 +631,10 @@
     }
 }
 
-void getCapabilitiesHook(hwc2_device_t* /*device*/, uint32_t* outCount,
-                         int32_t* /*outCapabilities*/) {
-    *outCount = 0;
+void getCapabilitiesHook(hwc2_device_t* device, uint32_t* outCount,
+                         int32_t* outCapabilities) {
+    auto& adapter = HWC2OnFbAdapter::cast(device);
+    adapter.getCapabilities(outCount, outCapabilities);
 }
 
 int closeHook(hw_device_t* device) {
@@ -656,6 +659,10 @@
     mFbInfo.xdpi_scaled = int(mFbDevice->xdpi * 1000.0f);
     mFbInfo.ydpi_scaled = int(mFbDevice->ydpi * 1000.0f);
 
+    // Present fences aren't supported, always indicate PresentFenceIsNotReliable
+    // for FB devices
+    mCapabilities.insert(Capability::PresentFenceIsNotReliable);
+
     mVsyncThread.start(0, mFbInfo.vsync_period_ns);
 }
 
@@ -791,6 +798,23 @@
     mVsyncThread.enableCallback(enable);
 }
 
+void HWC2OnFbAdapter::getCapabilities(uint32_t* outCount,
+                                      int32_t* outCapabilities) {
+    if (outCapabilities == nullptr) {
+        *outCount = mCapabilities.size();
+        return;
+    }
+
+    auto capabilityIter = mCapabilities.cbegin();
+    for (size_t written = 0; written < *outCount; ++written) {
+        if (capabilityIter == mCapabilities.cend()) {
+            return;
+        }
+        outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
+        ++capabilityIter;
+    }
+}
+
 int64_t HWC2OnFbAdapter::VsyncThread::now() {
     struct timespec ts;
     clock_gettime(CLOCK_MONOTONIC, &ts);
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
index d6272fd..f1f11ef 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h
@@ -23,7 +23,11 @@
 #include <thread>
 #include <unordered_set>
 
+#define HWC2_INCLUDE_STRINGIFICATION
+#define HWC2_USE_CPP11
 #include <hardware/hwcomposer2.h>
+#undef HWC2_INCLUDE_STRINGIFICATION
+#undef HWC2_USE_CPP11
 
 struct framebuffer_device_t;
 
@@ -75,6 +79,7 @@
 
     void setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data);
     void enableVsync(bool enable);
+    void getCapabilities(uint32_t* outCount, int32_t* outCapabilities);
 
 private:
     framebuffer_device_t* mFbDevice{nullptr};
@@ -90,6 +95,8 @@
 
     buffer_handle_t mBuffer{nullptr};
 
+    std::unordered_set<HWC2::Capability> mCapabilities;
+
     class VsyncThread {
     public:
         static int64_t now();