/*
 * 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"  // IWYU pragma: keep
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkSurfaceProps.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkNoncopyable.h"
#include "include/private/base/SkTArray.h"
#include "src/core/SkMatrixPriv.h"
#include "src/shaders/SkShaderBase.h"

#include <cstddef>
#include <cstdint>
#include <utility>

struct SkArc;
class SkBitmap;
class SkColorSpace;
class SkMesh;
struct SkDrawShadowRec;
class SkImageFilter;
class SkRasterHandleAllocator;
class SkSpecialImage;
class GrRecordingContext;
class SkData;
class SkDrawable;
class SkImage;
class SkPaint;
class SkPath;
class SkPixmap;
class SkRRect;
class SkSurface;
class SkVertices;
enum SkColorType : int;
enum class SkBlendMode;
enum class SkScalerContextFlags : uint32_t;
struct SkRSXform;

namespace sktext {
class GlyphRunList;
}

namespace skif {
class Backend;
class Mapping;
}
namespace skgpu::ganesh {
class Device;
}
namespace skgpu::graphite {
class Device;
class Recorder;
}
namespace sktext::gpu {
class SubRunControl;
class Slug;
}

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

/**
 * SkDevice is the internal API and implementation that SkCanvas will use to perform rendering and
 * implement the saveLayer abstraction. A device wraps some pixel allocation (for non-document based
 * devices) or wraps some other container that stores rendering operations. The drawing operations
 * perform equivalently to their corresponding functions in SkCanvas except that the canvas is
 * responsible for all SkImageFilters. An image filter is applied by automatically creating a layer,
 * drawing the filter-less paint into the layer, and then evaluating the filter on the layer's
 * image.
 *
 * Each layer in an SkCanvas stack is represented by an SkDevice instance that was created by the
 * parent SkDevice (up to the canvas's base device). In most cases these devices will be pixel
 * aligned with one another but may differ in size based on the known extent of the active clip. In
 * complex image filtering scenarios, they may not be axis aligned, although the effective pixel
 * size should remain approximately equal across all devices in a canvas.
 *
 * While SkCanvas manages a single stack of layers and canvas transforms, SkDevice does not have a
 * stack of transforms. Instead, it has a single active transform that is modified as needed by
 * SkCanvas. However, SkDevices are the means by which SkCanvas manages the clip stack because each
 * layer's clip stack starts anew (although the layer's results are then clipped by its parent's
 * stack when it is restored).
 */
class SkDevice : public SkRefCnt {
public:
    SkDevice(const SkImageInfo&, const SkSurfaceProps&);

    // -- Surface properties and metadata

    /**
     *  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; }

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

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

    // NOTE: Image dimensions as a rect, *not* the current restricted clip bounds.
    SkIRect bounds() const { return SkIRect::MakeWH(this->width(), this->height()); }
    SkISize size() const { return this->imageInfo().dimensions(); }

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

    SkScalerContextFlags scalerContextFlags() const;

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

    // -- Direct pixel manipulation

    /**
     *  Write the pixels in 'src' into this Device at the specified x,y offset. The caller is
     *  responsible for "pre-clipping" the src.
     */
    bool writePixels(const SkPixmap& src, int x, int y) { return this->onWritePixels(src, x, y); }

