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

Commit 81926cfb authored by Ben Wagner's avatar Ben Wagner Committed by Android (Google) Code Review
Browse files

Merge "Replace SkDrawFilter with PaintFilter."

parents 1c2ebb30 0ed10bed
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -126,7 +126,6 @@ cc_library_shared {
        "android/graphics/Camera.cpp",
        "android/graphics/Camera.cpp",
        "android/graphics/CanvasProperty.cpp",
        "android/graphics/CanvasProperty.cpp",
        "android/graphics/ColorFilter.cpp",
        "android/graphics/ColorFilter.cpp",
        "android/graphics/DrawFilter.cpp",
        "android/graphics/FontFamily.cpp",
        "android/graphics/FontFamily.cpp",
        "android/graphics/FontUtils.cpp",
        "android/graphics/FontUtils.cpp",
        "android/graphics/CreateJavaOutputStreamAdaptor.cpp",
        "android/graphics/CreateJavaOutputStreamAdaptor.cpp",
@@ -143,6 +142,7 @@ cc_library_shared {
        "android/graphics/NinePatch.cpp",
        "android/graphics/NinePatch.cpp",
        "android/graphics/NinePatchPeeker.cpp",
        "android/graphics/NinePatchPeeker.cpp",
        "android/graphics/Paint.cpp",
        "android/graphics/Paint.cpp",
        "android/graphics/PaintFilter.cpp",
        "android/graphics/Path.cpp",
        "android/graphics/Path.cpp",
        "android/graphics/PathMeasure.cpp",
        "android/graphics/PathMeasure.cpp",
        "android/graphics/PathEffect.cpp",
        "android/graphics/PathEffect.cpp",
+33 −26
Original line number Original line Diff line number Diff line
@@ -15,36 +15,43 @@
** limitations under the License.
** limitations under the License.
*/
*/


// This file was generated from the C++ include file: SkColorFilter.h
// Any changes made to this file will be discarded by the build.
// To change this file, either edit the include, or device/tools/gluemaker/main.cpp, 
// or one of the auxilary file specifications in device/tools/gluemaker.

#include "jni.h"
#include "jni.h"
#include "GraphicsJNI.h"
#include "GraphicsJNI.h"
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/AndroidRuntime.h>


#include "core_jni_helpers.h"
#include "core_jni_helpers.h"


#include "SkDrawFilter.h"
#include "hwui/PaintFilter.h"
#include "SkPaintFlagsDrawFilter.h"
#include "SkPaint.h"
#include "SkPaint.h"


namespace android {
namespace android {


// Custom version of SkPaintFlagsDrawFilter that also calls setFilterQuality.
class PaintFlagsFilter : public PaintFilter {
class CompatFlagsDrawFilter : public SkPaintFlagsDrawFilter {
public:
    PaintFlagsFilter(uint32_t clearFlags, uint32_t setFlags) {
        fClearFlags = static_cast<uint16_t>(clearFlags & SkPaint::kAllFlags);
        fSetFlags = static_cast<uint16_t>(setFlags & SkPaint::kAllFlags);
    }
    void filter(SkPaint* paint) override {
        paint->setFlags((paint->getFlags() & ~fClearFlags) | fSetFlags);
    }

private:
    uint16_t fClearFlags;
    uint16_t fSetFlags;
};

// Custom version of PaintFlagsDrawFilter that also calls setFilterQuality.
class CompatPaintFlagsFilter : public PaintFlagsFilter {
public:
public:
    CompatFlagsDrawFilter(uint32_t clearFlags, uint32_t setFlags,
    CompatPaintFlagsFilter(uint32_t clearFlags, uint32_t setFlags, SkFilterQuality desiredQuality)
            SkFilterQuality desiredQuality)
    : PaintFlagsFilter(clearFlags, setFlags)
    : SkPaintFlagsDrawFilter(clearFlags, setFlags)
    , fDesiredQuality(desiredQuality) {
    , fDesiredQuality(desiredQuality) {
    }
    }


    virtual bool filter(SkPaint* paint, Type type) {
    virtual void filter(SkPaint* paint) {
        SkPaintFlagsDrawFilter::filter(paint, type);
        PaintFlagsFilter::filter(paint);
        paint->setFilterQuality(fDesiredQuality);
        paint->setFilterQuality(fDesiredQuality);
        return true;
    }
    }


private:
private:
@@ -61,15 +68,15 @@ static inline bool hadFiltering(jint& flags) {
    return result;
    return result;
}
}


class SkDrawFilterGlue {
class PaintFilterGlue {
public:
public:


    static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
    static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
        SkDrawFilter* obj = reinterpret_cast<SkDrawFilter*>(objHandle);
        PaintFilter* obj = reinterpret_cast<PaintFilter*>(objHandle);
        SkSafeUnref(obj);
        SkSafeUnref(obj);
    }
    }


    static jlong CreatePaintFlagsDF(JNIEnv* env, jobject clazz,
    static jlong CreatePaintFlagsFilter(JNIEnv* env, jobject clazz,
                                        jint clearFlags, jint setFlags) {
                                        jint clearFlags, jint setFlags) {
        if (clearFlags | setFlags) {
        if (clearFlags | setFlags) {
            // Mask both groups of flags to remove FILTER_BITMAP_FLAG, which no
            // Mask both groups of flags to remove FILTER_BITMAP_FLAG, which no
@@ -79,16 +86,16 @@ public:
            const bool turnFilteringOn = hadFiltering(setFlags);
            const bool turnFilteringOn = hadFiltering(setFlags);
            const bool turnFilteringOff = hadFiltering(clearFlags);
            const bool turnFilteringOff = hadFiltering(clearFlags);


            SkDrawFilter* filter;
            PaintFilter* filter;
            if (turnFilteringOn) {
            if (turnFilteringOn) {
                // Turning filtering on overrides turning it off.
                // Turning filtering on overrides turning it off.
                filter = new CompatFlagsDrawFilter(clearFlags, setFlags,
                filter = new CompatPaintFlagsFilter(clearFlags, setFlags,
                        kLow_SkFilterQuality);
                        kLow_SkFilterQuality);
            } else if (turnFilteringOff) {
            } else if (turnFilteringOff) {
                filter = new CompatFlagsDrawFilter(clearFlags, setFlags,
                filter = new CompatPaintFlagsFilter(clearFlags, setFlags,
                        kNone_SkFilterQuality);
                        kNone_SkFilterQuality);
            } else {
            } else {
                filter = new SkPaintFlagsDrawFilter(clearFlags, setFlags);
                filter = new PaintFlagsFilter(clearFlags, setFlags);
            }
            }
            return reinterpret_cast<jlong>(filter);
            return reinterpret_cast<jlong>(filter);
        } else {
        } else {
@@ -98,11 +105,11 @@ public:
};
};


static const JNINativeMethod drawfilter_methods[] = {
static const JNINativeMethod drawfilter_methods[] = {
    {"nativeDestructor", "(J)V", (void*) SkDrawFilterGlue::finalizer}
    {"nativeDestructor", "(J)V", (void*) PaintFilterGlue::finalizer}
};
};


static const JNINativeMethod paintflags_methods[] = {
static const JNINativeMethod paintflags_methods[] = {
    {"nativeConstructor","(II)J", (void*) SkDrawFilterGlue::CreatePaintFlagsDF}
    {"nativeConstructor","(II)J", (void*) PaintFilterGlue::CreatePaintFlagsFilter}
};
};


int register_android_graphics_DrawFilter(JNIEnv* env) {
int register_android_graphics_DrawFilter(JNIEnv* env) {
+5 −4
Original line number Original line Diff line number Diff line
@@ -22,13 +22,13 @@
#include <androidfw/ResourceTypes.h>
#include <androidfw/ResourceTypes.h>
#include <hwui/Canvas.h>
#include <hwui/Canvas.h>
#include <hwui/Paint.h>
#include <hwui/Paint.h>
#include <hwui/PaintFilter.h>
#include <hwui/Typeface.h>
#include <hwui/Typeface.h>
#include <minikin/Layout.h>
#include <minikin/Layout.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedStringChars.h>
#include <nativehelper/ScopedStringChars.h>


#include "Bitmap.h"
#include "Bitmap.h"
#include "SkDrawFilter.h"
#include "SkGraphics.h"
#include "SkGraphics.h"
#include "SkRegion.h"
#include "SkRegion.h"
#include "SkVertices.h"
#include "SkVertices.h"
@@ -582,8 +582,9 @@ static void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstri
    env->ReleaseStringChars(text, jchars);
    env->ReleaseStringChars(text, jchars);
}
}


static void setDrawFilter(jlong canvasHandle, jlong filterHandle) {
static void setPaintFilter(jlong canvasHandle, jlong filterHandle) {
    get_canvas(canvasHandle)->setDrawFilter(reinterpret_cast<SkDrawFilter*>(filterHandle));
    PaintFilter* paintFilter = reinterpret_cast<PaintFilter*>(filterHandle);
    get_canvas(canvasHandle)->setPaintFilter(sk_ref_sp(paintFilter));
}
}


static void freeCaches(JNIEnv* env, jobject) {
static void freeCaches(JNIEnv* env, jobject) {
@@ -633,7 +634,7 @@ static const JNINativeMethod gMethods[] = {
    {"nQuickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect},
    {"nQuickReject","(JFFFF)Z", (void*)CanvasJNI::quickRejectRect},
    {"nClipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect},
    {"nClipRect","(JFFFFI)Z", (void*) CanvasJNI::clipRect},
    {"nClipPath","(JJI)Z", (void*) CanvasJNI::clipPath},
    {"nClipPath","(JJI)Z", (void*) CanvasJNI::clipPath},
    {"nSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setDrawFilter},
    {"nSetDrawFilter", "(JJ)V", (void*) CanvasJNI::setPaintFilter},
};
};


// If called from Canvas these are regular JNI
// If called from Canvas these are regular JNI
+58 −53
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@
#include "VectorDrawable.h"
#include "VectorDrawable.h"
#include "hwui/Bitmap.h"
#include "hwui/Bitmap.h"
#include "hwui/MinikinUtils.h"
#include "hwui/MinikinUtils.h"
#include "hwui/PaintFilter.h"
#include "pipeline/skia/AnimatedDrawables.h"
#include "pipeline/skia/AnimatedDrawables.h"


#include <SkAnimatedImage.h>
#include <SkAnimatedImage.h>
@@ -28,7 +29,6 @@
#include <SkColorFilter.h>
#include <SkColorFilter.h>
#include <SkColorSpaceXformCanvas.h>
#include <SkColorSpaceXformCanvas.h>
#include <SkDeque.h>
#include <SkDeque.h>
#include <SkDrawFilter.h>
#include <SkDrawable.h>
#include <SkDrawable.h>
#include <SkGraphics.h>
#include <SkGraphics.h>
#include <SkImage.h>
#include <SkImage.h>
@@ -40,6 +40,8 @@
#include <SkTextBlob.h>
#include <SkTextBlob.h>


#include <memory>
#include <memory>
#include <optional>
#include <utility>


namespace android {
namespace android {


@@ -211,7 +213,7 @@ public:
    Clip(const SkRRect& rrect, SkClipOp op, const SkMatrix& m)
    Clip(const SkRRect& rrect, SkClipOp op, const SkMatrix& m)
            : mType(Type::RRect), mOp(op), mMatrix(m), mRRect(rrect) {}
            : mType(Type::RRect), mOp(op), mMatrix(m), mRRect(rrect) {}
    Clip(const SkPath& path, SkClipOp op, const SkMatrix& m)
    Clip(const SkPath& path, SkClipOp op, const SkMatrix& m)
            : mType(Type::Path), mOp(op), mMatrix(m), mPath(&path) {}
            : mType(Type::Path), mOp(op), mMatrix(m), mPath(std::in_place, path) {}


    void apply(SkCanvas* canvas) const {
    void apply(SkCanvas* canvas) const {
        canvas->setMatrix(mMatrix);
        canvas->setMatrix(mMatrix);
@@ -223,7 +225,7 @@ public:
                canvas->clipRRect(mRRect, mOp);
                canvas->clipRRect(mRRect, mOp);
                break;
                break;
            case Type::Path:
            case Type::Path:
                canvas->clipPath(*mPath.get(), mOp);
                canvas->clipPath(mPath.value(), mOp);
                break;
                break;
        }
        }
    }
    }
@@ -240,7 +242,7 @@ private:
    SkMatrix mMatrix;
    SkMatrix mMatrix;


    // These are logically a union (tracked separately due to non-POD path).
    // These are logically a union (tracked separately due to non-POD path).
    SkTLazy<SkPath> mPath;
    std::optional<SkPath> mPath;
    SkRRect mRRect;
    SkRRect mRRect;
};
};


@@ -400,12 +402,12 @@ bool SkiaCanvas::clipPath(const SkPath* path, SkClipOp op) {
// Canvas state operations: Filters
// Canvas state operations: Filters
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


SkDrawFilter* SkiaCanvas::getDrawFilter() {
PaintFilter* SkiaCanvas::getPaintFilter() {
    return mCanvas->getDrawFilter();
    return mPaintFilter.get();
}
}


void SkiaCanvas::setDrawFilter(SkDrawFilter* drawFilter) {
void SkiaCanvas::setPaintFilter(sk_sp<PaintFilter> paintFilter) {
    mCanvas->setDrawFilter(drawFilter);
    mPaintFilter = std::move(paintFilter);
}
}


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -439,8 +441,15 @@ void SkiaCanvas::drawColor(int color, SkBlendMode mode) {
    mCanvas->drawColor(color, mode);
    mCanvas->drawColor(color, mode);
}
}


SkiaCanvas::PaintCoW&& SkiaCanvas::filterPaint(PaintCoW&& paint) const {
    if (mPaintFilter) {
        mPaintFilter->filter(&paint.writeable());
    }
    return std::move(paint);
}

void SkiaCanvas::drawPaint(const SkPaint& paint) {
void SkiaCanvas::drawPaint(const SkPaint& paint) {
    mCanvas->drawPaint(paint);
    mCanvas->drawPaint(*filterPaint(paint));
}
}


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -457,53 +466,53 @@ void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint
        pts[i].set(points[0], points[1]);
        pts[i].set(points[0], points[1]);
        points += 2;
        points += 2;
    }
    }
    mCanvas->drawPoints(mode, count, pts.get(), paint);
    mCanvas->drawPoints(mode, count, pts.get(), *filterPaint(paint));
}
}


void SkiaCanvas::drawPoint(float x, float y, const SkPaint& paint) {
void SkiaCanvas::drawPoint(float x, float y, const SkPaint& paint) {
    mCanvas->drawPoint(x, y, paint);
    mCanvas->drawPoint(x, y, *filterPaint(paint));
}
}


void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint) {
void SkiaCanvas::drawPoints(const float* points, int count, const SkPaint& paint) {
    this->drawPoints(points, count, paint, SkCanvas::kPoints_PointMode);
    this->drawPoints(points, count, *filterPaint(paint), SkCanvas::kPoints_PointMode);
}
}


void SkiaCanvas::drawLine(float startX, float startY, float stopX, float stopY,
void SkiaCanvas::drawLine(float startX, float startY, float stopX, float stopY,
                          const SkPaint& paint) {
                          const SkPaint& paint) {
    mCanvas->drawLine(startX, startY, stopX, stopY, paint);
    mCanvas->drawLine(startX, startY, stopX, stopY, *filterPaint(paint));
}
}


void SkiaCanvas::drawLines(const float* points, int count, const SkPaint& paint) {
void SkiaCanvas::drawLines(const float* points, int count, const SkPaint& paint) {
    if (CC_UNLIKELY(count < 4 || paint.nothingToDraw())) return;
    if (CC_UNLIKELY(count < 4 || paint.nothingToDraw())) return;
    this->drawPoints(points, count, paint, SkCanvas::kLines_PointMode);
    this->drawPoints(points, count, *filterPaint(paint), SkCanvas::kLines_PointMode);
}
}


void SkiaCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) {
void SkiaCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) {
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    mCanvas->drawRect({left, top, right, bottom}, paint);
    mCanvas->drawRect({left, top, right, bottom}, *filterPaint(paint));
}
}


void SkiaCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
void SkiaCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    mCanvas->drawRegion(region, paint);
    mCanvas->drawRegion(region, *filterPaint(paint));
}
}


