diff options
author | 2025-03-24 11:12:01 -0700 | |
---|---|---|
committer | 2025-03-24 11:12:01 -0700 | |
commit | 631b37078a3d09e2ee5f574fc27543e86991d079 (patch) | |
tree | 96a44c8b90d71db13ea0e753ba713d260949759c /libs | |
parent | e511fd4008548784561ef38304885293b50a8141 (diff) | |
parent | 65fb1c6daa8234ddc9f2d06972efcb40a425522e (diff) |
Merge "Add border API to surface control" into main
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gui/Android.bp | 1 | ||||
-rw-r--r-- | libs/gui/LayerState.cpp | 8 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 13 | ||||
-rw-r--r-- | libs/gui/android/gui/BorderSettings.aidl | 24 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 12 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 2 | ||||
-rw-r--r-- | libs/renderengine/Android.bp | 9 | ||||
-rw-r--r-- | libs/renderengine/include/renderengine/LayerSettings.h | 7 | ||||
-rw-r--r-- | libs/renderengine/skia/SkiaRenderEngine.cpp | 24 |
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; |