SurfaceFlinger: Implement merging of transaction objects.
Useful for WindowManager to collect multiple transactions
from independent units.
Test: Transaction_test.cpp
Change-Id: I52e89b038e3b375493169991e41cb75b67550264
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index bfc6f28..b5295f2 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -136,5 +136,101 @@
return NO_ERROR;
}
+void DisplayState::merge(const DisplayState& other) {
+ if (other.what & eSurfaceChanged) {
+ what |= eSurfaceChanged;
+ surface = other.surface;
+ }
+ if (other.what & eLayerStackChanged) {
+ what |= eLayerStackChanged;
+ layerStack = other.layerStack;
+ }
+ if (other.what & eDisplayProjectionChanged) {
+ what |= eDisplayProjectionChanged;
+ orientation = other.orientation;
+ viewport = other.viewport;
+ frame = other.frame;
+ }
+ if (other.what & eDisplaySizeChanged) {
+ what |= eDisplaySizeChanged;
+ width = other.width;
+ height = other.height;
+ }
+}
+
+void layer_state_t::merge(const layer_state_t& other) {
+ if (other.what & ePositionChanged) {
+ what |= ePositionChanged;
+ x = other.x;
+ y = other.y;
+ }
+ if (other.what & eLayerChanged) {
+ what |= eLayerChanged;
+ z = other.z;
+ }
+ if (other.what & eSizeChanged) {
+ what |= eSizeChanged;
+ w = other.w;
+ h = other.h;
+ }
+ if (other.what & eAlphaChanged) {
+ what |= eAlphaChanged;
+ alpha = other.alpha;
+ }
+ if (other.what & eMatrixChanged) {
+ what |= eMatrixChanged;
+ matrix = other.matrix;
+ }
+ if (other.what & eTransparentRegionChanged) {
+ what |= eTransparentRegionChanged;
+ transparentRegion = other.transparentRegion;
+ }
+ if (other.what & eFlagsChanged) {
+ what |= eFlagsChanged;
+ flags = other.flags;
+ mask = other.mask;
+ }
+ if (other.what & eLayerStackChanged) {
+ what |= eLayerStackChanged;
+ layerStack = other.layerStack;
+ }
+ if (other.what & eCropChanged) {
+ what |= eCropChanged;
+ crop = other.crop;
+ }
+ if (other.what & eDeferTransaction) {
+ what |= eDeferTransaction;
+ barrierHandle = other.barrierHandle;
+ barrierGbp = other.barrierGbp;
+ frameNumber = other.frameNumber;
+ }
+ if (other.what & eFinalCropChanged) {
+ what |= eFinalCropChanged;
+ finalCrop = other.finalCrop;
+ }
+ if (other.what & eOverrideScalingModeChanged) {
+ what |= eOverrideScalingModeChanged;
+ overrideScalingMode = other.overrideScalingMode;
+ }
+ if (other.what & eGeometryAppliesWithResize) {
+ what |= eGeometryAppliesWithResize;
+ }
+ if (other.what & eReparentChildren) {
+ what |= eReparentChildren;
+ reparentHandle = other.reparentHandle;
+ }
+ if (other.what & eDetachChildren) {
+ what |= eDetachChildren;
+ }
+ if (other.what & eRelativeLayerChanged) {
+ what |= eRelativeLayerChanged;
+ z = other.z;
+ relativeLayerHandle = other.relativeLayerHandle;
+ }
+ if (other.what & eReparent) {
+ what |= eReparent;
+ parentHandleForChild = other.parentHandleForChild;
+ }
+}
}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 15c4c9a..2adc273 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -104,6 +104,30 @@
mComposerStates = other.mComposerStates;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
+ for (auto const& state : other.mComposerStates) {
+ ssize_t index = mComposerStates.indexOf(state);
+ if (index < 0) {
+ mComposerStates.add(state);
+ } else {
+ mComposerStates.editItemAt(static_cast<size_t>(index)).state.merge(state.state);
+ }
+ }
+ other.mComposerStates.clear();
+
+ for (auto const& state : other.mDisplayStates) {
+ ssize_t index = mDisplayStates.indexOf(state);
+ if (index < 0) {
+ mDisplayStates.add(state);
+ } else {
+ mDisplayStates.editItemAt(static_cast<size_t>(index)).merge(state);
+ }
+ }
+ other.mDisplayStates.clear();
+
+ return *this;
+}
+
status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
if (mStatus != NO_ERROR) {
return mStatus;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index ae6965a..f3fb82f 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -77,6 +77,7 @@
matrix.dsdy = matrix.dtdx = 0.0f;
}
+ void merge(const layer_state_t& other);
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
@@ -144,6 +145,7 @@
};
DisplayState();
+ void merge(const DisplayState& other);
uint32_t what;
sp<IBinder> token;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index d63dafe..87fdfae 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -144,7 +144,9 @@
Transaction(Transaction const& other);
status_t apply(bool synchronous = false);
-
+ // Merge another transaction in to this one, clearing other
+ // as if it had been applied.
+ Transaction& merge(Transaction&& other);
Transaction& show(const sp<SurfaceControl>& sc);
Transaction& hide(const sp<SurfaceControl>& sc);
Transaction& setPosition(const sp<SurfaceControl>& sc,
@@ -175,8 +177,6 @@
float alpha);
Transaction& setMatrix(const sp<SurfaceControl>& sc,
float dsdx, float dtdx, float dtdy, float dsdy);
- Transaction& setOrientation(const sp<SurfaceControl>& sc,
- const Rect& crop);
Transaction& setCrop(const sp<SurfaceControl>& sc, const Rect& crop);
Transaction& setFinalCrop(const sp<SurfaceControl>& sc, const Rect& crop);
Transaction& setLayerStack(const sp<SurfaceControl>& sc, uint32_t layerStack);