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

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

Merge "Update ColorFilter API to be backed by mutable native objects"

parents eb668b93 f0ea9e19
Loading
Loading
Loading
Loading
+1 −12
Original line number Original line Diff line number Diff line
@@ -41,21 +41,11 @@ public class ColorFilter {
     * Current native SkColorFilter instance.
     * Current native SkColorFilter instance.
     */
     */
    private long mNativeInstance;
    private long mNativeInstance;
    // Runnable to do immediate destruction
    private Runnable mCleaner;


    long createNativeInstance() {
    long createNativeInstance() {
        return 0;
        return 0;
    }
    }


    synchronized final void discardNativeInstance() {
        if (mNativeInstance != 0) {
            mCleaner.run();
            mCleaner = null;
            mNativeInstance = 0;
        }
    }

    /** @hide */
    /** @hide */
    public synchronized final long getNativeInstance() {
    public synchronized final long getNativeInstance() {
        if (mNativeInstance == 0) {
        if (mNativeInstance == 0) {
@@ -65,8 +55,7 @@ public class ColorFilter {
                // Note: we must check for null here, since it's possible for createNativeInstance()
                // Note: we must check for null here, since it's possible for createNativeInstance()
                // to return nullptr if the native SkColorFilter would be a no-op at draw time.
                // to return nullptr if the native SkColorFilter would be a no-op at draw time.
                // See native implementations of subclass create methods for more info.
                // See native implementations of subclass create methods for more info.
                mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
                NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeInstance);
                        this, mNativeInstance);
            }
            }
        }
        }
        return mNativeInstance;
        return mNativeInstance;