void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
void SkiaCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
                               const SkPaint& paint) {
                               const SkPaint& paint) {
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
    mCanvas->drawRoundRect(rect, rx, ry, paint);
    mCanvas->drawRoundRect(rect, rx, ry, *filterPaint(paint));
}
}


void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
    if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return;
    if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return;
    mCanvas->drawCircle(x, y, radius, paint);
    mCanvas->drawCircle(x, y, radius, *filterPaint(paint));
}
}


void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) {
void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) {
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
    SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
    mCanvas->drawOval(oval, paint);
    mCanvas->drawOval(oval, *filterPaint(paint));
}
}


void SkiaCanvas::drawArc(float left, float top, float right, float bottom, float startAngle,
void SkiaCanvas::drawArc(float left, float top, float right, float bottom, float startAngle,
@@ -511,9 +520,9 @@ void SkiaCanvas::drawArc(float left, float top, float right, float bottom, float
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    SkRect arc = SkRect::MakeLTRB(left, top, right, bottom);
    SkRect arc = SkRect::MakeLTRB(left, top, right, bottom);
    if (fabs(sweepAngle) >= 360.0f) {
    if (fabs(sweepAngle) >= 360.0f) {
        mCanvas->drawOval(arc, paint);
        mCanvas->drawOval(arc, *filterPaint(paint));
    } else {
    } else {
        mCanvas->drawArc(arc, startAngle, sweepAngle, useCenter, paint);
        mCanvas->drawArc(arc, startAngle, sweepAngle, useCenter, *filterPaint(paint));
    }
    }
}
}


@@ -522,19 +531,19 @@ void SkiaCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
    if (CC_UNLIKELY(path.isEmpty() && (!path.isInverseFillType()))) {
    if (CC_UNLIKELY(path.isEmpty() && (!path.isInverseFillType()))) {
        return;
        return;
    }
    }
    mCanvas->drawPath(path, paint);
    mCanvas->drawPath(path, *filterPaint(paint));
}
}


