/*
 * Copyright 2010 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkDevice_DEFINED
#define SkDevice_DEFINED

#include "include/core/SkBlender.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkShader.h"
#include "include/core/SkSurfaceProps.h"
#include "include/private/base/SkNoncopyable.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkRasterClip.h"
#include "src/core/SkScalerContext.h"
#include "src/shaders/SkShaderBase.h"

namespace sktext {
class GlyphRun;
class GlyphRunList;
}
class SkBitmap;
class SkColorSpace;
class SkMesh;
struct SkDrawShadowRec;
class SkImageFilter;
class SkImageFilterCache;
struct SkIRect;
class SkRasterHandleAllocator;
class SkSpecialImage;

namespace skif { class Mapping; }
namespace skgpu::v1 {
class Device;
}
namespace skgpu::graphite {
class Device;
}
namespace sktext::gpu {
class SDFTControl;
}

struct SkStrikeDeviceInfo {
    const SkSurfaceProps fSurfaceProps;
    const SkScalerContextFlags fScalerContextFlags;
    // This is a pointer so this can be compiled without SK_GPU_SUPPORT.
    const sktext::gpu::SDFTControl* const fSDFTControl;
};

class SkBaseDevice : public SkRefCnt, public SkMatrixProvider {
public:
    SkBaseDevice(const SkImageInfo&, const SkSurfaceProps&);

    /**
     *  Return ImageInfo for this device. If the canvas is not backed by pixels
     *  (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
     */
    const SkImageInfo& imageInfo() const { return fInfo; }

    /**
     *  Return SurfaceProps for this device.
     */
    const SkSurfaceProps& surfaceProps() const {
        return fSurfaceProps;
    }

    SkScalerContextFlags scalerContextFlags() const;

    virtual SkStrikeDeviceInfo strikeDeviceInfo() const {
        return {fSurfaceProps, this->scalerContextFlags(), nullptr};
    }

    SkIRect bounds() const { return SkIRect::MakeWH(this->width(), this->height()); }

    /**
     *  Return the bounds of the device in the coordinate space of the root
     *  canvas. The root device will have its top-left at 0,0, but other devices
     *  such as those associated with saveLayer may have a non-zero origin.
     */
    void getGlobalBounds(SkIRect* bounds) const {
        SkASSERT(bounds);
        *bounds = SkMatrixPriv::MapRect(fDeviceToGlobal, SkRect::Make(this->bounds())).roundOut();
    }

    SkIRect getGlobalBounds() const {
        SkIRect bounds;
        this->getGlobalBounds(&bounds);
        return bounds;
    }

    /**
     *  Returns the bounding box of the current clip, in this device's
     *  coordinate space. No pixels outside of these bounds will be touched by
     *  draws unless the clip is further modified (at which point this will
     *  return the updated bounds).
     */
    SkIRect devClipBounds() const { return this->onDevClipBounds(); }

    int width() const {
        return this->imageInfo().width();
    }

    int height() const {
        return this->imageInfo().height();
    }

    bool isOpaque() const {
        return this->imageInfo().isOpaque();
    }

    bool writePixels(const SkPixmap&, int x, int y);

    /**
     *  Try to get write-access to the pixels behind the device. If successful, this returns true
     *  and fills-out the pixmap parameter. On success it also bumps the genID of the underlying
     *  bitmap.
     *
     *  On failure, returns false and ignores the pixmap parameter.
     */
    bool accessPixels(SkPixmap* pmap);

    /**
     *  Try to get read-only-access to the pixels behind the device. If successful, this returns
     *  true and fills-out the pixmap parameter.
     *
     *  On failure, returns false and ignores the pixmap parameter.
     */
    bool peekPixels(SkPixmap*);

    /**
     *  Return the device's coordinate space transform: this maps from the device's coordinate space
     *  into the global canvas' space (or root device space). This includes the translation
     *  necessary to account for the device's origin.
     */
    const SkM44& deviceToGlobal() const { return fDeviceToGlobal; }
    /**
     *  Return the inverse of getDeviceToGlobal(), mapping from the global canvas' space (or root
     *  device space) into this device's coordinate space.
     */
    const SkM44& globalToDevice() const { return fGlobalToDevice; }
    /**
     *  DEPRECATED: This asserts that 'getDeviceToGlobal' is a translation matrix with integer
     *  components. In the future some SkDevices will have more complex device-to-global transforms,
     *  so getDeviceToGlobal() or getRelativeTransform() should be used instead.
     */
    SkIPoint getOrigin() const;
    /**
     * Returns true when this device's pixel grid is axis aligned with the global coordinate space,
     * and any relative translation between the two spaces is in integer pixel units.
     */
    bool isPixelAlignedToGlobal() const;
    /**
     * Get the transformation from this device's coordinate system to the provided device space.
     * This transform can be used to draw this device into the provided device, such that once
     * that device is drawn to the root device, the net effect will be that this device's contents
     * have been transformed by the global CTM.
     */
    SkMatrix getRelativeTransform(const SkBaseDevice&) const;

    virtual void* getRasterHandle() const { return nullptr; }

    const SkMatrixProvider& asMatrixProvider() const { return *this; }

    void save() { this->onSave(); }
    void restore(const SkM44& ctm) {
        this->onRestore();
        this->setGlobalCTM(ctm);
    }
    void restoreLocal(const SkM44& localToDevice) {
        this->onRestore();
        this->setLocalToDevice(localToDevice);
    }
    void clipRect(const SkRect& rect, SkClipOp op, bool aa) {
        this->onClipRect(rect, op, aa);
    }
    void clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
        this->onClipRRect(rrect, op, aa);
    }
    void clipPath(const SkPath& path, SkClipOp op, bool aa) {
        this->onClipPath(path, op, aa);
    }
    void clipShader(sk_sp<SkShader> sh, SkClipOp op) {
        sh = as_SB(sh)->makeWithCTM(this->localToDevice());
        if (op == SkClipOp::kDifference) {
            sh = as_SB(sh)->makeInvertAlpha();
        }
        this->onClipShader(std::move(sh));
    }
    void clipRegion(const SkRegion& region, SkClipOp op) {
        this->onClipRegion(region, op);
    }
    void replaceClip(const SkIRect& rect) {
        this->onReplaceClip(rect);
    }

    bool clipIsWideOpen() const {
        return this->onClipIsWideOpen();
    }

    void setLocalToDevice(const SkM44& localToDevice) {
        fLocalToDevice = localToDevice;
        fLocalToDevice33 = fLocalToDevice.asM33();
        fLocalToDeviceDirty = true;
    }
    void setGlobalCTM(const SkM44& ctm);
    virtual void validateDevBounds(const SkIRect&) {}

    virtual bool android_utils_clipWithStencil() { return false; }

    virtual skgpu::v1::Device* asGaneshDevice() { return nullptr; }
    virtual skgpu::graphite::Device* asGraphiteDevice() { return nullptr; }

    // Ensure that non-RSXForm runs are passed to onDrawGlyphRunList.
    void drawGlyphRunList(SkCanvas*,
                          const sktext::GlyphRunList& glyphRunList,
                          const SkPaint& initialPaint,
                          const SkPaint& drawingPaint);

    // Snap the 'subset' contents from this device, possibly as a read-only view. If 'forceCopy'
    // is true then the returned image's pixels must not be affected by subsequent draws into the
    // device. When 'forceCopy' is false, the image can be a view into the device's pixels
    // (avoiding a copy for performance, at the expense of safety). Default returns null.
    virtual sk_sp<SkSpecialImage> snapSpecial(const SkIRect& subset, bool forceCopy = false);
    // Can return null if unable to perform scaling as part of the copy, even if snapSpecial() w/o
    // scaling would succeed.
    virtual sk_sp<SkSpecialImage> snapSpecialScaled(const SkIRect& subset, const SkISize& dstDims);
    // Get a view of the entire device's current contents as an image.
    sk_sp<SkSpecialImage> snapSpecial();