+4 −2
Original line number Original line Diff line number Diff line
@@ -81,12 +81,12 @@ public class ColorMatrixColorFilter extends ColorFilter {
     */
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public void setColorMatrix(@Nullable ColorMatrix matrix) {
    public void setColorMatrix(@Nullable ColorMatrix matrix) {
        discardNativeInstance();
        if (matrix == null) {
        if (matrix == null) {
            mMatrix.reset();
            mMatrix.reset();
        } else {
        } else {
            mMatrix.set(matrix);
            mMatrix.set(matrix);
        }
        }
        nativeSetColorMatrix(getNativeInstance(), mMatrix.getArray());
    }
    }


    /**
    /**
@@ -111,7 +111,6 @@ public class ColorMatrixColorFilter extends ColorFilter {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public void setColorMatrixArray(@Nullable float[] array) {
    public void setColorMatrixArray(@Nullable float[] array) {
        // called '...Array' so that passing null isn't ambiguous
        // called '...Array' so that passing null isn't ambiguous
        discardNativeInstance();
        if (array == null) {
        if (array == null) {
            mMatrix.reset();
            mMatrix.reset();
        } else {
        } else {
@@ -120,6 +119,7 @@ public class ColorMatrixColorFilter extends ColorFilter {
            }
            }
            mMatrix.set(array);
            mMatrix.set(array);
        }
        }
        nativeSetColorMatrix(getNativeInstance(), mMatrix.getArray());
    }
    }


    @Override
    @Override
@@ -128,4 +128,6 @@ public class ColorMatrixColorFilter extends ColorFilter {
    }
    }


    private static native long nativeColorMatrixFilter(float[] array);
    private static native long nativeColorMatrixFilter(float[] array);

    private static native void nativeSetColorMatrix(long colorMatrixColorFilter, float[] array);
}
}
+6 −2
Original line number Original line Diff line number Diff line
@@ -78,7 +78,7 @@ public class LightingColorFilter extends ColorFilter {
    public void setColorMultiply(@ColorInt int mul) {
    public void setColorMultiply(@ColorInt int mul) {
        if (mMul != mul) {
        if (mMul != mul) {
            mMul = mul;
            mMul = mul;
            discardNativeInstance();
            native_SetLightingFilterMul(getNativeInstance(), mul);
        }
        }
    }
    }


@@ -104,7 +104,7 @@ public class LightingColorFilter extends ColorFilter {
    public void setColorAdd(@ColorInt int add) {
    public void setColorAdd(@ColorInt int add) {
        if (mAdd != add) {
        if (mAdd != add) {
            mAdd = add;
            mAdd = add;
            discardNativeInstance();
            native_SetLightingFilterAdd(getNativeInstance(), add);
        }
        }
    }
    }


@@ -114,4 +114,8 @@ public class LightingColorFilter extends ColorFilter {
    }
    }


    private static native long native_CreateLightingFilter(int mul, int add);
    private static native long native_CreateLightingFilter(int mul, int add);

    private static native void native_SetLightingFilterAdd(long lightingFilter, int add);

    private static native void native_SetLightingFilterMul(long lightingFilter, int mul);
}
}
+94 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.
 */

#ifndef COLORFILTER_H_
#define COLORFILTER_H_

#include <stdint.h>

#include <memory>

#include "GraphicsJNI.h"
#include "SkColorFilter.h"
#include "SkiaWrapper.h"

namespace android {
namespace uirenderer {

class ColorFilter : public SkiaWrapper<SkColorFilter> {
public:
    static ColorFilter* fromJava(jlong handle) { return reinterpret_cast<ColorFilter*>(handle); }

protected:
    ColorFilter() = default;
};

class BlendModeColorFilter : public ColorFilter {
public:
    BlendModeColorFilter(SkColor color, SkBlendMode mode) : mColor(color), mMode(mode) {}

private:
    sk_sp<SkColorFilter> createInstance() override { return SkColorFilters::Blend(mColor, mMode); }

private:
    const SkColor mColor;
    const SkBlendMode mMode;
};

class LightingFilter : public ColorFilter {
public:
    LightingFilter(SkColor mul, SkColor add) : mMul(mul), mAdd(add) {}

    void setMul(SkColor mul) {
        mMul = mul;
        discardInstance();
    }

    void setAdd(SkColor add) {
        mAdd = add;
        discardInstance();
    }

private:
    sk_sp<SkColorFilter> createInstance() override { return SkColorFilters::Lighting(mMul, mAdd); }

private:
    SkColor mMul;
    SkColor mAdd;
};

class ColorMatrixColorFilter : public ColorFilter {
public:
    ColorMatrixColorFilter(std::vector<float>&& matrix) : mMatrix(std::move(matrix)) {}

    void setMatrix(std::vector<float>&& matrix) {
        mMatrix = std::move(matrix);
        discardInstance();
    }

private:
    sk_sp<SkColorFilter> createInstance() override {
        return SkColorFilters::Matrix(mMatrix.data());
    }

private:
    std::vector<float> mMatrix;
};

}  // namespace uirenderer
}  // namespace android

#endif  // COLORFILTER_H_
+56 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.
 */

#ifndef SKIA_WRAPPER_H_
#define SKIA_WRAPPER_H_

#include <SkRefCnt.h>
#include <utils/RefBase.h>

namespace android::uirenderer {

template <typename T>
class SkiaWrapper : public VirtualLightRefBase {
public:
    sk_sp<T> getInstance() {
        if (mInstance != nullptr && shouldDiscardInstance()) {
            mInstance = nullptr;
        }

        if (mInstance == nullptr) {
            mInstance = createInstance();
            mGenerationId++;
        }
        return mInstance;
    }

    virtual bool shouldDiscardInstance() const { return false; }

    void discardInstance() { mInstance = nullptr; }

    [[nodiscard]] int32_t getGenerationId() const { return mGenerationId; }

protected:
    virtual sk_sp<T> createInstance() = 0;

private:
    sk_sp<T> mInstance = nullptr;
    int32_t mGenerationId = 0;
};

}  // namespace android::uirenderer

#endif  // SKIA_WRAPPER_H_
Loading