Loading graphics/java/android/graphics/RenderEffect.java 0 → 100644 +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(); } graphics/java/android/graphics/RenderNode.java +20 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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); Loading libs/hwui/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading libs/hwui/RenderProperties.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -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))); Loading @@ -63,6 +69,7 @@ LayerProperties& LayerProperties::operator=(const LayerProperties& other) { setAlpha(other.alpha()); setXferMode(other.xferMode()); setColorFilter(other.getColorFilter()); setImageFilter(other.getImageFilter()); return *this; } Loading libs/hwui/RenderProperties.h +7 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "utils/PaintUtils.h" #include <SkBlendMode.h> #include <SkImageFilter.h> #include <SkCamera.h> #include <SkColor.h> #include <SkMatrix.h> Loading Loading @@ -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); Loading @@ -118,6 +123,7 @@ private: uint8_t mAlpha; SkBlendMode mMode; sk_sp<SkColorFilter> mColorFilter; sk_sp<SkImageFilter> mImageFilter; }; /* Loading Loading @@ -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 Loading
graphics/java/android/graphics/RenderEffect.java 0 → 100644 +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(); }
graphics/java/android/graphics/RenderNode.java +20 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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); Loading
libs/hwui/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading
libs/hwui/RenderProperties.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -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))); Loading @@ -63,6 +69,7 @@ LayerProperties& LayerProperties::operator=(const LayerProperties& other) { setAlpha(other.alpha()); setXferMode(other.xferMode()); setColorFilter(other.getColorFilter()); setImageFilter(other.getImageFilter()); return *this; } Loading
libs/hwui/RenderProperties.h +7 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "utils/PaintUtils.h" #include <SkBlendMode.h> #include <SkImageFilter.h> #include <SkCamera.h> #include <SkColor.h> #include <SkMatrix.h> Loading Loading @@ -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); Loading @@ -118,6 +123,7 @@ private: uint8_t mAlpha; SkBlendMode mMode; sk_sp<SkColorFilter> mColorFilter; sk_sp<SkImageFilter> mImageFilter; }; /* Loading Loading @@ -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