Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9e4f46c authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Clean up duplicate shadow lengths in layer snapshot

The shadow length is currently tracked in both the LayerFE
CompositionState and the shadow settings, which are used by the
RenderEngine. We can consolidate these fields and track shadow
settings in the LayerFE CompositionState. This makes sense because
we want the LayerFE CompositionState to contain all relevant
information that it can pass to the RenderEngine without calling
back into the frontend.

Bug: 302551905
Test: presubmit

Change-Id: I583c43993cf73784c6fec9ec2d40f2c76d21adeb
parent 6c0e32c0
Loading
Loading
Loading
Loading
+1 −41
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/ShadowSettings.h>
#include <ui/StretchEffect.h>
#include <ui/Transform.h>

@@ -97,36 +98,6 @@ struct PixelSource {
    half3 solidColor = half3(0.0f, 0.0f, 0.0f);
};

/*
 * Contains the configuration for the shadows drawn by single layer. Shadow follows
 * material design guidelines.
 */
struct ShadowSettings {
    // Boundaries of the shadow.
    FloatRect boundaries = FloatRect();

    // Color to the ambient shadow. The alpha is premultiplied.
    vec4 ambientColor = vec4();

    // Color to the spot shadow. The alpha is premultiplied. The position of the spot shadow
    // depends on the light position.
    vec4 spotColor = vec4();

    // Position of the light source used to cast the spot shadow.
    vec3 lightPos = vec3();

    // Radius of the spot light source. Smaller radius will have sharper edges,
    // larger radius will have softer shadows
    float lightRadius = 0.f;

    // Length of the cast shadow. If length is <= 0.f no shadows will be drawn.
    float length = 0.f;

    // If true fill in the casting layer is translucent and the shadow needs to fill the bounds.
    // Otherwise the shadow will only be drawn around the edges of the casting layer.
    bool casterIsTranslucent = false;
};

// The settings that RenderEngine requires for correctly rendering a Layer.
struct LayerSettings {
    // Geometry information
@@ -194,17 +165,6 @@ static inline bool operator==(const PixelSource& lhs, const PixelSource& rhs) {
    return lhs.buffer == rhs.buffer && lhs.solidColor == rhs.solidColor;
}

static inline bool operator==(const ShadowSettings& lhs, const ShadowSettings& rhs) {
    return lhs.boundaries == rhs.boundaries && lhs.ambientColor == rhs.ambientColor &&
            lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos &&
            lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length &&
            lhs.casterIsTranslucent == rhs.casterIsTranslucent;
}

static inline bool operator!=(const ShadowSettings& lhs, const ShadowSettings& rhs) {
    return !(operator==(lhs, rhs));
}

static inline bool operator==(const LayerSettings& lhs, const LayerSettings& rhs) {
    if (lhs.blurRegions.size() != rhs.blurRegions.size()) {
        return false;
+23 −32
Original line number Diff line number Diff line
@@ -403,7 +403,7 @@ public:
    }

    void expectShadowColor(const renderengine::LayerSettings& castingLayer,
                           const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
                           const ShadowSettings& shadow, const ubyte4& casterColor,
                           const ubyte4& backgroundColor) {
        const Rect casterRect(castingLayer.geometry.boundaries);
        Region casterRegion = Region(casterRect);
@@ -443,8 +443,7 @@ public:
                          backgroundColor.a);
    }

    void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
                                        const renderengine::ShadowSettings& shadow,
    void expectShadowColorWithoutCaster(const FloatRect& casterBounds, const ShadowSettings& shadow,
                                        const ubyte4& backgroundColor) {
        const float shadowInset = shadow.length * -1.0f;
        const Rect casterRect(casterBounds);
@@ -463,9 +462,9 @@ public:
                          backgroundColor.a);
    }

    static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
    static ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
                                            bool casterIsTranslucent) {
        renderengine::ShadowSettings shadow;
        ShadowSettings shadow;
        shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
        shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
        shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
@@ -602,12 +601,10 @@ public:
    void fillGreenColorBufferThenClearRegion();

    template <typename SourceVariant>
    void drawShadow(const renderengine::LayerSettings& castingLayer,
                    const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
                    const ubyte4& backgroundColor);
    void drawShadow(const renderengine::LayerSettings& castingLayer, const ShadowSettings& shadow,
                    const ubyte4& casterColor, const ubyte4& backgroundColor);

    void drawShadowWithoutCaster(const FloatRect& castingBounds,
                                 const renderengine::ShadowSettings& shadow,
    void drawShadowWithoutCaster(const FloatRect& castingBounds, const ShadowSettings& shadow,
                                 const ubyte4& backgroundColor);

    // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
@@ -1337,8 +1334,8 @@ void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {

template <typename SourceVariant>
void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
                                  const renderengine::ShadowSettings& shadow,
                                  const ubyte4& casterColor, const ubyte4& backgroundColor) {
                                  const ShadowSettings& shadow, const ubyte4& casterColor,
                                  const ubyte4& backgroundColor) {
    renderengine::DisplaySettings settings;
    settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
    settings.physicalDisplay = fullscreenRect();
@@ -1374,7 +1371,7 @@ void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLaye
}

void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
                                               const renderengine::ShadowSettings& shadow,
                                               const ShadowSettings& shadow,
                                               const ubyte4& backgroundColor) {
    renderengine::DisplaySettings settings;
    settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
@@ -2103,9 +2100,8 @@ TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
    const float shadowLength = 5.0f;
    Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
    casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
    renderengine::ShadowSettings settings =
            getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
                              false /* casterIsTranslucent */);
    ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
                                                shadowLength, false /* casterIsTranslucent */);

    drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
    expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