protected:
    enum TileUsage {
        kPossible_TileUsage,    //!< the created device may be drawn tiled
        kNever_TileUsage,       //!< the created device will never be drawn tiled
    };

    struct TextFlags {
        uint32_t    fFlags;     // SkPaint::getFlags()
    };

    virtual void onSave() {}
    virtual void onRestore() {}
    virtual void onClipRect(const SkRect& rect, SkClipOp, bool aa) {}
    virtual void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) {}
    virtual void onClipPath(const SkPath& path, SkClipOp, bool aa) {}
    virtual void onClipShader(sk_sp<SkShader>) {}
    virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp) {}
    virtual void onReplaceClip(const SkIRect& rect) {}
    virtual bool onClipIsAA() const = 0;
    virtual bool onClipIsWideOpen() const = 0;
    virtual void onAsRgnClip(SkRegion*) const = 0;
    enum class ClipType {
        kEmpty,
        kRect,
        kComplex
    };
    virtual ClipType onGetClipType() const = 0;

    // This should strive to be as tight as possible, ideally not just mapping
    // the global clip bounds by fToGlobal^-1.
    virtual SkIRect onDevClipBounds() const = 0;

    /** These are called inside the per-device-layer loop for each draw call.
     When these are called, we have already applied any saveLayer operations,
     and are handling any looping from the paint.
     */
    virtual void drawPaint(const SkPaint& paint) = 0;
    virtual void drawPoints(SkCanvas::PointMode mode, size_t count,
                            const SkPoint[], const SkPaint& paint) = 0;
    virtual void drawRect(const SkRect& r,
                          const SkPaint& paint) = 0;
    virtual void drawRegion(const SkRegion& r,
                            const SkPaint& paint);
    virtual void drawOval(const SkRect& oval,
                          const SkPaint& paint) = 0;
    /** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */
    virtual void drawArc(const SkRect& oval, SkScalar startAngle,
                         SkScalar sweepAngle, bool useCenter, const SkPaint& paint);
    virtual void drawRRect(const SkRRect& rr,
                           const SkPaint& paint) = 0;

    // Default impl calls drawPath()
    virtual void drawDRRect(const SkRRect& outer,
                            const SkRRect& inner, const SkPaint&);

    /**
     *  If pathIsMutable, then the implementation is allowed to cast path to a
     *  non-const pointer and modify it in place (as an optimization). Canvas
     *  may do this to implement helpers such as drawOval, by placing a temp
     *  path on the stack to hold the representation of the oval.
     */
    virtual void drawPath(const SkPath& path,
                          const SkPaint& paint,
                          bool pathIsMutable = false) = 0;

    virtual void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
                               const SkSamplingOptions&, const SkPaint&,
                               SkCanvas::SrcRectConstraint) = 0;
    virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
                                  const SkRect& dst, SkFilterMode, const SkPaint&);

    /**
     * If skipColorXform is true, then the implementation should assume that the provided
     * vertex colors are already in the destination color space.
     */
    virtual void drawVertices(const SkVertices*,
                              sk_sp<SkBlender>,
                              const SkPaint&,
                              bool skipColorXform = false) = 0;
