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

Commit e8e166dc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adopt sampling parameter"

parents 983a8a59 2d1279f3
Loading
Loading
Loading
Loading
+72 −49
Original line number Diff line number Diff line
@@ -306,25 +306,29 @@ struct DrawPicture final : Op {

struct DrawImage final : Op {
    static const auto kType = Type::DrawImage;
    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint,
              BitmapPalette palette)
            : image(std::move(image)), x(x), y(y), palette(palette) {
    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y,
              const SkSamplingOptions& sampling, const SkPaint* paint, BitmapPalette palette)
            : image(std::move(image)), x(x), y(y), sampling(sampling), palette(palette) {
        if (paint) {
            this->paint = *paint;
        }
    }
    sk_sp<const SkImage> image;
    SkScalar x, y;
    SkSamplingOptions sampling;
    SkPaint paint;
    BitmapPalette palette;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawImage(image.get(), x, y, &paint); }
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawImage(image.get(), x, y, sampling, &paint);
    }
};
struct DrawImageRect final : Op {
    static const auto kType = Type::DrawImageRect;
    DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
                  const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
                  BitmapPalette palette)
            : image(std::move(image)), dst(dst), constraint(constraint), palette(palette) {
                  const SkSamplingOptions& sampling, const SkPaint* paint,
                  SkCanvas::SrcRectConstraint constraint, BitmapPalette palette)
            : image(std::move(image)), dst(dst), sampling(sampling), constraint(constraint)
            , palette(palette) {
        this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height());
        if (paint) {
            this->paint = *paint;
@@ -332,23 +336,26 @@ struct DrawImageRect final : Op {
    }
    sk_sp<const SkImage> image;
    SkRect src, dst;
    SkSamplingOptions sampling;
    SkPaint paint;
    SkCanvas::SrcRectConstraint constraint;
    BitmapPalette palette;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawImageRect(image.get(), src, dst, &paint, constraint);
        c->drawImageRect(image.get(), src, dst, sampling, &paint, constraint);
    }
};
struct DrawImageLattice final : Op {
    static const auto kType = Type::DrawImageLattice;
    DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src,
                     const SkRect& dst, const SkPaint* paint, BitmapPalette palette)
                     const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
                     BitmapPalette palette)
            : image(std::move(image))
            , xs(xs)
            , ys(ys)
            , fs(fs)
            , src(src)
            , dst(dst)
            , filter(filter)
            , palette(palette) {
        if (paint) {
            this->paint = *paint;
@@ -358,6 +365,7 @@ struct DrawImageLattice final : Op {
    int xs, ys, fs;
    SkIRect src;
    SkRect dst;
    SkFilterMode filter;
    SkPaint paint;
    BitmapPalette palette;
    void draw(SkCanvas* c, const SkMatrix&) const {
@@ -366,7 +374,8 @@ struct DrawImageLattice final : Op {
        auto flags =
                (0 == fs) ? nullptr : pod<SkCanvas::Lattice::RectType>(
                                              this, (xs + ys) * sizeof(int) + fs * sizeof(SkColor));
        c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst, &paint);
        c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst,
                            filter, &paint);
    }
};

@@ -431,9 +440,10 @@ struct DrawVertices final : Op {
};
struct DrawAtlas final : Op {
    static const auto kType = Type::DrawAtlas;
    DrawAtlas(const SkImage* atlas, int count, SkBlendMode xfermode, const SkRect* cull,
              const SkPaint* paint, bool has_colors)
            : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_colors(has_colors) {
    DrawAtlas(const SkImage* atlas, int count, SkBlendMode mode, const SkSamplingOptions& sampling,
              const SkRect* cull, const SkPaint* paint, bool has_colors)
            : atlas(sk_ref_sp(atlas)), count(count), mode(mode), sampling(sampling)
            , has_colors(has_colors) {
        if (cull) {
            this->cull = *cull;
        }
@@ -443,7 +453,8 @@ struct DrawAtlas final : Op {
    }
    sk_sp<const SkImage> atlas;
    int count;
    SkBlendMode xfermode;
    SkBlendMode mode;
    SkSamplingOptions sampling;
    SkRect cull = kUnset;
    SkPaint paint;
    bool has_colors;
@@ -452,7 +463,8 @@ struct DrawAtlas final : Op {
        auto texs = pod<SkRect>(this, count * sizeof(SkRSXform));
        auto colors = has_colors ? pod<SkColor>(this, count * (sizeof(SkRSXform) + sizeof(SkRect)))
                                 : nullptr;
        c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, maybe_unset(cull), &paint);
        c->drawAtlas(atlas.get(), xforms, texs, colors, count, mode, sampling, maybe_unset(cull),
                     &paint);
    }
};
struct DrawShadowRec final : Op {
@@ -613,16 +625,18 @@ void DisplayListData::drawPicture(const SkPicture* picture, const SkMatrix* matr
    this->push<DrawPicture>(0, picture, matrix, paint);
}
void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
                                const SkPaint* paint, BitmapPalette palette) {
    this->push<DrawImage>(0, std::move(image), x, y, paint, palette);
                                const SkSamplingOptions& sampling, const SkPaint* paint,
                                BitmapPalette palette) {
    this->push<DrawImage>(0, std::move(image), x, y, sampling, paint, palette);
}
void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
                                    const SkRect& dst, const SkPaint* paint,
                                    SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) {
    this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint, palette);
                                    const SkRect& dst, const SkSamplingOptions& sampling,
                                    const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
                                    BitmapPalette palette) {
    this->push<DrawImageRect>(0, std::move(image), src, dst, sampling, paint, constraint, palette);
}
void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
                                       const SkRect& dst, const SkPaint* paint,
                                       const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
                                       BitmapPalette palette) {
    int xs = lattice.fXCount, ys = lattice.fYCount;
    int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0;
@@ -630,7 +644,7 @@ void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanva
                   fs * sizeof(SkColor);
    SkASSERT(lattice.fBounds);
    void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds,
                                             dst, paint, palette);
                                             dst, filter, paint, palette);
    copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes,
           fs);
}
@@ -650,18 +664,19 @@ void DisplayListData::drawPoints(SkCanvas::PointMode mode, size_t count, const S
    void* pod = this->push<DrawPoints>(count * sizeof(SkPoint), mode, count, paint);
    copy_v(pod, points, count);
}
void DisplayListData::drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint) {
    this->push<DrawVertices>(0, vertices, mode, paint);
void DisplayListData::drawVertices(const SkVertices* vert, SkBlendMode mode, const SkPaint& paint) {
    this->push<DrawVertices>(0, vert, mode, paint);
}
void DisplayListData::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
                                const SkColor colors[], int count, SkBlendMode xfermode,
                                const SkRect* cull, const SkPaint* paint) {
                                const SkSamplingOptions& sampling, const SkRect* cull,
                                const SkPaint* paint) {
    size_t bytes = count * (sizeof(SkRSXform) + sizeof(SkRect));
    if (colors) {
        bytes += count * sizeof(SkColor);
    }
    void* pod =
            this->push<DrawAtlas>(bytes, atlas, count, xfermode, cull, paint, colors != nullptr);
    void* pod = this->push<DrawAtlas>(bytes, atlas, count, xfermode, sampling, cull, paint,
                                      colors != nullptr);
    copy_v(pod, xforms, count, texs, count, colors, colors ? count : 0);
}
void DisplayListData::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
@@ -887,18 +902,20 @@ void RecordingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScala
}

