Camera: Add per-surface mirroring mode
Add the support to do per output surface mirror mode. Previously
mirroring mode is set per OutputConfiguration, which could contain
multiple shared surfaces.
Flag: com.android.internal.camera.flags.mirror_mode_shared_surfaces
Test: atest MultiViewTest
Bug: 298899993
Change-Id: I3654cb585d243365b62a10131c21a869af754e73
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 2d1af32..48a7338 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -22,12 +22,14 @@
#include <camera/camera2/OutputConfiguration.h>
#include <camera/StringUtils.h>
+#include <com_android_internal_camera_flags.h>
#include <binder/Parcel.h>
#include <gui/view/Surface.h>
#include <system/camera_metadata.h>
#include <system/graphics.h>
#include <utils/String8.h>
+namespace flags = com::android::internal::camera::flags;
namespace android {
@@ -95,7 +97,21 @@
return mTimestampBase;
}
-int OutputConfiguration::getMirrorMode() const {
+int OutputConfiguration::getMirrorMode(sp<IGraphicBufferProducer> surface) const {
+ if (!flags::mirror_mode_shared_surfaces()) {
+ return mMirrorMode;
+ }
+
+ // Use per-producer mirror mode if available.
+ for (size_t i = 0; i < mGbps.size(); i++) {
+ if (mGbps[i] == surface) {
+ return mMirrorModeForProducers[i];
+ }
+ }
+
+ // For surface that doesn't belong to this output configuration, use
+ // mMirrorMode as default.
+ ALOGW("%s: Surface doesn't belong to this OutputConfiguration!", __FUNCTION__);
return mMirrorMode;
}
@@ -251,6 +267,12 @@
return err;
}
+ std::vector<int> mirrorModeForProducers;
+ if ((err = parcel->readInt32Vector(&mirrorModeForProducers)) != OK) {
+ ALOGE("%s: Failed to read mirroring mode for surfaces from parcel", __FUNCTION__);
+ return err;
+ }
+
int useReadoutTimestamp = 0;
if ((err = parcel->readInt32(&useReadoutTimestamp)) != OK) {
ALOGE("%s: Failed to read useReadoutTimestamp flag from parcel", __FUNCTION__);
@@ -286,6 +308,7 @@
mStreamUseCase = streamUseCase;
mTimestampBase = timestampBase;
mMirrorMode = mirrorMode;
+ mMirrorModeForProducers = std::move(mirrorModeForProducers);
mUseReadoutTimestamp = useReadoutTimestamp != 0;
for (auto& surface : surfaceShims) {
ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
@@ -409,6 +432,9 @@
err = parcel->writeInt32(mMirrorMode);
if (err != OK) return err;
+ err = parcel->writeInt32Vector(mMirrorModeForProducers);
+ if (err != OK) return err;
+
err = parcel->writeInt32(mUseReadoutTimestamp ? 1 : 0);
if (err != OK) return err;
@@ -438,6 +464,20 @@
return true;
}
+template <typename T>
+static bool simpleVectorsLessThan(T first, T second) {
+ if (first.size() != second.size()) {
+ return first.size() < second.size();
+ }
+
+ for (size_t i = 0; i < first.size(); i++) {
+ if (first[i] != second[i]) {
+ return first[i] < second[i];
+ }
+ }
+ return false;
+}
+
bool OutputConfiguration::gbpsEqual(const OutputConfiguration& other) const {
const std::vector<sp<IGraphicBufferProducer> >& otherGbps =
other.getGraphicBufferProducers();
@@ -449,20 +489,20 @@
return simpleVectorsEqual(othersensorPixelModesUsed, mSensorPixelModesUsed);
}
+bool OutputConfiguration::mirrorModesEqual(const OutputConfiguration& other) const {
+ const std::vector<int>& otherMirrorModes = other.getMirrorModes();
+ return simpleVectorsEqual(otherMirrorModes, mMirrorModeForProducers);
+
+}
+
bool OutputConfiguration::sensorPixelModesUsedLessThan(const OutputConfiguration& other) const {
const std::vector<int32_t>& spms = other.getSensorPixelModesUsed();
+ return simpleVectorsLessThan(mSensorPixelModesUsed, spms);
+}
- if (mSensorPixelModesUsed.size() != spms.size()) {
- return mSensorPixelModesUsed.size() < spms.size();
- }
-
- for (size_t i = 0; i < spms.size(); i++) {
- if (mSensorPixelModesUsed[i] != spms[i]) {
- return mSensorPixelModesUsed[i] < spms[i];
- }
- }
-
- return false;
+bool OutputConfiguration::mirrorModesLessThan(const OutputConfiguration& other) const {
+ const std::vector<int>& otherMirrorModes = other.getMirrorModes();
+ return simpleVectorsLessThan(mMirrorModeForProducers, otherMirrorModes);
}
bool OutputConfiguration::gbpsLessThan(const OutputConfiguration& other) const {