#ifdef SK_ENABLE_SKSL
    virtual void drawMesh(const SkMesh& mesh, sk_sp<SkBlender>, const SkPaint&) = 0;
#endif
    virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);

    // default implementation calls drawVertices
    virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
                           const SkPoint texCoords[4], sk_sp<SkBlender>, const SkPaint& paint);

    // default implementation calls drawVertices
    virtual void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count,
                           sk_sp<SkBlender>, const SkPaint&);

    virtual void drawAnnotation(const SkRect&, const char[], SkData*) {}

    // Default impl always calls drawRect() with a solid-color paint, setting it to anti-aliased
    // only when all edge flags are set. If there's a clip region, it draws that using drawPath,
    // or uses clipPath().
    virtual void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
                                SkCanvas::QuadAAFlags aaFlags, const SkColor4f& color,
                                SkBlendMode mode);
    // Default impl uses drawImageRect per entry, being anti-aliased only when an entry's edge flags
    // are all set. If there's a clip region, it will be applied using clipPath().
    virtual void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count,
                                    const SkPoint dstClips[], const SkMatrix preViewMatrices[],
                                    const SkSamplingOptions&, const SkPaint&,
                                    SkCanvas::SrcRectConstraint);

    virtual void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*);

    // Only called with glyphRunLists that do not contain RSXForm.
    virtual void onDrawGlyphRunList(SkCanvas*,
                                    const sktext::GlyphRunList&,
                                    const SkPaint& initialPaint,
                                    const SkPaint& drawingPaint) = 0;

    // Slug handling routines.
