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

Commit 16efdbff authored by Vishnu Nair's avatar Vishnu Nair
Browse files

[Shadows] Add shadow vertex generation code and shaders [8/n]

Bug: 136561771
Test: go/wm-smoke

Change-Id: I13e627a707d6d7a10bbd0ea6cc26bcb5c5bc9ab8
parent 440992f6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -52,6 +52,8 @@ filegroup {
        "gl/GLExtensions.cpp",
        "gl/GLFramebuffer.cpp",
        "gl/GLImage.cpp",
        "gl/GLShadowVertexGenerator.cpp",
        "gl/GLSkiaShadowPort.cpp",
        "gl/ImageManager.cpp",
        "gl/Program.cpp",
        "gl/ProgramCache.cpp",
+32 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include "GLExtensions.h"
#include "GLFramebuffer.h"
#include "GLImage.h"
#include "GLShadowVertexGenerator.h"
#include "Program.h"
#include "ProgramCache.h"

@@ -1046,7 +1047,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
        setSourceDataSpace(layer.sourceDataspace);

        if (layer.shadow.length > 0.0f) {
            // handle shadows
            handleShadow(layer.geometry.boundaries, layer.geometry.roundedCornersRadius,
                         layer.shadow);
        }
        // We only want to do a special handling for rounded corners when having rounded corners
        // is the only reason it needs to turn on blending, otherwise, we handle it like the
@@ -1561,6 +1563,35 @@ void GLESRenderEngine::FlushTracer::loop() {
    }
}

void GLESRenderEngine::handleShadow(const FloatRect& casterRect, float casterCornerRadius,
                                    const ShadowSettings& settings) {
    ATRACE_CALL();
    const float casterZ = settings.length / 2.0f;
    const GLShadowVertexGenerator shadows(casterRect, casterCornerRadius, casterZ,
                                          settings.casterIsTranslucent, settings.ambientColor,
                                          settings.spotColor, settings.lightPos,
                                          settings.lightRadius);

    // setup mesh for both shadows
    Mesh mesh = Mesh::Builder()
                        .setPrimitive(Mesh::TRIANGLES)
                        .setVertices(shadows.getVertexCount(), 2 /* size */)
                        .setShadowAttrs()
                        .setIndices(shadows.getIndexCount())
                        .build();

    Mesh::VertexArray<vec2> position = mesh.getPositionArray<vec2>();
    Mesh::VertexArray<vec4> shadowColor = mesh.getShadowColorArray<vec4>();
    Mesh::VertexArray<vec3> shadowParams = mesh.getShadowParamsArray<vec3>();
    shadows.fillVertices(position, shadowColor, shadowParams);
    shadows.fillIndices(mesh.getIndicesArray());

    mState.cornerRadius = 0.0f;
    mState.drawShadows = true;
    drawMesh(mesh);
    mState.drawShadows = false;
}

} // namespace gl
} // namespace renderengine
} // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -148,6 +148,8 @@ private:
    bool waitFence(base::unique_fd fenceFd);
    void clearWithColor(float red, float green, float blue, float alpha);
    void fillRegionWithColor(const Region& region, float red, float green, float blue, float alpha);
    void handleShadow(const FloatRect& casterRect, float casterCornerRadius,
                      const ShadowSettings& shadowSettings);
    void setupLayerBlending(bool premultipliedAlpha, bool opaque, bool disableTexture,
                            const half4& color, float cornerRadius);
    void setupLayerTexturing(const Texture& texture);
+98 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 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.
 */

#include <renderengine/Mesh.h>

#include <math/vec4.h>

#include <ui/Rect.h>
#include <ui/Transform.h>

#include "GLShadowVertexGenerator.h"

