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

Commit 692226fe authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13928948 from 69778137 to 25Q4-release

Change-Id: Ie3205d536f552984f8767e25016ff5589ee31fc6
parents eb5eac3a 69778137
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -238,7 +238,7 @@ static void joinRpcServer(sp<RpcServer>&& thiz) {

void RpcServer::start() {
    RpcMutexLockGuard _l(mLock);
    LOG_ALWAYS_FATAL_IF(mJoinThread.get(), "Already started!");
    LOG_ALWAYS_FATAL_IF(mJoinThread.get() != nullptr, "Already started!");
    mJoinThread =
            std::make_unique<RpcMaybeThread>(&joinRpcServer, sp<RpcServer>::fromExisting(this));
    rpcJoinIfSingleThreaded(*mJoinThread);
+1 −1
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ public:
                    .num_iov = static_cast<uint32_t>(niovs),
                    .iov = iovs,
                    .num_handles = mMessageInfo.num_handles,
                    .handles = haveHandles ? msgHandles : 0,
                    .handles = haveHandles ? msgHandles : nullptr,
            };
            ssize_t rc = read_msg(mSocket.fd.get(), mMessageInfo.id, mMessageOffset, &msg);
            if (rc < 0) {
+25 −13
Original line number Diff line number Diff line
@@ -112,25 +112,37 @@ bool validateTopologyGraph(
                           << adjacentDisplay.displayId << " for source " << sourceDisplay;
                return false;
            }
            const auto reverseEdgeIt =
                    std::find_if(adjacentGraphIt->second.adjacentDisplays.begin(),
                                 adjacentGraphIt->second.adjacentDisplays.end(),
                                 [sourceDisplay](const DisplayTopologyAdjacentDisplay&
                                                         reverseAdjacentDisplay) {
                                     return sourceDisplay == reverseAdjacentDisplay.displayId;
                                 });
            if (reverseEdgeIt == adjacentGraphIt->second.adjacentDisplays.end()) {
            std::vector<DisplayTopologyAdjacentDisplay> reverseEdges;
            for (const auto& edge : adjacentGraphIt->second.adjacentDisplays) {
                if (edge.displayId == sourceDisplay) {
                    reverseEdges.push_back(edge);
                }
            }
            if (reverseEdges.empty()) {
                LOG(ERROR) << "Missing reverse edge in topology graph for: " << sourceDisplay
                           << " -> " << adjacentDisplay.displayId;
                return false;
            }
            DisplayTopologyPosition expectedPosition =

            DisplayTopologyPosition expectedOppositePosition =
                    getOppositePosition(adjacentDisplay.position);
            if (reverseEdgeIt->position != expectedPosition) {
                LOG(ERROR) << "Unexpected reverse edge for: " << sourceDisplay << " -> "
            const auto reverseEdgeIt =
                    std::find_if(reverseEdges.begin(), reverseEdges.end(),
                                 [expectedOppositePosition](
                                         const DisplayTopologyAdjacentDisplay& edge) {
                                     return expectedOppositePosition == edge.position;
                                 });
            if (reverseEdgeIt == reverseEdges.end()) {
                std::string positions;
                for (const auto& edge : reverseEdges) {
                    positions += ftl::enum_string(edge.position);
                    positions += " ";
                }
                LOG(ERROR) << "Reverse edges for: " << sourceDisplay << " -> "
                           << adjacentDisplay.displayId
                           << " expected position: " << ftl::enum_string(expectedPosition)
                           << " actual " << ftl::enum_string(reverseEdgeIt->position);
                           << " found, but none had the expected position: "
                           << ftl::enum_string(expectedOppositePosition) << " actual [" << positions
                           << "]";
                return false;
            }
            if (reverseEdgeIt->offsetDp != -adjacentDisplay.offsetDp) {
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ filegroup {
        "skia/GLExtensions.cpp",
        "skia/ShaderCache.cpp",
        "skia/SkiaRenderEngine.cpp",
        "skia/BoxShadowUtils.cpp",
        "skia/SkiaGLRenderEngine.cpp",
        "skia/SkiaVkRenderEngine.cpp",
        "skia/VulkanInterface.cpp",
+182 −0
Original line number Diff line number Diff line

#include "BoxShadowUtils.h"

#include <common/trace.h>
#include <include/core/SkBlurTypes.h>
#include <include/core/SkCanvas.h>
#include <include/core/SkColor.h>
#include <include/core/SkColorFilter.h>
#include <include/core/SkImage.h>
#include <include/core/SkImageInfo.h>
#include <include/core/SkMaskFilter.h>
#include <include/core/SkPaint.h>
#include <include/core/SkRRect.h>
#include <include/core/SkRect.h>
#include <include/core/SkShader.h>
#include <include/core/SkSurface.h>
#include <include/core/SkVertices.h>
#include <ui/BlurRegion.h>

namespace android::renderengine::skia {

namespace {

const float kSigmaFactor = 3.0;
const float kSin45Deg = 0.7071067811f;

sk_sp<SkImage> makeBlurredRRect(SkiaGpuContext* context, float sigma, float cornerRadius) {
    float kernelRadius = kSigmaFactor * sigma;
    float size = kernelRadius + cornerRadius + cornerRadius + kernelRadius;

    SkRect rrectBounds = SkRect::MakeXYWH(kernelRadius, kernelRadius, size - 2 * kernelRadius,
                                          size - 2 * kernelRadius);
    SkRRect rrectToBlur = SkRRect::MakeRectXY(rrectBounds, cornerRadius, cornerRadius);

    SkImageInfo info = SkImageInfo::Make(size, size, kRGBA_8888_SkColorType, kPremul_SkAlphaType);

    sk_sp<SkSurface> surface = context->createRenderTarget(info);
    LOG_ALWAYS_FATAL_IF(surface == nullptr,
                        "Failed to create render target for box shadow texture!");

    SkCanvas* canvas = surface->getCanvas();
    canvas->clear(SK_ColorTRANSPARENT);

    SkPaint blurPaint;
    blurPaint.setAntiAlias(true);
    blurPaint.setColor(SK_ColorWHITE);
    blurPaint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma));

    canvas->drawRRect(rrectToBlur, blurPaint);
    return surface->makeImageSnapshot()->withDefaultMipmaps();
}

void drawNineSlice(SkCanvas* canvas, const sk_sp<SkShader> shader, const SkRect& dest,
                   const SkColor& color, float cornerScale) {
    int kVertexCount = 16;
    // 8 quads * 6 indices per quad
    int kImageIndexCount = 8 * 6;

    SkVertices::Builder builder(SkVertices::kTriangles_VertexMode, kVertexCount, kImageIndexCount,
                                SkVertices::kHasTexCoords_BuilderFlag);

    SkImage* image = shader->isAImage(nullptr, (SkTileMode*)nullptr);
    float s = static_cast<float>(image->width());

    // Corner source size.
    float c = s / 2.0f;

    // Clamp corner dest size to prevent corners from overlapping.
    float dstCornerSize = c * cornerScale;
    float xc = std::min(dstCornerSize, 0.5f * (dest.fRight - dest.fLeft));
    float yc = std::min(dstCornerSize, 0.5f * (dest.fBottom - dest.fTop));

    // Dest coordinates
    float dx[] = {dest.fLeft, dest.fLeft + xc, dest.fRight - xc, dest.fRight};
    float dy[] = {dest.fTop, dest.fTop + yc, dest.fBottom - yc, dest.fBottom};

    // Source coordinates adjusted to take into account dest center tile expansion.
    float sx[] = {0.0f, c, c, s};
    float sy[] = {0.0f, c, c, s};

    SkPoint* posPtr = builder.positions();
    SkPoint* texPtr = builder.texCoords();

    // Populate the 16 vertices
    for (int j = 0; j < 4; ++j) {
        for (int i = 0; i < 4; ++i) {
            int v_idx = j * 4 + i;
            posPtr[v_idx] = {dx[i], dy[j]};
            texPtr[v_idx] = {sx[i], sy[j]};
        }
    }

    uint16_t* indicesPtr = builder.indices();
    int indicesOffset = 0;

    // Add indices for the 8 image patches
    for (int j = 0; j < 3; ++j) {
        for (int i = 0; i < 3; ++i) {
            if (i == 1 && j == 1) continue; // skip center

            uint16_t v00 = j * 4 + i;
            uint16_t v01 = j * 4 + (i + 1);
            uint16_t v10 = (j + 1) * 4 + i;
            uint16_t v11 = (j + 1) * 4 + (i + 1);

            indicesPtr[indicesOffset + 0] = v00;
            indicesPtr[indicesOffset + 1] = v01;
            indicesPtr[indicesOffset + 2] = v10;

            indicesPtr[indicesOffset + 3] = v01;
            indicesPtr[indicesOffset + 4] = v11;
            indicesPtr[indicesOffset + 5] = v10;
            indicesOffset += 6;
        }
    }

    sk_sp<SkVertices> skirtVerts = builder.detach();

    SkPaint skirtPaint;
    skirtPaint.setColorFilter(SkColorFilters::Blend(color, SkBlendMode::kSrcIn));
    skirtPaint.setShader(shader);
    skirtPaint.setAntiAlias(false);
    canvas->drawVertices(skirtVerts, /*ignored*/ SkBlendMode::kSrcOver, skirtPaint);
}

} // namespace

void BoxShadowUtils::init(SkiaGpuContext* context) {
    int memorySize = 0;
    for (int i = 0; i < kSupportedBlurRadius.size(); i++) {
        float blurRadius = kSupportedBlurRadius[i];
        float sigma = convertBlurUserRadiusToSigma(blurRadius);
        sk_sp<SkImage> image = makeBlurredRRect(context, sigma, kDefaultCornerRadius);
        SkSamplingOptions sampling(SkFilterMode::kLinear, SkMipmapMode::kLinear);
        mBlurImages[i] = image->makeShader(sampling);

        memorySize += image->width() * image->height() * 4;
    }

    ALOGI("[BoxShadowUtils] Shadow memory size: %d MB", memorySize / (1024 * 1024));
}

void BoxShadowUtils::cleanup() {
    for (int i = 0; i < kSupportedBlurRadius.size(); i++) {
        mBlurImages[i] = nullptr;
    }
}

void BoxShadowUtils::drawBoxShadows(SkCanvas* canvas, const SkRect& rect, float cornerRadius,
                                    const android::gui::BoxShadowSettings& settings) {
    for (const gui::BoxShadowSettings::BoxShadowParams& box : settings.boxShadows) {
        SkRect boxRect = rect;
        boxRect.outset(box.spreadRadius, box.spreadRadius);
        boxRect.offset(box.offsetX, box.offsetY);

        float desiredCornerRadius = std::max(4.0f, cornerRadius + box.spreadRadius);
        float cornerScale = desiredCornerRadius / kDefaultCornerRadius;

        float optimalBlurRadius = kDefaultCornerRadius * (box.blurRadius / desiredCornerRadius);

        int blurRadiusIndex = 0;
        float minError = std::abs(optimalBlurRadius - kSupportedBlurRadius[0]);
        for (int i = 1; i < kSupportedBlurRadius.size(); i++) {
            float err = std::abs(optimalBlurRadius - kSupportedBlurRadius[i]);
            if (err <= minError) {
                blurRadiusIndex = i;
                minError = err;
            }
        }

        float effectiveBlurRadius = kSupportedBlurRadius[blurRadiusIndex];
        float sigma = convertBlurUserRadiusToSigma(effectiveBlurRadius);

        float kernelRadius = sigma * kSigmaFactor * cornerScale;
        boxRect.outset(kernelRadius, kernelRadius);

        sk_sp<SkShader> shader = mBlurImages[blurRadiusIndex];
        drawNineSlice(canvas, shader, boxRect, box.color, cornerScale);
    }
}

} // namespace android::renderengine::skia
 No newline at end of file
Loading