#if (SK_SUPPORT_GPU || defined(SK_GRAPHITE_ENABLED))
    virtual sk_sp<sktext::gpu::Slug> convertGlyphRunListToSlug(
            const sktext::GlyphRunList& glyphRunList,
            const SkPaint& initialPaint,
            const SkPaint& drawingPaint);
    virtual void drawSlug(SkCanvas*, const sktext::gpu::Slug* slug, const SkPaint& drawingPaint);
#endif

    /**
     * The SkDevice passed will be an SkDevice which was returned by a call to
     * onCreateDevice on this device with kNeverTile_TileExpectation.
     *
     * The default implementation calls snapSpecial() and drawSpecial() with the relative transform
     * from the input device to this device. The provided SkPaint cannot have a mask filter or
     * image filter, and any shader is ignored.
     */
    virtual void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&);

    /**
     * Draw the special image's subset to this device, subject to the given matrix transform instead
     * of the device's current local to device matrix.
     */
    virtual void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice,
                             const SkSamplingOptions&, const SkPaint&);

    /**
     * Evaluate 'filter' and draw the final output into this device using 'paint'. The 'mapping'
     * defines the parameter-to-layer space transform used to evaluate the image filter on 'src',
     * and the layer-to-device space transform that is used to draw the result into this device.
     * Since 'mapping' fully specifies the transform, this draw function ignores the current
     * local-to-device matrix (i.e. just like drawSpecial and drawDevice).
     *
     * The final paint must not have an image filter or mask filter set on it; a shader is ignored.
     * The provided color type will be used for any intermediate surfaces that need to be created as
     * part of filter evaluation. It does not have to be src's color type or this Device's type.
     */
    void drawFilteredImage(const skif::Mapping& mapping, SkSpecialImage* src, SkColorType ct,
                           const SkImageFilter*, const SkSamplingOptions&, const SkPaint&);

    virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
    virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);

    virtual void setImmutable() {}

    bool readPixels(const SkPixmap&, int x, int y);

    virtual sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&);
    virtual bool onPeekPixels(SkPixmap*) { return false; }

    /**
     *  The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
     *  image at the specified x,y offset will fit within the device's bounds.
     *
     *  This is explicitly asserted in readPixels(), the public way to call this.
     */
    virtual bool onReadPixels(const SkPixmap&, int x, int y);

    /**
     *  The caller is responsible for "pre-clipping" the src. The impl can assume that the src
     *  image at the specified x,y offset will fit within the device's bounds.
     *
     *  This is explicitly asserted in writePixelsDirect(), the public way to call this.
     */
    virtual bool onWritePixels(const SkPixmap&, int x, int y);

    virtual bool onAccessPixels(SkPixmap*) { return false; }

    struct CreateInfo {
        CreateInfo(const SkImageInfo& info,
                   SkPixelGeometry geo,
                   TileUsage tileUsage,
                   SkRasterHandleAllocator* allocator)
            : fInfo(info)
            , fTileUsage(tileUsage)
            , fPixelGeometry(geo)
            , fAllocator(allocator)
        {}

        const SkImageInfo        fInfo;
        const TileUsage          fTileUsage;
        const SkPixelGeometry    fPixelGeometry;
        SkRasterHandleAllocator* fAllocator = nullptr;
    };

    /**
     *  Create a new device based on CreateInfo. If the paint is not null, then it represents a
     *  preview of how the new device will be composed with its creator device (this).
     *
     *  The subclass may be handed this device in drawDevice(), so it must always return
     *  a device that it knows how to draw, and that it knows how to identify if it is not of the
     *  same subclass (since drawDevice is passed a SkBaseDevice*). If the subclass cannot fulfill
     *  that contract (e.g. PDF cannot support some settings on the paint) it should return NULL,
     *  and the caller may then decide to explicitly create a bitmapdevice, knowing that later
     *  it could not call drawDevice with it (but it could call drawSprite or drawBitmap).
     */
    virtual SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) {
        return nullptr;
    }

    // SkCanvas uses NoPixelsDevice when onCreateDevice fails; but then it needs to be able to
    // inspect a layer's device to know if calling drawDevice() later is allowed.
    virtual bool isNoPixelsDevice() const { return false; }

    // Returns whether or not localToDevice() has changed since the last call to this function.
    bool checkLocalToDeviceDirty() {
        bool wasDirty = fLocalToDeviceDirty;
        fLocalToDeviceDirty = false;
        return wasDirty;
    }