@@ -2127,9 +2123,8 @@ TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
    renderengine::LayerSettings castingLayer;
    castingLayer.geometry.boundaries = casterBounds.toFloatRect();
    castingLayer.alpha = 1.0f;
    renderengine::ShadowSettings settings =
            getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
                              false /* casterIsTranslucent */);
    ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
                                                shadowLength, false /* casterIsTranslucent */);

    drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
    expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
@@ -2152,9 +2147,8 @@ TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
    castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
    castingLayer.geometry.boundaries = casterBounds.toFloatRect();
    castingLayer.alpha = 1.0f;
    renderengine::ShadowSettings settings =
            getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
                              false /* casterIsTranslucent */);
    ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
                                                shadowLength, false /* casterIsTranslucent */);

    drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
    expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
@@ -2177,9 +2171,8 @@ TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
    castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
    castingLayer.geometry.boundaries = casterBounds.toFloatRect();
    castingLayer.alpha = 1.0f;
    renderengine::ShadowSettings settings =
            getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
                              false /* casterIsTranslucent */);
    ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
                                                shadowLength, false /* casterIsTranslucent */);

    drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
                                                              backgroundColor);
@@ -2204,9 +2197,8 @@ TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
    castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
    castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
    castingLayer.alpha = 1.0f;
    renderengine::ShadowSettings settings =
            getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
                              false /* casterIsTranslucent */);
    ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
                                                shadowLength, false /* casterIsTranslucent */);

    drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
                                                              backgroundColor);
@@ -2227,9 +2219,8 @@ TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
    renderengine::LayerSettings castingLayer;
    castingLayer.geometry.boundaries = casterBounds.toFloatRect();
    castingLayer.alpha = 0.5f;
    renderengine::ShadowSettings settings =
            getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
                              true /* casterIsTranslucent */);
    ShadowSettings settings = getShadowSettings(vec2(casterBounds.left, casterBounds.top),
                                                shadowLength, true /* casterIsTranslucent */);

    drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
                                                              backgroundColor);
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023 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 <math/vec4.h>
#include "FloatRect.h"

namespace android {

/*
 * Contains the configuration for the shadows drawn by single layer. Shadow follows
 * material design guidelines.
 */
struct ShadowSettings {
    // Boundaries of the shadow.
    FloatRect boundaries = FloatRect();

    // Color to the ambient shadow. The alpha is premultiplied.
    vec4 ambientColor = vec4();

    // Color to the spot shadow. The alpha is premultiplied. The position of the spot shadow
    // depends on the light position.
    vec4 spotColor = vec4();

    // Position of the light source used to cast the spot shadow.
    vec3 lightPos = vec3();

    // Radius of the spot light source. Smaller radius will have sharper edges,
    // larger radius will have softer shadows
    float lightRadius = 0.f;

    // Length of the cast shadow. If length is <= 0.f no shadows will be drawn.
    float length = 0.f;

    // If true fill in the casting layer is translucent and the shadow needs to fill the bounds.
    // Otherwise the shadow will only be drawn around the edges of the casting layer.
    bool casterIsTranslucent = false;
};

static inline bool operator==(const ShadowSettings& lhs, const ShadowSettings& rhs) {
    return lhs.boundaries == rhs.boundaries && lhs.ambientColor == rhs.ambientColor &&
            lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos &&
            lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length &&
            lhs.casterIsTranslucent == rhs.casterIsTranslucent;
}

static inline bool operator!=(const ShadowSettings& lhs, const ShadowSettings& rhs) {
    return !(operator==(lhs, rhs));
}

} // namespace android
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <ui/LayerStack.h>
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/ShadowSettings.h>
#include <ui/Transform.h>

// TODO(b/129481165): remove the #pragma below and fix conversion issues
@@ -132,8 +133,7 @@ struct LayerFECompositionState {
    // The bounds of the layer in layer local coordinates
    FloatRect geomLayerBounds;

    // length of the shadow in screen space
    float shadowRadius{0.f};
    ShadowSettings shadowSettings;

    // List of regions that require blur
    std::vector<BlurRegion> blurRegions;
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ void LayerFECompositionState::dump(std::string& out) const {
    dumpVal(out, "geomLayerBounds", geomLayerBounds);

    out.append("      ");
    dumpVal(out, "shadowRadius", shadowRadius);
    dumpVal(out, "shadowLength", shadowSettings.length);

    out.append("\n      ");
    dumpVal(out, "blend", toString(blendMode), blendMode);
Loading