    /**
     *  Read pixels from this Device at the specified x,y offset into dst. The caller is
     *  responsible for "pre-clipping" the dst
     */
    bool readPixels(const SkPixmap& dst, int x, int y) { return this->onReadPixels(dst, x, 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*);


    // -- Device's transform (both current transform affecting draws, and its fixed global mapping)

    /**
     *  Returns the transformation that maps from the local space to the device's coordinate space.
     */
    const SkM44& localToDevice44() const { return fLocalToDevice; }
    const SkMatrix& localToDevice() const { return fLocalToDevice33; }

    /**
     *  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.
     */
    SkM44 getRelativeTransform(const SkDevice&) const;

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

    // -- Device's clip bounds and stack manipulation

    /**
     *  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).
     */
    virtual SkIRect devClipBounds() const = 0;

    virtual void pushClipStack() = 0;
    virtual void popClipStack() = 0;

    virtual void clipRect(const SkRect& rect, SkClipOp op, bool aa) = 0;
    virtual void clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) = 0;
    virtual void clipPath(const SkPath& path, SkClipOp op, bool aa) = 0;
    virtual void clipRegion(const SkRegion& region, SkClipOp op) = 0;

    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));
    }

    virtual void replaceClip(const SkIRect& rect) = 0;

    virtual bool isClipAntiAliased() const = 0;
    virtual bool isClipEmpty() const = 0;
    virtual bool isClipRect() const = 0;
    virtual bool isClipWideOpen() const = 0;

    virtual void android_utils_clipAsRgn(SkRegion*) const = 0;
    virtual bool android_utils_clipWithStencil() { return false; }

    // -- Device reflection

    // TEMPORARY: Whether or not SkCanvas should use an layer and image filters to simulate
    // mask filters and then draw the filtered mask using drawCoverageMask. Unlike regular
    // layers, the color type passed to SkDevice::createDevice() will always be an alpha-only
    // color type. Eventually this will be the only way that mask filters are handled (barring
    // dedicated fast-paths for blurs on [r]rects and text).
    virtual bool useDrawCoverageMaskForMaskFilters() const { return false; }

    // SkCanvas uses NoPixelsDevice when createDevice 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; }

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

    virtual GrRecordingContext* recordingContext() const { return nullptr; }
    virtual skgpu::graphite::Recorder* recorder() const { return nullptr; }

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

    // Marking an SkDevice immutable declares the intent that rendering to the device is
    // complete, allowing it to be sampled as an image without requiring a copy. Drawing
    // operations may not function and may assert if invoked after setImmutable() is called.
    virtual void setImmutable() {}

    virtual sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&);

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

        const SkImageInfo        fInfo;
        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 SkDevice*). 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 sk_sp<SkDevice> createDevice(const CreateInfo&, const SkPaint*) { return nullptr; }

    // -- Drawing routines (called after saveLayers and imagefilter operations are applied)

    // Ensure that non-RSXForm runs are passed to onDrawGlyphRunList.
    void drawGlyphRunList(SkCanvas*,
                          const sktext::GlyphRunList& glyphRunList,
                          const SkPaint& paint);
    // Slug handling routines.
    virtual sk_sp<sktext::gpu::Slug> convertGlyphRunListToSlug(
            const sktext::GlyphRunList& glyphRunList, const SkPaint& paint);
    virtual void drawSlug(SkCanvas*, const sktext::gpu::Slug* slug, const SkPaint& 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 SkArc& arc, 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) = 0;

    virtual void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
                               const SkSamplingOptions&, const SkPaint&,
                               SkCanvas::SrcRectConstraint) = 0;
    // Return true if canvas calls to drawImage or drawImageRect should try to
    // be drawn in a tiled way.
    virtual bool shouldDrawAsTiledImageRect() const { return false; }
    virtual bool drawAsTiledImageRect(SkCanvas*,
                                      const SkImage*,
                                      const SkRect* src,
                                      const SkRect& dst,
                                      const SkSamplingOptions&,
                                      const SkPaint&,
                                      SkCanvas::SrcRectConstraint) { return false; }

    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;
    virtual void drawMesh(const SkMesh& mesh, sk_sp<SkBlender>, const SkPaint&) = 0;
    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*);

    // -- "Special" drawing and image routines

    // 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();

    /**
     * The SkDevice passed will be an SkDevice which was returned by a call to
     * createDevice 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(SkDevice*, 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.
     *
     * If 'constraint' is kFast, the rendered geometry of the image still reflects the extent of
     * the SkSpecialImage's subset, but it's assumed that the pixel data beyond the subset is valid
     * (e.g. SkSpecialImage::makeSubset() was called to crop a larger image).
     */
    virtual void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice,
                             const SkSamplingOptions&, const SkPaint&,
                             SkCanvas::SrcRectConstraint constraint =
                                    SkCanvas::kStrict_SrcRectConstraint);

    /**
     * Draw the special image's subset to this device, treating its alpha channel as coverage for
     * the draw and ignoring any RGB channels that might be present. This will be drawn using the
     * provided matrix transform instead of the device's current local to device matrix.
     *
     * Coverage values beyond the image's subset are treated as 0 (i.e. kDecal tiling). Color values
     * before coverage are determined as normal by the SkPaint, ignoring style, path effects,
     * mask filters and image filters. The local coords of any SkShader on the paint should be
     * relative to the SkDevice's current matrix (i.e. 'maskToDevice' determines how the coverage
     * mask aligns with device-space, but otherwise shading proceeds like other draws).
    */
    virtual void drawCoverageMask(const SkSpecialImage*, const SkMatrix& maskToDevice,
                                  const SkSamplingOptions&, const SkPaint&);

    /**
     * Draw rrect with an optimized path for analytic blurs, if provided by the device.
     */
    virtual bool drawBlurredRRect(const SkRRect&, const SkPaint&, float deviceSigma) {
        return false;
    }

    /**
     * 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&);

protected:
    // DEPRECATED: Can be deleted once SkCanvas::onDrawImage() uses skif::FilterResult so don't
    // bother re-arranging.
    virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
    virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);

    // 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);
    }

    // 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 SkCanvas; // for setOrigin/setDeviceCoordinateSystem
    friend class DeviceTestingAccess;

    // Defaults to a CPU image filtering backend.
    virtual sk_sp<skif::Backend> createImageFilteringBackend(const SkSurfaceProps& surfaceProps,
                                                             SkColorType colorType) const;

    // Implementations can assume that the device from (x,y) to (w,h) will fit within dst.
    virtual bool onReadPixels(const SkPixmap&, int x, int y) { return false; }

    // Implementations can assume that the src image placed at 'x,y' will fit within the device.
    virtual bool onWritePixels(const SkPixmap&, int x, int y) { return false; }

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

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

    virtual void onClipShader(sk_sp<SkShader>) = 0;

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

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

    const SkImageInfo    fInfo;
    const SkSurfaceProps fSurfaceProps;
    SkM44 fLocalToDevice;
    // 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 but as a 3x3.
    SkMatrix fLocalToDevice33;

    // fLocalToDevice 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;
};

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

    // Returns false if the device could not be reset; this should only be called on a root device.
    bool resetForNextPicture(const SkIRect& bounds);

    // SkNoPixelsDevice tracks the clip conservatively in order to respond to some queries as
    // accurately as possible while emphasizing performance
    void pushClipStack() override;
    void popClipStack() override;
    void clipRect(const SkRect& rect, SkClipOp op, bool aa) override;
    void clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) override;
    void clipPath(const SkPath& path, SkClipOp op, bool aa) override;
    void clipRegion(const SkRegion& globalRgn, SkClipOp op) override;
    void replaceClip(const SkIRect& rect) override;
    bool isClipAntiAliased() const override { return this->clip().fIsAA; }
    bool isClipEmpty() const override { return this->devClipBounds().isEmpty(); }
    bool isClipRect() const override { return this->clip().fIsRect && !this->isClipEmpty(); }
    bool isClipWideOpen() const override {
        return this->clip().fIsRect &&
               this->devClipBounds() == this->bounds();
    }
    void android_utils_clipAsRgn(SkRegion* rgn) const override {
        rgn->setRect(this->devClipBounds());
    }
    SkIRect devClipBounds() const override { return this->clip().fClipBounds; }

protected:

    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(SkDevice*, const SkSamplingOptions&, const SkPaint&) override {}
    void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override {}
    void drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override {}

    void drawSlug(SkCanvas*, const sktext::gpu::Slug*, const SkPaint&) override {}
    void onDrawGlyphRunList(SkCanvas*, const sktext::GlyphRunList&, 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);
    };

    void onClipShader(sk_sp<SkShader> shader) override;

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

    skia_private::STArray<4, ClipState> fClipStack;
};

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

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

#endif
