summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
author Cairn Overturf <cairno@google.com> 2025-03-24 11:12:01 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-24 11:12:01 -0700
commit631b37078a3d09e2ee5f574fc27543e86991d079 (patch)
tree96a44c8b90d71db13ea0e753ba713d260949759c /libs
parente511fd4008548784561ef38304885293b50a8141 (diff)
parent65fb1c6daa8234ddc9f2d06972efcb40a425522e (diff)
Merge "Add border API to surface control" into main
Diffstat (limited to 'libs')
-rw-r--r--libs/gui/Android.bp1
-rw-r--r--libs/gui/LayerState.cpp8
-rw-r--r--libs/gui/SurfaceComposerClient.cpp13
-rw-r--r--libs/gui/android/gui/BorderSettings.aidl24
-rw-r--r--libs/gui/include/gui/LayerState.h12
-rw-r--r--libs/gui/include/gui/SurfaceComposerClient.h2
-rw-r--r--libs/renderengine/Android.bp9
-rw-r--r--libs/renderengine/include/renderengine/LayerSettings.h7
-rw-r--r--libs/renderengine/skia/SkiaRenderEngine.cpp24
9 files changed, 96 insertions, 4 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 158c54886d..2117c987e4 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -93,6 +93,7 @@ filegroup {
"android/gui/StalledTransactionInfo.aidl",
"android/**/TouchOcclusionMode.aidl",
"android/gui/TrustedOverlay.aidl",
+ "android/gui/BorderSettings.aidl",
],
}
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index ad95d1a85a..86bc97e9d3 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -180,6 +180,7 @@ status_t layer_state_t::write(Parcel& output) const
SAFE_PARCEL(output.writeParcelableVector, listener.callbackIds);
}
SAFE_PARCEL(output.writeFloat, shadowRadius);
+ SAFE_PARCEL(output.writeParcelable, borderSettings);
SAFE_PARCEL(output.writeInt32, frameRateSelectionPriority);
SAFE_PARCEL(output.writeFloat, frameRate);
SAFE_PARCEL(output.writeByte, frameRateCompatibility);
@@ -328,6 +329,8 @@ status_t layer_state_t::read(const Parcel& input)
listeners.emplace_back(listener, callbackIds);
}
SAFE_PARCEL(input.readFloat, &shadowRadius);
+ SAFE_PARCEL(input.readParcelable, &borderSettings);
+
SAFE_PARCEL(input.readInt32, &frameRateSelectionPriority);
SAFE_PARCEL(input.readFloat, &frameRate);
SAFE_PARCEL(input.readByte, &frameRateCompatibility);
@@ -727,6 +730,10 @@ void layer_state_t::merge(const layer_state_t& other) {
what |= eShadowRadiusChanged;
shadowRadius = other.shadowRadius;
}
+ if (other.what & eBorderSettingsChanged) {
+ what |= eBorderSettingsChanged;
+ borderSettings = other.borderSettings;
+ }
if (other.what & eLutsChanged) {
what |= eLutsChanged;
luts = other.luts;
@@ -881,6 +888,7 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const {
CHECK_DIFF2(diff, eBackgroundColorChanged, other, bgColor, bgColorDataspace);
if (other.what & eMetadataChanged) diff |= eMetadataChanged;
CHECK_DIFF(diff, eShadowRadiusChanged, other, shadowRadius);
+ CHECK_DIFF(diff, eBorderSettingsChanged, other, borderSettings);
CHECK_DIFF(diff, eDefaultFrameRateCompatibilityChanged, other, defaultFrameRateCompatibility);
CHECK_DIFF(diff, eFrameRateSelectionPriority, other, frameRateSelectionPriority);
CHECK_DIFF3(diff, eFrameRateChanged, other, frameRate, frameRateCompatibility,
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 69ba1d731d..786bc06f64 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2025,6 +2025,19 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShado
return *this;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBorderSettings(
+ const sp<SurfaceControl>& sc, gui::BorderSettings settings) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+
+ s->what |= layer_state_t::eBorderSettingsChanged;
+ s->borderSettings = settings;
+ return *this;
+}
+
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameRate(
const sp<SurfaceControl>& sc, float frameRate, int8_t compatibility,
int8_t changeFrameRateStrategy) {
diff --git a/libs/gui/android/gui/BorderSettings.aidl b/libs/gui/android/gui/BorderSettings.aidl
new file mode 100644
index 0000000000..547f57fe76
--- /dev/null
+++ b/libs/gui/android/gui/BorderSettings.aidl
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2025, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable BorderSettings {
+ float strokeWidth;
+ // Space is sRGB, not premultiplied, bit pattern is 0xAARRGGBB.
+ int color;
+}
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 369d3d136a..e2d27ac464 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <span>
+#include <android/gui/BorderSettings.h>
#include <android/gui/DisplayCaptureArgs.h>
#include <android/gui/IWindowInfosReportedListener.h>
#include <android/gui/LayerCaptureArgs.h>
@@ -250,6 +251,7 @@ struct layer_state_t {
ePictureProfileHandleChanged = 0x80000'00000000,
eAppContentPriorityChanged = 0x100000'00000000,
eClientDrawnCornerRadiusChanged = 0x200000'00000000,
+ eBorderSettingsChanged = 0x400000'00000000,
};
layer_state_t();
@@ -293,8 +295,8 @@ struct layer_state_t {
layer_state_t::eColorSpaceAgnosticChanged | layer_state_t::eColorTransformChanged |
layer_state_t::eCornerRadiusChanged | layer_state_t::eDimmingEnabledChanged |
layer_state_t::eHdrMetadataChanged | layer_state_t::eShadowRadiusChanged |
- layer_state_t::eStretchChanged |
- layer_state_t::ePictureProfileHandleChanged | layer_state_t::eAppContentPriorityChanged;
+ layer_state_t::eStretchChanged | layer_state_t::ePictureProfileHandleChanged |
+ layer_state_t::eAppContentPriorityChanged | layer_state_t::eBorderSettingsChanged;
// Changes which invalidates the layer's visible region in CE.
static constexpr uint64_t CONTENT_DIRTY = layer_state_t::CONTENT_CHANGES |
@@ -322,7 +324,8 @@ struct layer_state_t {
// Changes that force GPU composition.
static constexpr uint64_t COMPOSITION_EFFECTS = layer_state_t::eBackgroundBlurRadiusChanged |
layer_state_t::eBlurRegionsChanged | layer_state_t::eCornerRadiusChanged |
- layer_state_t::eShadowRadiusChanged | layer_state_t::eStretchChanged;
+ layer_state_t::eShadowRadiusChanged | layer_state_t::eStretchChanged |
+ layer_state_t::eBorderSettingsChanged;
bool hasValidBuffer() const;
void sanitize(int32_t permissions);
@@ -411,6 +414,9 @@ struct layer_state_t {
// Draws a shadow around the surface.
float shadowRadius;
+ // Draws an outline around the layer.
+ gui::BorderSettings borderSettings;
+
// Priority of the layer assigned by Window Manager.
int32_t frameRateSelectionPriority;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 668bd6fbb8..5c348cb9c7 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -679,6 +679,8 @@ public:
const Rect& source, const Rect& dst, int transform);
Transaction& setShadowRadius(const sp<SurfaceControl>& sc, float cornerRadius);
+ Transaction& setBorderSettings(const sp<SurfaceControl>& sc, gui::BorderSettings settings);
+
Transaction& setFrameRate(const sp<SurfaceControl>& sc, float frameRate,
int8_t compatibility, int8_t changeFrameRateStrategy);
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index f9b84fa948..39182aa389 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -52,6 +52,7 @@ cc_defaults {
"libtonemap",
"libsurfaceflinger_common",
"libsurfaceflingerflags",
+ "libgui_window_info_static",
],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
@@ -122,7 +123,13 @@ cc_defaults {
"skia_renderengine_deps",
"libsurfaceflinger_common_deps",
],
- static_libs: ["libskia_renderengine"],
+ static_libs: [
+ "libgui_window_info_static",
+ "libskia_renderengine",
+ ],
+ shared_libs: [
+ "libbinder",
+ ],
}
// Note: if compilation fails when adding librenderengine as a dependency, try adding
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index ecb16b2e17..3523497519 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -16,6 +16,7 @@
#pragma once
+#include <android/gui/BorderSettings.h>
#include <gui/DisplayLuts.h>
#include <math/mat4.h>
#include <math/vec3.h>
@@ -71,6 +72,10 @@ struct Geometry {
// Boundaries of the layer.
FloatRect boundaries = FloatRect();
+ // Boundaries of the layer before transparent region hint is subtracted.
+ // Effects like shadows and outline ignore the transparent region hint.
+ FloatRect originalBounds = FloatRect();
+
// Transform matrix to apply to mesh coordinates.
mat4 positionTransform = mat4();
@@ -127,6 +132,8 @@ struct LayerSettings {
ShadowSettings shadow;
+ gui::BorderSettings borderSettings;
+
int backgroundBlurRadius = 0;
std::vector<BlurRegion> blurRegions;
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index 9e1c226371..5b6edb4e30 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -986,6 +986,30 @@ void SkiaRenderEngine::drawLayersInternal(
drawShadow(canvas, rrect, layer.shadow);
}
+ // Similar to shadows, do the rendering before the clip is applied because even when the
+ // layer is occluded it should have an outline.
+ if (layer.borderSettings.strokeWidth > 0) {
+ // TODO(b/367464660): Move this code to the parent scope and
+ // update shadow rendering above to use these bounds since they should be
+ // identical.
+ SkRRect originalBounds, originalClip;
+ std::tie(originalBounds, originalClip) =
+ getBoundsAndClip(layer.geometry.boundaries, layer.geometry.roundedCornersCrop,
+ layer.geometry.roundedCornersRadius);
+ const SkRRect& preferredOriginalBounds =
+ originalBounds.isRect() && !originalClip.isEmpty() ? originalClip
+ : originalBounds;
+
+ SkRRect outlineRect = preferredOriginalBounds;
+ outlineRect.outset(layer.borderSettings.strokeWidth, layer.borderSettings.strokeWidth);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setColor(layer.borderSettings.color);
+ paint.setStyle(SkPaint::kFill_Style);
+ canvas->drawDRRect(outlineRect, preferredOriginalBounds, paint);
+ }
+
const float layerDimmingRatio = layer.whitePointNits <= 0.f
? displayDimmingRatio
: (layer.whitePointNits / maxLayerWhitePoint) * displayDimmingRatio;