diff options
author | 2021-02-10 05:42:36 +0000 | |
---|---|---|
committer | 2021-02-10 05:42:36 +0000 | |
commit | 1c69780efbb60608767a28a0887f2cb548fa2002 (patch) | |
tree | e3ac9f7ffebbd3d4ba24921f73311a09ddbf2ec8 | |
parent | 70091d6660ae38137971ebed061c3aedad775937 (diff) | |
parent | cdb4ed7743f5abfa4e9a785b14a50ca25c906f3f (diff) |
Merge "Add plumbing for sending stretch effect to SF" into sc-dev
-rw-r--r-- | libs/gui/LayerState.cpp | 6 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 17 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 5 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 4 | ||||
-rw-r--r-- | libs/renderengine/include/renderengine/LayerSettings.h | 3 | ||||
-rw-r--r-- | libs/renderengine/skia/SkiaGLRenderEngine.cpp | 3 | ||||
-rw-r--r-- | libs/ui/include/ui/StretchEffect.h | 57 | ||||
-rw-r--r-- | services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 19 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 6 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 |
11 files changed, 126 insertions, 2 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index fff33056e1..f053372cb0 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -167,6 +167,9 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeInt32, region.right); SAFE_PARCEL(output.writeInt32, region.bottom); } + + SAFE_PARCEL(output.write, stretchEffect); + return NO_ERROR; } @@ -290,6 +293,9 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readInt32, ®ion.bottom); blurRegions.push_back(region); } + + SAFE_PARCEL(input.read, stretchEffect); + return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 4493a21fc3..27fb2a8cd7 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1569,6 +1569,23 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApply return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setStretchEffect( + const sp<SurfaceControl>& sc, float left, float top, float right, float bottom, float vecX, + float vecY, float maxAmount) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eStretchChanged; + s->stretchEffect = StretchEffect{.area = {left, top, right, bottom}, + .vectorX = vecX, + .vectorY = vecY, + .maxAmount = maxAmount}; + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 2f9a0c01eb..b273805e25 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -56,6 +56,7 @@ #include <ui/Rect.h> #include <ui/Region.h> #include <ui/Rotation.h> +#include <ui/StretchEffect.h> #include <ui/Transform.h> #include <utils/Errors.h> @@ -135,6 +136,7 @@ struct layer_state_t { eFrameTimelineInfoChanged = 0x800'00000000, eBlurRegionsChanged = 0x1000'00000000, eAutoRefreshChanged = 0x2000'00000000, + eStretchChanged = 0x4000'00000000, }; layer_state_t(); @@ -244,6 +246,9 @@ struct layer_state_t { // can and not wait for a frame to become available. This is only relevant // in shared buffer mode. bool autoRefresh; + + // Stretch effect to be applied to this layer + StretchEffect stretchEffect; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index bd9f066f96..e89f3a7b44 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -550,6 +550,10 @@ public: // transactions from blocking each other. Transaction& setApplyToken(const sp<IBinder>& token); + Transaction& setStretchEffect(const sp<SurfaceControl>& sc, float left, float top, + float right, float bottom, float vecX, float vecY, + float maxAmount); + status_t setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h index 3a727c9caf..7661233967 100644 --- a/libs/renderengine/include/renderengine/LayerSettings.h +++ b/libs/renderengine/include/renderengine/LayerSettings.h @@ -28,6 +28,7 @@ #include <ui/GraphicTypes.h> #include <ui/Rect.h> #include <ui/Region.h> +#include <ui/StretchEffect.h> #include <ui/Transform.h> namespace android { @@ -155,6 +156,8 @@ struct LayerSettings { std::vector<BlurRegion> blurRegions; + StretchEffect stretchEffect; + // Name associated with the layer for debugging purposes. std::string name; }; diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index dd26b17eb4..1eb8da9b25 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -491,6 +491,9 @@ sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> sh const LayerSettings* layer, const DisplaySettings& display, bool undoPremultipliedAlpha) { + if (layer->stretchEffect.hasEffect()) { + // TODO: Implement + } if (mUseColorManagement && needsLinearEffect(layer->colorTransform, layer->sourceDataspace, display.outputDataspace)) { LinearEffect effect = LinearEffect{.inputDataspace = layer->sourceDataspace, diff --git a/libs/ui/include/ui/StretchEffect.h b/libs/ui/include/ui/StretchEffect.h new file mode 100644 index 0000000000..1d2460ccfc --- /dev/null +++ b/libs/ui/include/ui/StretchEffect.h @@ -0,0 +1,57 @@ +/* + * Copyright 2021 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. + */ + +#pragma once + +#include <utils/Flattenable.h> +#include "FloatRect.h" + +#include <type_traits> + +namespace android { + +struct StretchEffect : public LightFlattenablePod<StretchEffect> { + FloatRect area = {0, 0, 0, 0}; + float vectorX = 0; + float vectorY = 0; + float maxAmount = 0; + + bool operator==(const StretchEffect& other) const { + return area == other.area && vectorX == other.vectorX && vectorY == other.vectorY && + maxAmount == other.maxAmount; + } + + static bool isZero(float value) { + constexpr float NON_ZERO_EPSILON = 0.001f; + return fabsf(value) <= NON_ZERO_EPSILON; + } + + bool isNoOp() const { return isZero(vectorX) && isZero(vectorY); } + + bool hasEffect() const { return !isNoOp(); } + + void sanitize() { + // If the area is empty, or the max amount is zero, then reset back to defaults + if (area.bottom >= area.top || area.left >= area.right || isZero(maxAmount)) { + *this = StretchEffect{}; + } + } +}; + +static_assert(std::is_trivially_copyable<StretchEffect>::value, + "StretchEffect must be trivially copyable to be flattenable"); + +} // namespace android
\ No newline at end of file diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h index c445d5b615..8402149c57 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h @@ -34,6 +34,7 @@ #include <gui/BufferQueue.h> #include <ui/GraphicBuffer.h> #include <ui/GraphicTypes.h> +#include <ui/StretchEffect.h> #include "DisplayHardware/Hal.h" @@ -123,6 +124,8 @@ struct LayerFECompositionState { // List of regions that require blur std::vector<BlurRegion> blurRegions; + StretchEffect stretchEffect; + /* * Geometry state */ diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 87ca9c73c3..27b2b87d77 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -488,6 +488,7 @@ void Layer::prepareBasicGeometryCompositionState() { compositionState->alpha = alpha; compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius; compositionState->blurRegions = drawingState.blurRegions; + compositionState->stretchEffect = drawingState.stretchEffect; } void Layer::prepareGeometryCompositionState() { @@ -556,8 +557,8 @@ void Layer::preparePerFrameCompositionState() { isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf; // Force client composition for special cases known only to the front-end. - if (isHdrY410() || usesRoundedCorners || drawShadows() || - getDrawingState().blurRegions.size() > 0) { + if (isHdrY410() || usesRoundedCorners || drawShadows() || drawingState.blurRegions.size() > 0 || + drawingState.stretchEffect.hasEffect()) { compositionState->forceClientComposition = true; } } @@ -656,6 +657,7 @@ std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientCom layerSettings.backgroundBlurRadius = getBackgroundBlurRadius(); layerSettings.blurRegions = getBlurRegions(); } + layerSettings.stretchEffect = getDrawingState().stretchEffect; // Record the name of the layer for debugging further down the stack. layerSettings.name = getName(); return layerSettings; @@ -1421,6 +1423,19 @@ bool Layer::setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHin return true; } +bool Layer::setStretchEffect(const StretchEffect& effect) { + StretchEffect temp = effect; + temp.sanitize(); + if (mCurrentState.stretchEffect == temp) { + return false; + } + mCurrentState.sequence++; + mCurrentState.stretchEffect = temp; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); + return true; +} + void Layer::updateTreeHasFrameRateVote() { const auto traverseTree = [&](const LayerVector::Visitor& visitor) { auto parent = getParent(); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 36ae19cb46..273601f440 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -32,6 +32,7 @@ #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <ui/Region.h> +#include <ui/StretchEffect.h> #include <ui/Transform.h> #include <utils/RefBase.h> #include <utils/Timers.h> @@ -323,6 +324,9 @@ public: // An arbitrary threshold for the number of BufferlessSurfaceFrames in the state. Used to // trigger a warning if the number of SurfaceFrames crosses the threshold. static constexpr uint32_t kStateSurfaceFramesThreshold = 25; + + // Stretch effect to apply to this layer + StretchEffect stretchEffect; }; /* @@ -938,6 +942,8 @@ public: bool backpressureEnabled() { return mDrawingState.flags & layer_state_t::eEnableBackpressure; } + bool setStretchEffect(const StretchEffect& effect); + protected: class SyncPoint { public: diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 04e9a6d3ff..a36502cea1 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3950,6 +3950,11 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (what & layer_state_t::eAutoRefreshChanged) { layer->setAutoRefresh(s.autoRefresh); } + if (what & layer_state_t::eStretchChanged) { + if (layer->setStretchEffect(s.stretchEffect)) { + flags |= eTraversalNeeded; + } + } // This has to happen after we reparent children because when we reparent to null we remove // child layers from current state and remove its relative z. If the children are reparented in // the same transaction, then we have to make sure we reparent the children first so we do not |