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

Commit 921b9392 authored by Nader Jawad's avatar Nader Jawad Committed by Android (Google) Code Review
Browse files

Merge "Added RenderEffect property on RenderNode"

parents 73d2514a 390d6e85
Loading
Loading
Loading
Loading
+145 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.
 */

package android.graphics;

import android.annotation.NonNull;
import android.graphics.Shader.TileMode;

import libcore.util.NativeAllocationRegistry;

/**
 * Intermediate rendering step used to render drawing commands with a corresponding
 * visual effect
 *
 * @hide
 */
public final class RenderEffect {

    private static class RenderEffectHolder {
        public static final NativeAllocationRegistry RENDER_EFFECT_REGISTRY =
                NativeAllocationRegistry.createMalloced(
                        RenderEffect.class.getClassLoader(), nativeGetFinalizer());
    }

    /**
     * Create a {@link RenderEffect} instance that will offset the drawing content
     * by the provided x and y offset.
     * @param offsetX offset along the x axis in pixels
     * @param offsetY offset along the y axis in pixels
     */
    @NonNull
    public static RenderEffect createOffsetEffect(float offsetX, float offsetY) {
        return new RenderEffect(nativeCreateOffsetEffect(offsetX, offsetY, 0));
    }

    /**
     * Create a {@link RenderEffect} instance with the provided x and y offset
     * @param offsetX offset along the x axis in pixels
     * @param offsetY offset along the y axis in pixels
     * @param input target RenderEffect used to render in the offset coordinates.
     */
    @NonNull
    public static RenderEffect createOffsetEffect(
            float offsetX,
            float offsetY,
            @NonNull RenderEffect input
    ) {
        return new RenderEffect(nativeCreateOffsetEffect(
                    offsetX,
                    offsetY,
                    input.getNativeInstance()
                )
        );
    }

    /**
     * Create a {@link RenderEffect} that blurs the contents of the optional input RenderEffect
     * with the specified radius along the x and y axis. If no input RenderEffect is provided
     * then all drawing commands issued with a {@link android.graphics.RenderNode} that this
     * RenderEffect is installed in will be blurred
     * @param radiusX Radius of blur along the X axis
     * @param radiusY Radius of blur along the Y axis
     * @param inputEffect Input RenderEffect that provides the content to be blurred, can be null
     *                    to indicate that the drawing commands on the RenderNode are to be
     *                    blurred instead of the input RenderEffect
     * @param edgeTreatment Policy for how to blur content near edges of the blur kernel
     */
    @NonNull
    public static RenderEffect createBlurEffect(
            float radiusX,
            float radiusY,
            @NonNull RenderEffect inputEffect,
            @NonNull TileMode edgeTreatment
    ) {
        long nativeInputEffect = inputEffect != null ? inputEffect.mNativeRenderEffect : 0;
        return new RenderEffect(
                nativeCreateBlurEffect(
                        radiusX,
                        radiusY,
                        nativeInputEffect,
                        edgeTreatment.nativeInt
                )
            );
    }

    /**
     * Create a {@link RenderEffect} that blurs the contents of the
     * {@link android.graphics.RenderNode} that this RenderEffect is installed on with the
     * specified radius along hte x and y axis.
     * @param radiusX Radius of blur along the X axis
     * @param radiusY Radius of blur along the Y axis
     * @param edgeTreatment Policy for how to blur content near edges of the blur kernel
     */
    @NonNull
    public static RenderEffect createBlurEffect(
            float radiusX,
            float radiusY,
            @NonNull TileMode edgeTreatment
    ) {
        return new RenderEffect(
                nativeCreateBlurEffect(
                        radiusX,
                        radiusY,
                        0,
                        edgeTreatment.nativeInt
                )
        );
    }

    private final long mNativeRenderEffect;

    /* only constructed from static factory methods */
    private RenderEffect(long nativeRenderEffect) {
        mNativeRenderEffect = nativeRenderEffect;
        RenderEffectHolder.RENDER_EFFECT_REGISTRY.registerNativeAllocation(
                this, mNativeRenderEffect);
    }

    /**
     * Obtain the pointer to the underlying RenderEffect to be configured
     * on a RenderNode object via {@link RenderNode#setRenderEffect(RenderEffect)}
     */
    /* package */ long getNativeInstance() {
        return mNativeRenderEffect;
    }