void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
                                const SkPaint* paint, BitmapPalette palette) {
    fDL->drawImage(image, x, y, paint, palette);
                                const SkSamplingOptions& sampling, const SkPaint* paint,
                                BitmapPalette palette) {
    fDL->drawImage(image, x, y, sampling, paint, palette);
}

void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src,
                                    const SkRect& dst, const SkPaint* paint,
                                    SrcRectConstraint constraint, BitmapPalette palette) {
    fDL->drawImageRect(image, &src, dst, paint, constraint, palette);
                                    const SkRect& dst, const SkSamplingOptions& sampling,
                                    const SkPaint* paint, SrcRectConstraint constraint,
                                    BitmapPalette palette) {
    fDL->drawImageRect(image, &src, dst, sampling, paint, constraint, palette);
}

void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice,
                                       const SkRect& dst, const SkPaint* paint,
                                       const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
                                       BitmapPalette palette) {
    if (!image || dst.isEmpty()) {
        return;
@@ -912,24 +929,29 @@ void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattic
    }

    if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
        fDL->drawImageLattice(image, latticePlusBounds, dst, paint, palette);
        fDL->drawImageLattice(image, latticePlusBounds, dst, filter, paint, palette);
    } else {
        fDL->drawImageRect(image, nullptr, dst, paint, SrcRectConstraint::kFast_SrcRectConstraint,
                           palette);
        SkSamplingOptions sampling(filter, SkMipmapMode::kNone);
        fDL->drawImageRect(image, nullptr, dst, sampling, paint, kFast_SrcRectConstraint, palette);
    }
}

void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y,
                                  const SkPaint* paint) {
    fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown);