void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
    mCanvas->drawVertices(vertices, mode, paint);
    mCanvas->drawVertices(vertices, mode, *filterPaint(paint));
}
}


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Canvas draw operations: Bitmaps
// Canvas draw operations: Bitmaps
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


const SkPaint* SkiaCanvas::addFilter(const SkPaint* origPaint, SkPaint* tmpPaint,
SkiaCanvas::PaintCoW&& SkiaCanvas::filterBitmap(PaintCoW&& paint,
                                     sk_sp<SkColorFilter> colorSpaceFilter) {
                                                sk_sp<SkColorFilter> colorSpaceFilter) const {
    /* We don't apply the colorSpace filter if this canvas is already wrapped with
    /* We don't apply the colorSpace filter if this canvas is already wrapped with
     * a SkColorSpaceXformCanvas since it already takes care of converting the
     * a SkColorSpaceXformCanvas since it already takes care of converting the
     * contents of the bitmap into the appropriate colorspace.  The mCanvasWrapper
     * contents of the bitmap into the appropriate colorspace.  The mCanvasWrapper
@@ -542,39 +551,31 @@ const SkPaint* SkiaCanvas::addFilter(const SkPaint* origPaint, SkPaint* tmpPaint
     * to have a non-sRGB colorspace.
     * to have a non-sRGB colorspace.
     */
     */
    if (!mCanvasWrapper && colorSpaceFilter) {
    if (!mCanvasWrapper && colorSpaceFilter) {
        if (origPaint) {
        SkPaint& tmpPaint = paint.writeable();
            *tmpPaint = *origPaint;
        if (tmpPaint.getColorFilter()) {
        }
            tmpPaint.setColorFilter(SkColorFilter::MakeComposeFilter(tmpPaint.refColorFilter(),

                                                                     std::move(colorSpaceFilter)));
        if (tmpPaint->getColorFilter()) {
            LOG_ALWAYS_FATAL_IF(!tmpPaint.getColorFilter());
            tmpPaint->setColorFilter(
                    SkColorFilter::MakeComposeFilter(tmpPaint->refColorFilter(), colorSpaceFilter));
            LOG_ALWAYS_FATAL_IF(!tmpPaint->getColorFilter());
        } else {
        } else {
            tmpPaint->setColorFilter(colorSpaceFilter);
            tmpPaint.setColorFilter(std::move(colorSpaceFilter));
        }
        }

        return tmpPaint;
    } else {
        return origPaint;
    }
    }
    return filterPaint(std::move(paint));
}
}


