123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- /*
- * 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/SkCanvas.h"
- #include "include/core/SkColor.h"
- #include "include/core/SkRefCnt.h"
- #include "include/core/SkRegion.h"
- #include "include/core/SkSurfaceProps.h"
- #include "include/private/SkNoncopyable.h"
- class SkBitmap;
- struct SkDrawShadowRec;
- class SkGlyphRun;
- class SkGlyphRunList;
- class SkImageFilterCache;
- struct SkIRect;
- class SkMatrix;
- class SkRasterHandleAllocator;
- class SkSpecialImage;
- class SkBaseDevice : public SkRefCnt {
- 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;
- }
- /**
- * 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);
- const SkIPoint& origin = this->getOrigin();
- bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
- }
- SkIRect getGlobalBounds() const {
- SkIRect bounds;
- this->getGlobalBounds(&bounds);
- return bounds;
- }
- 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 origin: its offset in device coordinates from
- * the default origin in its canvas' matrix/clip
- */
- const SkIPoint& getOrigin() const { return fOrigin; }
- virtual void* getRasterHandle() const { return nullptr; }
- void save() { this->onSave(); }
- void restore(const SkMatrix& ctm) {
- this->onRestore();
- this->setGlobalCTM(ctm);
- }
- 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 clipRegion(const SkRegion& region, SkClipOp op) {
- this->onClipRegion(region, op);
- }
- void androidFramework_setDeviceClipRestriction(SkIRect* mutableClipRestriction) {
- this->onSetDeviceClipRestriction(mutableClipRestriction);
- }
- bool clipIsWideOpen() const;
- const SkMatrix& ctm() const { return fCTM; }
- void setCTM(const SkMatrix& ctm) {
- fCTM = ctm;
- }
- void setGlobalCTM(const SkMatrix& ctm);
- virtual void validateDevBounds(const SkIRect&) {}
- 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 onClipRegion(const SkRegion& deviceRgn, SkClipOp) {}
- virtual void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) {}
- virtual bool onClipIsAA() const = 0;
- virtual void onAsRgnClip(SkRegion*) const = 0;
- enum ClipType {
- kEmpty_ClipType,
- kRect_ClipType,
- kComplex_ClipType
- };
- virtual ClipType onGetClipType() 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 drawSprite(const SkBitmap& bitmap,
- int x, int y, const SkPaint& paint) = 0;
- /**
- * The default impl. will create a bitmap-shader from the bitmap,
- * and call drawRect with it.
- */
- virtual void drawBitmapRect(const SkBitmap&,
- const SkRect* srcOrNull, const SkRect& dst,
- const SkPaint& paint,
- SkCanvas::SrcRectConstraint) = 0;
- virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center,
- const SkRect& dst, const SkPaint&);
- virtual void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
- const SkRect& dst, const SkPaint&);
- virtual void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
- const SkPaint&, SkCanvas::SrcRectConstraint);
- virtual void drawImageNine(const SkImage*, const SkIRect& center,
- const SkRect& dst, const SkPaint&);
- virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
- const SkRect& dst, const SkPaint&);
- virtual void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
- SkBlendMode, const SkPaint&) = 0;
- virtual void drawShadow(const SkPath&, const SkDrawShadowRec&);
- virtual void drawGlyphRunList(const SkGlyphRunList& glyphRunList) = 0;
- // default implementation calls drawVertices
- virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
- const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
- // default implementation calls drawPath
- virtual void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
- const SkColor[], int count, SkBlendMode, 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, SkColor 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 SkPaint& paint, SkCanvas::SrcRectConstraint);
- /** The SkDevice passed will be an SkDevice which was returned by a call to
- onCreateDevice on this device with kNeverTile_TileExpectation.
- */
- virtual void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) = 0;
- void drawGlyphRunRSXform(const SkFont&, const SkGlyphID[], const SkRSXform[], int count,
- SkPoint origin, const SkPaint& paint);
- virtual void drawDrawable(SkDrawable*, const SkMatrix*, SkCanvas*);
- virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&,
- SkImage* clipImage, const SkMatrix& clipMatrix);
- virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
- virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
- virtual sk_sp<SkSpecialImage> snapSpecial();
- virtual void setImmutable() {}
- bool readPixels(const SkPixmap&, int x, int y);
- virtual sk_sp<SkSpecialImage> snapBackImage(const SkIRect&); // default returns null
- ///////////////////////////////////////////////////////////////////////////
- virtual GrContext* context() const { return nullptr; }
- 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 {
- static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry,
- bool preserveLCDText);
- // The constructor may change the pixel geometry based on other parameters.
- CreateInfo(const SkImageInfo& info,
- TileUsage tileUsage,
- SkPixelGeometry geo)
- : fInfo(info)
- , fTileUsage(tileUsage)
- , fPixelGeometry(AdjustGeometry(info, tileUsage, geo, false))
- {}
- CreateInfo(const SkImageInfo& info,
- TileUsage tileUsage,
- SkPixelGeometry geo,
- bool preserveLCDText,
- bool trackCoverage,
- SkRasterHandleAllocator* allocator)
- : fInfo(info)
- , fTileUsage(tileUsage)
- , fPixelGeometry(AdjustGeometry(info, tileUsage, geo, preserveLCDText))
- , fTrackCoverage(trackCoverage)
- , fAllocator(allocator)
- {}
- const SkImageInfo fInfo;
- const TileUsage fTileUsage;
- const SkPixelGeometry fPixelGeometry;
- const bool fTrackCoverage = false;
- 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;
- }
- // A helper function used by derived classes to log the scale factor of a bitmap or image draw.
- static void LogDrawScaleFactor(const SkMatrix& view, const SkMatrix& srcToDst, SkFilterQuality);
- private:
- friend class SkAndroidFrameworkUtils;
- friend class SkCanvas;
- friend struct DeviceCM; //for setMatrixClip
- friend class SkDraw;
- friend class SkDrawIter;
- friend class SkSurface_Raster;
- friend class DeviceTestingAccess;
- // Temporarily friend the SkGlyphRunBuilder until drawPosText is gone.
- friend class SkGlyphRun;
- friend class SkGlyphRunList;
- friend class SkGlyphRunBuilder;
- // 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; }
- /**
- * Don't call this!
- */
- virtual GrRenderTargetContext* accessRenderTargetContext() { return nullptr; }
- // just called by SkCanvas when built as a layer
- void setOrigin(const SkMatrix& ctm, int x, int y);
- /** Causes any deferred drawing to the device to be completed.
- */
- virtual void flush() {}
- 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);
- }
- SkIPoint fOrigin;
- const SkImageInfo fInfo;
- const SkSurfaceProps fSurfaceProps;
- SkMatrix fCTM;
- typedef SkRefCnt INHERITED;
- };
- class SkNoPixelsDevice : public SkBaseDevice {
- public:
- SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props,
- sk_sp<SkColorSpace> colorSpace = nullptr)
- : SkBaseDevice(SkImageInfo::Make(bounds.width(), bounds.height(), kUnknown_SkColorType,
- kUnknown_SkAlphaType, std::move(colorSpace)), props)
- {
- // this fails if we enable this assert: DiscardableImageMapTest.GetDiscardableImagesInRectMaxImage
- //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
- }
- void resetForNextPicture(const SkIRect& bounds) {
- //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
- this->privateResize(bounds.width(), bounds.height());
- }
- protected:
- // We don't track the clip at all (for performance), but we have to respond to some queries.
- // We pretend to be wide-open. We could pretend to always be empty, but that *seems* worse.
- void onSave() override {}
- void onRestore() override {}
- void onClipRect(const SkRect& rect, SkClipOp, bool aa) override {}
- void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override {}
- void onClipPath(const SkPath& path, SkClipOp, bool aa) override {}
- void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override {}
- void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override {}
- bool onClipIsAA() const override { return false; }
- void onAsRgnClip(SkRegion* rgn) const override {
- rgn->setRect(SkIRect::MakeWH(this->width(), this->height()));
- }
- ClipType onGetClipType() const override {
- return kRect_ClipType;
- }
- void drawPaint(const SkPaint& paint) override {}
- void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&) 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 drawSprite(const SkBitmap&, int, int, const SkPaint&) override {}
- void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint&,
- SkCanvas::SrcRectConstraint) override {}
- void drawDevice(SkBaseDevice*, int, int, const SkPaint&) override {}
- void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override {}
- void drawVertices(const SkVertices*, const SkVertices::Bone[], int, SkBlendMode,
- const SkPaint&) override {}
- private:
- typedef SkBaseDevice INHERITED;
- };
- class SkAutoDeviceCTMRestore : SkNoncopyable {
- public:
- SkAutoDeviceCTMRestore(SkBaseDevice* device, const SkMatrix& ctm)
- : fDevice(device)
- , fPrevCTM(device->ctm())
- {
- fDevice->setCTM(ctm);
- }
- ~SkAutoDeviceCTMRestore() {
- fDevice->setCTM(fPrevCTM);
- }
- private:
- SkBaseDevice* fDevice;
- const SkMatrix fPrevCTM;
- };
- #endif
|