void RecordingCanvas::onDrawImage2(const SkImage* img, SkScalar x, SkScalar y,
                                   const SkSamplingOptions& sampling, const SkPaint* paint) {
    fDL->drawImage(sk_ref_sp(img), x, y, sampling, paint, BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst,
                                      const SkPaint* paint, SrcRectConstraint constraint) {
    fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint, BitmapPalette::Unknown);

void RecordingCanvas::onDrawImageRect2(const SkImage* img, const SkRect& src, const SkRect& dst,
                                       const SkSamplingOptions& sampling, const SkPaint* paint,
                                       SrcRectConstraint constraint) {
    fDL->drawImageRect(sk_ref_sp(img), &src, dst, sampling, paint, constraint,
                       BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice,
                                         const SkRect& dst, const SkPaint* paint) {
    fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint, BitmapPalette::Unknown);

void RecordingCanvas::onDrawImageLattice2(const SkImage* img, const SkCanvas::Lattice& lattice,
                                          const SkRect& dst, SkFilterMode filter,
                                          const SkPaint* paint) {
    fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, filter, paint, BitmapPalette::Unknown);
}

void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
@@ -945,10 +967,11 @@ void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices,
                                           SkBlendMode mode, const SkPaint& paint) {
    fDL->drawVertices(vertices, mode, paint);
}
void RecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[],
void RecordingCanvas::onDrawAtlas2(const SkImage* atlas, const SkRSXform xforms[],
                                   const SkRect texs[], const SkColor colors[], int count,
                                  SkBlendMode bmode, const SkRect* cull, const SkPaint* paint) {
    fDL->drawAtlas(atlas, xforms, texs, colors, count, bmode, cull, paint);
                                   SkBlendMode bmode, const SkSamplingOptions& sampling,
                                   const SkRect* cull, const SkPaint* paint) {
    fDL->drawAtlas(atlas, xforms, texs, colors, count, bmode, sampling, cull, paint);
}
void RecordingCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
    fDL->drawShadowRec(path, rec);
+18 −15
Original line number Diff line number Diff line
@@ -108,19 +108,20 @@ private:

    void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);

    void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*, BitmapPalette palette);
    void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkSamplingOptions&,
                   const SkPaint*, BitmapPalette palette);
    void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
    void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkPaint*,
                       SkCanvas::SrcRectConstraint, BitmapPalette palette);
    void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkSamplingOptions&,
                       const SkPaint*, SkCanvas::SrcRectConstraint, BitmapPalette palette);
    void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
                          const SkPaint*, BitmapPalette);
                          SkFilterMode, const SkPaint*, BitmapPalette);

    void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
                   const SkPaint&);
    void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&);
    void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&);
    void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
                   SkBlendMode, const SkRect*, const SkPaint*);
                   SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*);
    void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
    void drawVectorDrawable(VectorDrawableRoot* tree);
    void drawWebView(skiapipeline::FunctorDrawable*);
@@ -178,25 +179,27 @@ public:

    void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;

    void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top, const SkPaint* paint,
                   BitmapPalette pallete);
    void drawImage(const sk_sp<SkImage>&, SkScalar left, SkScalar top, const SkSamplingOptions&,
                   const SkPaint* paint, BitmapPalette pallete);

    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
                       const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette);
                       const SkSamplingOptions&, const SkPaint*, SrcRectConstraint, BitmapPalette);
    void drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, const SkRect& dst,
                          const SkPaint* paint, BitmapPalette palette);
                          SkFilterMode, const SkPaint* paint, BitmapPalette palette);

    void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
    void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
    void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
                         SrcRectConstraint) override;
    void onDrawImage2(const SkImage*, SkScalar, SkScalar, const SkSamplingOptions&,
                      const SkPaint*) override;
    void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect&, SkFilterMode,
                             const SkPaint*) override;
    void onDrawImageRect2(const SkImage*, const SkRect&, const SkRect&, const SkSamplingOptions&,
                          const SkPaint*, SrcRectConstraint) override;

    void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
                     const SkPaint&) override;
    void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
    void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
    void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
                     SkBlendMode, const SkRect*, const SkPaint*) override;
    void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
                     SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*) override;
    void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;

    void drawVectorDrawable(VectorDrawableRoot* tree);
+0 −1
Original line number Diff line number Diff line
@@ -190,7 +190,6 @@ protected:
        }
        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;
