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

Commit deaecdc7 authored by Kevin Lubick's avatar Kevin Lubick
Browse files

Inline code to turn an SkRuntimeBuilder -> SkImage

This appears to be the only use of SkRuntimeEffect::makeImage

This also removes a very small amount of code size and very slightly
reduces parse time by removing whitespace from the shader code.

Change-Id: I51b1b11f1cb49717ab5c069f9f5cb4e66c0b93ff
parent 3d367380
Loading
Loading
Loading
Loading
+56 −18
Original line number Original line Diff line number Diff line
@@ -17,14 +17,20 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#define ATRACE_TAG ATRACE_TAG_GRAPHICS


#include "KawaseBlurFilter.h"
#include "KawaseBlurFilter.h"
#include <SkAlphaType.h>
#include <SkBlendMode.h>
#include <SkCanvas.h>
#include <SkCanvas.h>
#include <SkImageInfo.h>
#include <SkPaint.h>
#include <SkPaint.h>
#include <SkRRect.h>
#include <SkRRect.h>
#include <SkRuntimeEffect.h>
#include <SkRuntimeEffect.h>
#include <SkShader.h>
#include <SkSize.h>
#include <SkSize.h>
#include <SkString.h>
#include <SkString.h>
#include <SkSurface.h>
#include <SkSurface.h>
#include <SkTileMode.h>
#include <SkTileMode.h>
#include <include/gpu/GpuTypes.h>
#include <include/gpu/ganesh/SkSurfaceGanesh.h>
#include <log/log.h>
#include <log/log.h>
#include <utils/Trace.h>
#include <utils/Trace.h>


@@ -33,19 +39,18 @@ namespace renderengine {
namespace skia {
namespace skia {


KawaseBlurFilter::KawaseBlurFilter(): BlurFilter() {
KawaseBlurFilter::KawaseBlurFilter(): BlurFilter() {
    SkString blurString(R"(
    SkString blurString(
        uniform shader child;
        "uniform shader child;"
        uniform float in_blurOffset;
        "uniform float in_blurOffset;"


        half4 main(float2 xy) {
        "half4 main(float2 xy) {"
            half4 c = child.eval(xy);
            "half4 c = child.eval(xy);"
            c += child.eval(xy + float2(+in_blurOffset, +in_blurOffset));
            "c += child.eval(xy + float2(+in_blurOffset, +in_blurOffset));"
            c += child.eval(xy + float2(+in_blurOffset, -in_blurOffset));
            "c += child.eval(xy + float2(+in_blurOffset, -in_blurOffset));"
            c += child.eval(xy + float2(-in_blurOffset, -in_blurOffset));
            "c += child.eval(xy + float2(-in_blurOffset, -in_blurOffset));"
            c += child.eval(xy + float2(-in_blurOffset, +in_blurOffset));
            "c += child.eval(xy + float2(-in_blurOffset, +in_blurOffset));"
            return half4(c.rgb * 0.2, 1.0);
            "return half4(c.rgb * 0.2, 1.0);"
        }
        "}");
    )");


    auto [blurEffect, error] = SkRuntimeEffect::MakeForShader(blurString);
    auto [blurEffect, error] = SkRuntimeEffect::MakeForShader(blurString);
    if (!blurEffect) {
    if (!blurEffect) {
@@ -54,10 +59,43 @@ KawaseBlurFilter::KawaseBlurFilter(): BlurFilter() {
    mBlurEffect = std::move(blurEffect);
    mBlurEffect = std::move(blurEffect);
}
}


sk_sp<SkImage> KawaseBlurFilter::generate(GrRecordingContext* context, const uint32_t blurRadius,
// Draws the given runtime shader on a GPU (Ganesh) surface and returns the result as an
                                          const sk_sp<SkImage> input, const SkRect& blurRect)
// SkImage.
    const {
static sk_sp<SkImage> makeImage(GrRecordingContext* context, SkRuntimeShaderBuilder* builder,
                                const SkImageInfo& resultInfo) {
    if (resultInfo.alphaType() == kUnpremul_SkAlphaType ||
        resultInfo.alphaType() == kUnknown_SkAlphaType) {
        return nullptr;
    }
    constexpr int kSampleCount = 1;
    constexpr bool kMipmapped = false;

    sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(context,
                                                        skgpu::Budgeted::kYes,
                                                        resultInfo,
                                                        kSampleCount,
                                                        kTopLeft_GrSurfaceOrigin,
                                                        nullptr,
                                                        kMipmapped);
    if (!surface) {
        return nullptr;
    }
    sk_sp<SkShader> shader = builder->makeShader(nullptr);
    if (!shader) {
        return nullptr;
    }
    SkPaint paint;
    paint.setShader(std::move(shader));
    paint.setBlendMode(SkBlendMode::kSrc);
    surface->getCanvas()->drawPaint(paint);
    return surface->makeImageSnapshot();
}


sk_sp<SkImage> KawaseBlurFilter::generate(GrRecordingContext* context,
                                          const uint32_t blurRadius,
                                          const sk_sp<SkImage> input,
                                          const SkRect& blurRect) const {
    LOG_ALWAYS_FATAL_IF(context == nullptr, "%s: Needs GPU context", __func__);
    LOG_ALWAYS_FATAL_IF(input == nullptr, "%s: Invalid input image", __func__);
    LOG_ALWAYS_FATAL_IF(input == nullptr, "%s: Invalid input image", __func__);
    // Kawase is an approximation of Gaussian, but it behaves differently from it.
    // Kawase is an approximation of Gaussian, but it behaves differently from it.
    // A radius transformation is required for approximating them, and also to introduce
    // A radius transformation is required for approximating them, and also to introduce
@@ -83,7 +121,7 @@ sk_sp<SkImage> KawaseBlurFilter::generate(GrRecordingContext* context, const uin
            input->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, linear, blurMatrix);
            input->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, linear, blurMatrix);
    blurBuilder.uniform("in_blurOffset") = radiusByPasses * kInputScale;
    blurBuilder.uniform("in_blurOffset") = radiusByPasses * kInputScale;


    sk_sp<SkImage> tmpBlur(blurBuilder.makeImage(context, nullptr, scaledInfo, false));
    sk_sp<SkImage> tmpBlur = makeImage(context, &blurBuilder, scaledInfo);


    // And now we'll build our chain of scaled blur stages
    // And now we'll build our chain of scaled blur stages
    for (auto i = 1; i < numberOfPasses; i++) {
    for (auto i = 1; i < numberOfPasses; i++) {
@@ -91,7 +129,7 @@ sk_sp<SkImage> KawaseBlurFilter::generate(GrRecordingContext* context, const uin
        blurBuilder.child("child") =
        blurBuilder.child("child") =
                tmpBlur->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, linear);
                tmpBlur->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, linear);
        blurBuilder.uniform("in_blurOffset") = (float) i * radiusByPasses * kInputScale;
        blurBuilder.uniform("in_blurOffset") = (float) i * radiusByPasses * kInputScale;
        tmpBlur = blurBuilder.makeImage(context, nullptr, scaledInfo, false);
        tmpBlur = makeImage(context, &blurBuilder, scaledInfo);
    }
    }


    return tmpBlur;
    return tmpBlur;