Add Color Layer to ASurfaceControl
Bug:122326454
Test: atest CtsViewTestCases:android.view.cts.ASurfaceControlTests
Change-Id: Ib05ad70d838c79aa6f2e309217b93906c950b6fa
diff --git a/include/android/surface_control.h b/include/android/surface_control.h
index 430f81b..0573187 100644
--- a/include/android/surface_control.h
+++ b/include/android/surface_control.h
@@ -241,6 +241,17 @@
int acquire_fence_fd = -1) __INTRODUCED_IN(29);
/**
+ * Updates the color for |surface_control|. This will make the background color for the
+ * ASurfaceControl visible in transparent regions of the surface. Colors |r|, |g|,
+ * and |b| must be within the range that is valid for |dataspace|. |dataspace| and |alpha|
+ * will be the dataspace and alpha set for the background color layer.
+ */
+void ASurfaceTransaction_setColor(ASurfaceTransaction* transaction,
+ ASurfaceControl* surface_control, float r, float g, float b,
+ float alpha, ADataSpace dataspace)
+ __INTRODUCED_IN(29);
+
+/**
* |source| the sub-rect within the buffer's content to be rendered inside the surface's area
* The surface's source rect is clipped by the bounds of its current buffer. The source rect's width
* and height must be > 0.
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 40b55fa..ab92973 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -97,6 +97,9 @@
output.writeStrongBinder(cachedBuffer.token);
output.writeInt32(cachedBuffer.bufferId);
+ output.writeFloat(colorAlpha);
+ output.writeUint32(static_cast<uint32_t>(colorDataspace));
+
return NO_ERROR;
}
@@ -170,6 +173,9 @@
cachedBuffer.token = input.readStrongBinder();
cachedBuffer.bufferId = input.readInt32();
+ colorAlpha = input.readFloat();
+ colorDataspace = static_cast<ui::Dataspace>(input.readUint32());
+
return NO_ERROR;
}
@@ -382,6 +388,14 @@
what |= eCachedBufferChanged;
cachedBuffer = other.cachedBuffer;
}
+ if (other.what & eColorAlphaChanged) {
+ what |= eColorAlphaChanged;
+ colorAlpha = other.colorAlpha;
+ }
+ if (other.what & eColorDataspaceChanged) {
+ what |= eColorDataspaceChanged;
+ colorDataspace = other.colorDataspace;
+ }
if ((other.what & what) != other.what) {
ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
"other.what=0x%" PRIu64 " what=0x%" PRIu64,
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7869a5b..7cc0ee5 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -643,6 +643,36 @@
return *this;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorAlpha(
+ const sp<SurfaceControl>& sc, float alpha) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+
+ s->what |= layer_state_t::eColorAlphaChanged;
+ s->colorAlpha = alpha;
+
+ registerSurfaceControlForCallback(sc);
+ return *this;
+}
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorDataspace(
+ const sp<SurfaceControl>& sc, ui::Dataspace dataspace) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+
+ s->what |= layer_state_t::eColorDataspaceChanged;
+ s->colorDataspace = dataspace;
+
+ registerSurfaceControlForCallback(sc);
+ return *this;
+}
+
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTransform(
const sp<SurfaceControl>& sc, uint32_t transform) {
layer_state_t* s = getLayerState(sc);
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index af31420..c1750cf 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -85,6 +85,8 @@
eCornerRadiusChanged = 0x80000000,
eFrameChanged = 0x1'00000000,
eCachedBufferChanged = 0x2'00000000,
+ eColorAlphaChanged = 0x3'00000000,
+ eColorDataspaceChanged = 0x4'00000000,
};
layer_state_t()
@@ -110,7 +112,9 @@
dataspace(ui::Dataspace::UNKNOWN),
surfaceDamageRegion(),
api(-1),
- colorTransform(mat4()) {
+ colorTransform(mat4()),
+ colorAlpha(0),
+ colorDataspace(ui::Dataspace::UNKNOWN) {
matrix.dsdx = matrix.dtdy = 1.0f;
matrix.dsdy = matrix.dtdx = 0.0f;
hdrMetadata.validTypes = 0;
@@ -180,6 +184,9 @@
#endif
cached_buffer_t cachedBuffer;
+
+ float colorAlpha;
+ ui::Dataspace colorDataspace;
};
struct ComposerState {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index b9686c3..2563351 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -324,6 +324,12 @@
Transaction& setColor(const sp<SurfaceControl>& sc, const half3& color);
+ // Sets the alpha of the background color layer if it exists.
+ Transaction& setColorAlpha(const sp<SurfaceControl>& sc, float alpha);
+
+ // Sets the dataspace of the background color layer if it exists.
+ Transaction& setColorDataspace(const sp<SurfaceControl>& sc, ui::Dataspace dataspace);
+
Transaction& setTransform(const sp<SurfaceControl>& sc, uint32_t transform);
Transaction& setTransformToDisplayInverse(const sp<SurfaceControl>& sc,
bool transformToDisplayInverse);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index aa9bc15..ef77590 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -109,6 +109,7 @@
mCurrentState.cornerRadius = 0.0f;
mCurrentState.api = -1;
mCurrentState.hasColorTransform = false;
+ mCurrentState.colorDataspace = ui::Dataspace::UNKNOWN;
// drawing state & current state are identical
mDrawingState = mCurrentState;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 95a8630..0f83464 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -202,6 +202,8 @@
mat4 colorTransform;
bool hasColorTransform;
+ ui::Dataspace colorDataspace; // The dataspace of the background color layer
+
// The deque of callback handles for this frame. The back of the deque contains the most
// recent callback handle.
std::deque<sp<CallbackHandle>> callbackHandles;
@@ -308,6 +310,8 @@
const std::vector<sp<CallbackHandle>>& /*handles*/) {
return false;
};
+ virtual bool setColorAlpha(float /*alpha*/) { return false; };
+ virtual bool setColorDataspace(ui::Dataspace /*dataspace*/) { return false; };
ui::Dataspace getDataSpace() const { return mCurrentDataSpace; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3f6298f..709b1ef 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3828,6 +3828,12 @@
if (layer->setColor(s.color))
flags |= eTraversalNeeded;
}
+ if (what & layer_state_t::eColorAlphaChanged) {
+ if (layer->setColorAlpha(s.colorAlpha)) flags |= eTraversalNeeded;
+ }
+ if (what & layer_state_t::eColorDataspaceChanged) {
+ if (layer->setColorDataspace(s.colorDataspace)) flags |= eTraversalNeeded;
+ }
if (what & layer_state_t::eColorTransformChanged) {
if (layer->setColorTransform(s.colorTransform)) {
flags |= eTraversalNeeded;