+6 −5
Original line number Diff line number Diff line
@@ -86,17 +86,18 @@ protected:
        mOutput << mIdent << "drawTextBlob" << std::endl;
    }

    void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*) override {
    void onDrawImage2(const SkImage*, SkScalar dx, SkScalar dy, const SkSamplingOptions&,
                      const SkPaint*) override {
        mOutput << mIdent << "drawImage" << std::endl;
    }

    void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
                         SrcRectConstraint) override {
    void onDrawImageRect2(const SkImage*, const SkRect&, const SkRect&, const SkSamplingOptions&,
                          const SkPaint*, SrcRectConstraint) override {
        mOutput << mIdent << "drawImageRect" << std::endl;
    }

    void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst,
                            const SkPaint*) override {
    void onDrawImageLattice2(const SkImage*, const Lattice& lattice, const SkRect& dst,
                             SkFilterMode, const SkPaint*) override {
        mOutput << mIdent << "drawImageLattice" << std::endl;
    }

+30 −18
Original line number Diff line number Diff line
@@ -185,18 +185,21 @@ static SkDrawLooper* get_looper(const Paint* paint) {
}

template <typename Proc>
void applyLooper(SkDrawLooper* looper, const SkPaint& paint, Proc proc) {
void applyLooper(SkDrawLooper* looper, const SkPaint* paint, Proc proc) {
    if (looper) {
        SkSTArenaAlloc<256> alloc;
        SkDrawLooper::Context* ctx = looper->makeContext(&alloc);
        if (ctx) {
            SkDrawLooper::Context::Info info;
            for (;;) {
                SkPaint p = paint;
                SkPaint p;
                if (paint) {
                    p = *paint;
                }
                if (!ctx->next(&info, &p)) {
                    break;
                }
                proc(info.fTranslate.fX, info.fTranslate.fY, p);
                proc(info.fTranslate.fX, info.fTranslate.fY, &p);
            }
        }
    } else {
@@ -204,11 +207,22 @@ void applyLooper(SkDrawLooper* looper, const SkPaint& paint, Proc proc) {
    }
}

static SkFilterMode Paint_to_filter(const SkPaint* paint) {
    return paint && paint->getFilterQuality() != kNone_SkFilterQuality ? SkFilterMode::kLinear
                                                                       : SkFilterMode::kNearest;
}

static SkSamplingOptions Paint_to_sampling(const SkPaint* paint) {
    // Android only has 1-bit for "filter", so we don't try to cons-up mipmaps or cubics
    return SkSamplingOptions(Paint_to_filter(paint), SkMipmapMode::kNone);
}

void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) {
    sk_sp<SkImage> image = bitmap.makeImage();

    applyLooper(get_looper(paint), *filterBitmap(paint), [&](SkScalar x, SkScalar y, const SkPaint& p) {
        mRecorder.drawImage(image, left + x, top + y, &p, bitmap.palette());
    applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
                const SkPaint* p) {
        mRecorder.drawImage(image, left + x, top + y, Paint_to_sampling(p), p, bitmap.palette());
    });

    // if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
@@ -225,8 +239,9 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, con

    sk_sp<SkImage> image = bitmap.makeImage();

    applyLooper(get_looper(paint), *filterBitmap(paint), [&](SkScalar x, SkScalar y, const SkPaint& p) {
        mRecorder.drawImage(image, x, y, &p, bitmap.palette());
    applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
                const SkPaint* p) {
        mRecorder.drawImage(image, x, y, Paint_to_sampling(p), p, bitmap.palette());
    });

    if (!bitmap.isImmutable() && image.get() && !image->unique()) {
@@ -242,9 +257,10 @@ void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop

    sk_sp<SkImage> image = bitmap.makeImage();

    applyLooper(get_looper(paint), *filterBitmap(paint), [&](SkScalar x, SkScalar y, const SkPaint& p) {
        mRecorder.drawImageRect(image, srcRect, dstRect.makeOffset(x, y), &p,
                                SkCanvas::kFast_SrcRectConstraint, bitmap.palette());
    applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
                const SkPaint* p) {
        mRecorder.drawImageRect(image, srcRect, dstRect.makeOffset(x, y), Paint_to_sampling(p),
                                p, SkCanvas::kFast_SrcRectConstraint, bitmap.palette());
    });

    if (!bitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty() &&
@@ -276,16 +292,12 @@ void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& ch

    lattice.fBounds = nullptr;
    SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);

    PaintCoW filteredPaint(paint);
    // HWUI always draws 9-patches with bilinear filtering, regardless of what is set in the Paint.
    if (!filteredPaint || filteredPaint->getFilterQuality() != kLow_SkFilterQuality) {
        filteredPaint.writeable().setFilterQuality(kLow_SkFilterQuality);
    }
    sk_sp<SkImage> image = bitmap.makeImage();

    applyLooper(get_looper(paint), *filterBitmap(paint), [&](SkScalar x, SkScalar y, const SkPaint& p) {
        mRecorder.drawImageLattice(image, lattice, dst.makeOffset(x, y), &p, bitmap.palette());
    applyLooper(get_looper(paint), filterBitmap(paint), [&](SkScalar x, SkScalar y,
                const SkPaint* p) {
        mRecorder.drawImageLattice(image, lattice, dst.makeOffset(x, y), Paint_to_filter(p),
                                   p, bitmap.palette());
    });

    if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
Loading