    private static native long nativeCreateOffsetEffect(
            float offsetX, float offsetY, long nativeInput);
    private static native long nativeCreateBlurEffect(
            float radiusX, float radiusY, long nativeInput, int edgeTreatment);
    private static native long nativeGetFinalizer();
}
+20 −0
Original line number Diff line number Diff line
@@ -849,6 +849,23 @@ public final class RenderNode {
        return nSetAlpha(mNativeRenderNode, alpha);
    }

    /**
     * Configure the {@link android.graphics.RenderEffect} to apply to this RenderNode. This
     * will apply a visual effect to the end result of the contents of this RenderNode before
     * it is drawn into the destination. For example if
     * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, Shader.TileMode)}
     * is provided, the contents will be drawn in a separate layer, then this layer will
     * be blurred when this RenderNode is drawn into the destination.
     * @param renderEffect to be applied to the RenderNode. Passing null clears all previously
     *          configured RenderEffects
     *
     * @hide
     */
    public void setRenderEffect(@Nullable RenderEffect renderEffect) {
        nSetRenderEffect(mNativeRenderNode,
                renderEffect != null ? renderEffect.getNativeInstance() : 0);
    }

    /**
     * Returns the translucency level of this display list.
     *
@@ -1654,6 +1671,9 @@ public final class RenderNode {
    @CriticalNative
    private static native boolean nSetAlpha(long renderNode, float alpha);

    @CriticalNative
    private static native void nSetRenderEffect(long renderNode, long renderEffect);

    @CriticalNative
    private static native boolean nSetHasOverlappingRendering(long renderNode,
            boolean hasOverlappingRendering);
+1 −0
Original line number Diff line number Diff line
@@ -327,6 +327,7 @@ cc_defaults {
        "jni/PathMeasure.cpp",
        "jni/Picture.cpp",
        "jni/Shader.cpp",
        "jni/RenderEffect.cpp",
        "jni/Typeface.cpp",
        "jni/Utils.cpp",
        "jni/YuvToJpegEncoder.cpp",
+7 −0
Original line number Diff line number Diff line
@@ -49,6 +49,12 @@ bool LayerProperties::setColorFilter(SkColorFilter* filter) {
    return true;
}

bool LayerProperties::setImageFilter(SkImageFilter* imageFilter) {
    if(mImageFilter.get() == imageFilter) return false;
    mImageFilter = sk_ref_sp(imageFilter);
    return true;
}

bool LayerProperties::setFromPaint(const SkPaint* paint) {
    bool changed = false;
    changed |= setAlpha(static_cast<uint8_t>(PaintUtils::getAlphaDirect(paint)));
@@ -63,6 +69,7 @@ LayerProperties& LayerProperties::operator=(const LayerProperties& other) {
    setAlpha(other.alpha());
    setXferMode(other.xferMode());
    setColorFilter(other.getColorFilter());
    setImageFilter(other.getImageFilter());
    return *this;
}

+7 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "utils/PaintUtils.h"

#include <SkBlendMode.h>
#include <SkImageFilter.h>
#include <SkCamera.h>
#include <SkColor.h>
#include <SkMatrix.h>
@@ -93,6 +94,10 @@ public:

    SkColorFilter* getColorFilter() const { return mColorFilter.get(); }

    bool setImageFilter(SkImageFilter* imageFilter);

    SkImageFilter* getImageFilter() const { return mImageFilter.get(); }

    // Sets alpha, xfermode, and colorfilter from an SkPaint
    // paint may be NULL, in which case defaults will be set
    bool setFromPaint(const SkPaint* paint);
@@ -118,6 +123,7 @@ private:
    uint8_t mAlpha;
    SkBlendMode mMode;
    sk_sp<SkColorFilter> mColorFilter;
    sk_sp<SkImageFilter> mImageFilter;
};

/*
@@ -541,6 +547,7 @@ public:
    bool promotedToLayer() const {
        return mLayerProperties.mType == LayerType::None && fitsOnLayer() &&
               (mComputedFields.mNeedLayerForFunctors ||
                mLayerProperties.mImageFilter != nullptr ||
                (!MathUtils::isZero(mPrimitiveFields.mAlpha) && mPrimitiveFields.mAlpha < 1 &&
                 mPrimitiveFields.mHasOverlappingRendering));
    }
Loading