private:
    friend class SkAndroidFrameworkUtils;
    friend class SkCanvas;
    friend class SkDraw;
    friend class SkSurface_Raster;
    friend class DeviceTestingAccess;

    void simplifyGlyphRunRSXFormAndRedraw(SkCanvas*,
                                          const sktext::GlyphRunList&,
                                          const SkPaint& initialPaint,
                                          const SkPaint& drawingPaint);

    // used to change the backend's pixels (and possibly config/rowbytes)
    // but cannot change the width/height, so there should be no change to
    // any clip information.
    // TODO: move to SkBitmapDevice
    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {}

    virtual bool forceConservativeRasterClip() const { return false; }

    // Configure the device's coordinate spaces, specifying both how its device image maps back to
    // the global space (via 'deviceToGlobal') and the initial CTM of the device (via
    // 'localToDevice', i.e. what geometry drawn into this device will be transformed with).
    //
    // (bufferOriginX, bufferOriginY) defines where the (0,0) pixel the device's backing buffer
    // is anchored in the device space. The final device-to-global matrix stored by the SkDevice
    // will include a pre-translation by T(deviceOriginX, deviceOriginY), and the final
    // local-to-device matrix will have a post-translation of T(-deviceOriginX, -deviceOriginY).
    void setDeviceCoordinateSystem(const SkM44& deviceToGlobal,
                                   const SkM44& globalToDevice,
                                   const SkM44& localToDevice,
                                   int bufferOriginX,
                                   int bufferOriginY);
    // Convenience to configure the device to be axis-aligned with the root canvas, but with a
    // unique origin.
    void setOrigin(const SkM44& globalCTM, int x, int y) {
        this->setDeviceCoordinateSystem(SkM44(), SkM44(), globalCTM, x, y);
    }

    virtual SkImageFilterCache* getImageFilterCache() { return nullptr; }

    friend class SkNoPixelsDevice;
    friend class SkBitmapDevice;
    void privateResize(int w, int h) {
        *const_cast<SkImageInfo*>(&fInfo) = fInfo.makeWH(w, h);
    }

    const SkImageInfo    fInfo;
    const SkSurfaceProps fSurfaceProps;
    // fDeviceToGlobal and fGlobalToDevice are inverses of each other; there are never that many
    // SkDevices, so pay the memory cost to avoid recalculating the inverse.
    SkM44 fDeviceToGlobal;
    SkM44 fGlobalToDevice;

    // fLocalToDevice (inherited from SkMatrixProvider) is the device CTM, not the global CTM
    // It maps from local space to the device's coordinate space.
    // fDeviceToGlobal * fLocalToDevice will match the canvas' CTM.
    //
    // setGlobalCTM and setLocalToDevice are intentionally not virtual for performance reasons.
    // However, track a dirty bit for subclasses that want to defer local-to-device dependent
    // calculations until needed for a clip or draw.
    bool fLocalToDeviceDirty = true;

    using INHERITED = SkRefCnt;
};