namespace android {
namespace renderengine {
namespace gl {

GLShadowVertexGenerator::GLShadowVertexGenerator(const FloatRect& casterRect,
                                                 float casterCornerRadius, float casterZ,
                                                 bool casterIsTranslucent, const vec4& ambientColor,
                                                 const vec4& spotColor, const vec3& lightPosition,
                                                 float lightRadius) {
    mDrawAmbientShadow = ambientColor.a > 0.f;
    mDrawSpotShadow = spotColor.a > 0.f;

    // Generate geometries and find number of vertices to generate
    if (mDrawAmbientShadow) {
        mAmbientShadowGeometry = getAmbientShadowGeometry(casterRect, casterCornerRadius, casterZ,
                                                          casterIsTranslucent, ambientColor);
        mAmbientShadowVertexCount = getVertexCountForGeometry(*mAmbientShadowGeometry.get());
        mAmbientShadowIndexCount = getIndexCountForGeometry(*mAmbientShadowGeometry.get());
    } else {
        mAmbientShadowVertexCount = 0;
        mAmbientShadowIndexCount = 0;
    }

    if (mDrawSpotShadow) {
        mSpotShadowGeometry =
                getSpotShadowGeometry(casterRect, casterCornerRadius, casterZ, casterIsTranslucent,
                                      spotColor, lightPosition, lightRadius);
        mSpotShadowVertexCount = getVertexCountForGeometry(*mSpotShadowGeometry.get());
        mSpotShadowIndexCount = getIndexCountForGeometry(*mSpotShadowGeometry.get());
    } else {
        mSpotShadowVertexCount = 0;
        mSpotShadowIndexCount = 0;
    }
}

size_t GLShadowVertexGenerator::getVertexCount() const {
    return mAmbientShadowVertexCount + mSpotShadowVertexCount;
}

size_t GLShadowVertexGenerator::getIndexCount() const {
    return mAmbientShadowIndexCount + mSpotShadowIndexCount;
}

void GLShadowVertexGenerator::fillVertices(Mesh::VertexArray<vec2>& position,
                                           Mesh::VertexArray<vec4>& color,
                                           Mesh::VertexArray<vec3>& params) const {
    if (mDrawAmbientShadow) {
        fillVerticesForGeometry(*mAmbientShadowGeometry.get(), mAmbientShadowVertexCount, position,
                                color, params);
    }
    if (mDrawSpotShadow) {
        fillVerticesForGeometry(*mSpotShadowGeometry.get(), mSpotShadowVertexCount,
                                Mesh::VertexArray<vec2>(position, mAmbientShadowVertexCount),
                                Mesh::VertexArray<vec4>(color, mAmbientShadowVertexCount),
                                Mesh::VertexArray<vec3>(params, mAmbientShadowVertexCount));
    }
}

void GLShadowVertexGenerator::fillIndices(uint16_t* indices) const {
    if (mDrawAmbientShadow) {
        fillIndicesForGeometry(*mAmbientShadowGeometry.get(), mAmbientShadowIndexCount,
                               0 /* starting vertex offset */, indices);
    }
    if (mDrawSpotShadow) {
        fillIndicesForGeometry(*mSpotShadowGeometry.get(), mSpotShadowIndexCount,
                               mAmbientShadowVertexCount /* starting vertex offset */,
                               &(indices[mAmbientShadowIndexCount]));
    }
}

} // namespace gl
} // namespace renderengine
} // namespace android
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 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 <ui/Rect.h>

#include "GLSkiaShadowPort.h"

namespace android {
namespace renderengine {

class Mesh;

namespace gl {

/**
 * Generates gl attributes required to draw shadow spot and/or ambient shadows.
 *
 * Each shadow can support different colors. This class generates three vertex attributes for
 * each shadow, its position, color and shadow params(offset and distance). These can be sent
 * using a single glDrawElements call.
 */
class GLShadowVertexGenerator {
public:
    GLShadowVertexGenerator(const FloatRect& casterRect, float casterCornerRadius, float casterZ,
                            bool casterIsTranslucent, const vec4& ambientColor,
                            const vec4& spotColor, const vec3& lightPosition, float lightRadius);
    ~GLShadowVertexGenerator() = default;

    size_t getVertexCount() const;
    size_t getIndexCount() const;
    void fillVertices(Mesh::VertexArray<vec2>& position, Mesh::VertexArray<vec4>& color,
                      Mesh::VertexArray<vec3>& params) const;
    void fillIndices(uint16_t* indices) const;

private:
    bool mDrawAmbientShadow;
    std::unique_ptr<Geometry> mAmbientShadowGeometry;
    int mAmbientShadowVertexCount = 0;
    int mAmbientShadowIndexCount = 0;

    bool mDrawSpotShadow;
    std::unique_ptr<Geometry> mSpotShadowGeometry;
    int mSpotShadowVertexCount = 0;
    int mSpotShadowIndexCount = 0;
};

} // namespace gl
} // namespace renderengine
} // namespace android
Loading