void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
    SkPaint tmpPaint;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    mCanvas->drawImage(image, left, top, addFilter(paint, &tmpPaint, colorFilter));
    mCanvas->drawImage(image, left, top, filterBitmap(paint, std::move(colorFilter)));
}
}


void SkiaCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) {
void SkiaCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) {
    SkAutoCanvasRestore acr(mCanvas, true);
    SkAutoCanvasRestore acr(mCanvas, true);
    mCanvas->concat(matrix);
    mCanvas->concat(matrix);


    SkPaint tmpPaint;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    mCanvas->drawImage(image, 0, 0, addFilter(paint, &tmpPaint, colorFilter));
    mCanvas->drawImage(image, 0, 0, filterBitmap(paint, std::move(colorFilter)));
}
}


void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
@@ -583,10 +584,9 @@ void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float s
    SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
    SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
    SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
    SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);


    SkPaint tmpPaint;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    mCanvas->drawImageRect(image, srcRect, dstRect, addFilter(paint, &tmpPaint, colorFilter),
    mCanvas->drawImageRect(image, srcRect, dstRect, filterBitmap(paint, std::move(colorFilter)),
                           SkCanvas::kFast_SrcRectConstraint);
                           SkCanvas::kFast_SrcRectConstraint);
}
}


@@ -665,21 +665,20 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
#endif
#endif


    // cons-up a shader for the bitmap
    // cons-up a shader for the bitmap
    SkPaint tmpPaint;
    PaintCoW paintCoW(paint);
    if (paint) {
    SkPaint& tmpPaint = paintCoW.writeable();
        tmpPaint = *paint;
    }


    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    sk_sp<SkShader> shader =
    sk_sp<SkShader> shader =
            image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
            image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
    if (colorFilter) {
    if (colorFilter) {
        shader = shader->makeWithColorFilter(colorFilter);
        shader = shader->makeWithColorFilter(std::move(colorFilter));
    }
    }
    tmpPaint.setShader(shader);
    tmpPaint.setShader(std::move(shader));


    mCanvas->drawVertices(builder.detach(), SkBlendMode::kModulate, tmpPaint);
    mCanvas->drawVertices(builder.detach(), SkBlendMode::kModulate,
                          *filterPaint(std::move(paintCoW)));
}
}


void SkiaCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, float dstLeft,
void SkiaCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, float dstLeft,
@@ -706,10 +705,10 @@ void SkiaCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, floa
    lattice.fBounds = nullptr;
    lattice.fBounds = nullptr;
    SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
    SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);


    SkPaint tmpPaint;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkColorFilter> colorFilter;
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
    mCanvas->drawImageLattice(image.get(), lattice, dst, addFilter(paint, &tmpPaint, colorFilter));
    mCanvas->drawImageLattice(image.get(), lattice, dst,
                              filterBitmap(paint, std::move(colorFilter)));
}
}


double SkiaCanvas::drawAnimatedImage(AnimatedImageDrawable* imgDrawable) {
double SkiaCanvas::drawAnimatedImage(AnimatedImageDrawable* imgDrawable) {
@@ -732,6 +731,9 @@ void SkiaCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& p
    // glyphs centered or right-aligned; the offset above takes
    // glyphs centered or right-aligned; the offset above takes
    // care of all alignment.
    // care of all alignment.
    SkPaint paintCopy(paint);
    SkPaint paintCopy(paint);
    if (mPaintFilter) {
        mPaintFilter->filter(&paintCopy);
    }
    paintCopy.setTextAlign(SkPaint::kLeft_Align);
    paintCopy.setTextAlign(SkPaint::kLeft_Align);
    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
    // Stroke with a hairline is drawn on HW with a fill style for compatibility with Android O and
    // Stroke with a hairline is drawn on HW with a fill style for compatibility with Android O and
@@ -760,6 +762,9 @@ void SkiaCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset,
    // glyphs centered or right-aligned; the offsets take care of
    // glyphs centered or right-aligned; the offsets take care of
    // that portion of the alignment.
    // that portion of the alignment.
    SkPaint paintCopy(paint);
    SkPaint paintCopy(paint);
    if (mPaintFilter) {
        mPaintFilter->filter(&paintCopy);
    }
    paintCopy.setTextAlign(SkPaint::kLeft_Align);
    paintCopy.setTextAlign(SkPaint::kLeft_Align);
    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);


+55 −5
Original line number Original line Diff line number Diff line
@@ -22,7 +22,9 @@
#include "hwui/Canvas.h"
#include "hwui/Canvas.h"


#include <SkCanvas.h>
#include <SkCanvas.h>
#include <SkTLazy.h>

#include <cassert>
#include <optional>


namespace android {
namespace android {


@@ -87,8 +89,8 @@ public:
    virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
    virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
    virtual bool clipPath(const SkPath* path, SkClipOp op) override;
    virtual bool clipPath(const SkPath* path, SkClipOp op) override;


    virtual SkDrawFilter* getDrawFilter() override;
    virtual PaintFilter* getPaintFilter() override;
    virtual void setDrawFilter(SkDrawFilter* drawFilter) override;
    virtual void setPaintFilter(sk_sp<PaintFilter> paintFilter) override;


    virtual SkCanvasState* captureCanvasState() const override;
    virtual SkCanvasState* captureCanvasState() const override;


@@ -158,6 +160,46 @@ protected:
                                  const SkPaint& paint, const SkPath& path, size_t start,
                                  const SkPaint& paint, const SkPath& path, size_t start,
                                  size_t end) override;
                                  size_t end) override;


    /** This class acts as a copy on write SkPaint.
     *
     *  Initially this will be the SkPaint passed to the contructor.
     *  The first time writable() is called this will become a copy of the
     *  initial SkPaint (or a default SkPaint if nullptr).
     */
    struct PaintCoW {
        PaintCoW(const SkPaint& that) : mPtr(&that) {}
        PaintCoW(const SkPaint* ptr) : mPtr(ptr) {}
        PaintCoW(const PaintCoW&) = delete;
        PaintCoW(PaintCoW&&) = delete;
        PaintCoW& operator=(const PaintCoW&) = delete;
        PaintCoW& operator=(PaintCoW&&) = delete;
        SkPaint& writeable() {
            if (!mStorage) {
                if (!mPtr) {
                    mStorage.emplace();
                } else {
                    mStorage.emplace(*mPtr);
                }
                mPtr = &*mStorage;
            }
            return *mStorage;
        }
        operator const SkPaint*() const { return mPtr; }
        const SkPaint* operator->() const { assert(mPtr); return mPtr; }
        const SkPaint& operator*() const { assert(mPtr); return *mPtr; }
        explicit operator bool() { return mPtr != nullptr; }
    private:
        const SkPaint* mPtr;
        std::optional<SkPaint> mStorage;
    };

    /** Filters the paint using the current paint filter.
     *
     *  @param paint the paint to filter. Will be initialized with the default
     *      SkPaint before filtering if filtering is required.
     */
    PaintCoW&& filterPaint(PaintCoW&& paint) const;

private:
private:
    struct SaveRec {
    struct SaveRec {
        int saveCount;
        int saveCount;
@@ -174,8 +216,15 @@ private:


    void drawPoints(const float* points, int count, const SkPaint& paint, SkCanvas::PointMode mode);
    void drawPoints(const float* points, int count, const SkPaint& paint, SkCanvas::PointMode mode);


    const SkPaint* addFilter(const SkPaint* origPaint, SkPaint* tmpPaint,
    /** Filters the paint for bitmap drawing.
                             sk_sp<SkColorFilter> colorSpaceFilter);
     *
     *  After filtering the paint for bitmap drawing,
     *  also calls filterPaint on the paint.
     *
     *  @param paint the paint to filter. Will be initialized with the default
     *      SkPaint before filtering if filtering is required.
     */
    PaintCoW&& filterBitmap(PaintCoW&& paint, sk_sp<SkColorFilter> colorSpaceFilter) const;


    class Clip;
    class Clip;


@@ -185,6 +234,7 @@ private:
                                               // unless it is the same as mCanvasOwned.get()
                                               // unless it is the same as mCanvasOwned.get()
    std::unique_ptr<SkDeque> mSaveStack;       // lazily allocated, tracks partial saves.
    std::unique_ptr<SkDeque> mSaveStack;       // lazily allocated, tracks partial saves.
    std::vector<Clip> mClipStack;              // tracks persistent clips.
    std::vector<Clip> mClipStack;              // tracks persistent clips.
    sk_sp<PaintFilter> mPaintFilter;
};
};


}  // namespace android
}  // namespace android
Loading