class SkNoPixelsDevice : public SkBaseDevice {
public:
    SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props);
    SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props,
                     sk_sp<SkColorSpace> colorSpace);

    void resetForNextPicture(const SkIRect& bounds) {
        //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
        this->privateResize(bounds.width(), bounds.height());
        this->setOrigin(SkM44(), bounds.left(), bounds.top());
        this->resetClipStack();
    }

protected:
    // SkNoPixelsDevice tracks the clip conservatively in order to respond to some queries as
    // accurately as possible while emphasizing performance
    void onSave() override;
    void onRestore() override;
    void onClipRect(const SkRect& rect, SkClipOp op, bool aa) override;
    void onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) override;
    void onClipPath(const SkPath& path, SkClipOp op, bool aa) override;
    void onClipRegion(const SkRegion& globalRgn, SkClipOp op) override;
    void onClipShader(sk_sp<SkShader> shader) override;
    void onReplaceClip(const SkIRect& rect) override;
    bool onClipIsAA() const override { return this->clip().fIsAA; }
    bool onClipIsWideOpen() const override {
        return this->clip().fIsRect &&
               this->onDevClipBounds() == this->bounds();
    }
    void onAsRgnClip(SkRegion* rgn) const override {
        rgn->setRect(this->onDevClipBounds());
    }
    ClipType onGetClipType() const override;
    SkIRect onDevClipBounds() const override { return this->clip().fClipBounds; }

    void drawPaint(const SkPaint& paint) override {}
    void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&) override {}
    void drawImageRect(const SkImage*, const SkRect*, const SkRect&,
                       const SkSamplingOptions&, const SkPaint&,
                       SkCanvas::SrcRectConstraint) override {}
    void drawRect(const SkRect&, const SkPaint&) override {}
    void drawOval(const SkRect&, const SkPaint&) override {}
    void drawRRect(const SkRRect&, const SkPaint&) override {}
    void drawPath(const SkPath&, const SkPaint&, bool) override {}
    void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override {}
    void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override {}
#ifdef SK_ENABLE_SKSL
    void drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override {}
#endif

#if SK_SUPPORT_GPU
    void drawSlug(SkCanvas*, const sktext::gpu::Slug*, const SkPaint&) override {}
#endif

    void onDrawGlyphRunList(
            SkCanvas*, const sktext::GlyphRunList&, const SkPaint&, const SkPaint&) override {}

    bool isNoPixelsDevice() const override { return true; }

private:
    struct ClipState {
        SkIRect fClipBounds;
        int fDeferredSaveCount;
        bool fIsAA;
        bool fIsRect;

        ClipState(const SkIRect& bounds, bool isAA, bool isRect)
                : fClipBounds(bounds)
                , fDeferredSaveCount(0)
                , fIsAA(isAA)
                , fIsRect(isRect) {}

        void op(SkClipOp op, const SkM44& transform, const SkRect& bounds,
                bool isAA, bool fillsBounds);
    };

    const ClipState& clip() const { return fClipStack.back(); }
    ClipState& writableClip();

    void resetClipStack() {
        fClipStack.clear();
        fClipStack.emplace_back(this->bounds(), /*isAA=*/false, /*isRect=*/true);
    }

    SkSTArray<4, ClipState> fClipStack;

    using INHERITED = SkBaseDevice;
};

class SkAutoDeviceTransformRestore : SkNoncopyable {
public:
    SkAutoDeviceTransformRestore(SkBaseDevice* device, const SkMatrix& localToDevice)
        : fDevice(device)
        , fPrevLocalToDevice(device->localToDevice())
    {
        fDevice->setLocalToDevice(SkM44(localToDevice));
    }
    ~SkAutoDeviceTransformRestore() {
        fDevice->setLocalToDevice(fPrevLocalToDevice);
    }

private:
    SkBaseDevice* fDevice;
    const SkM44   fPrevLocalToDevice;
};

#endif
