| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkDeferredCanvas_DEFINED |
| #define SkDeferredCanvas_DEFINED |
| |
| #include "SkCanvas.h" |
| #include "SkDevice.h" |
| #include "SkPicture.h" |
| #include "SkPixelRef.h" |
| |
| /** \class SkDeferredCanvas |
| Subclass of SkCanvas that encapsulates an SkPicture for deferred drawing. |
| The main difference between this class and SkPictureRecord (the canvas |
| provided by SkPicture) is that this is a full drop-in replacement for |
| SkCanvas, while SkPictureRecord only supports draw operations. |
| SkDeferredCanvas will transparently trigger the flushing of deferred |
| draw operations when an attempt is made to access the pixel data. |
| */ |
| class SK_API SkDeferredCanvas : public SkCanvas { |
| public: |
| class DeviceContext; |
| |
| SkDeferredCanvas(); |
| |
| /** Construct a canvas with the specified device to draw into. |
| Equivalent to calling default constructor, then setDevice. |
| @param device Specifies a device for the canvas to draw into. |
| */ |
| explicit SkDeferredCanvas(SkDevice* device); |
| |
| /** Construct a canvas with the specified device to draw into, and |
| * a device context. Equivalent to calling default constructor, then |
| * setDevice. |
| * @param device Specifies a device for the canvas to draw into. |
| * @param deviceContext interface for the device's the graphics context |
| */ |
| explicit SkDeferredCanvas(SkDevice* device, DeviceContext* deviceContext); |
| |
| virtual ~SkDeferredCanvas(); |
| |
| /** |
| * Specify a device to be used by this canvas. Calling setDevice will |
| * release the previously set device, if any. |
| * |
| * @param device The device that the canvas will raw into |
| * @return The device argument, for convenience. |
| */ |
| virtual SkDevice* setDevice(SkDevice* device); |
| |
| /** |
| * Specify a deviceContext to be used by this canvas. Calling |
| * setDeviceContext will release the previously set deviceContext, if any. |
| * A deviceContext must be specified if the device uses a graphics context |
| * that requires some form of state initialization prior to drawing |
| * and/or explicit flushing to synchronize the execution of rendering |
| * operations. |
| * Note: Must be called after the device is set with setDevice. |
| * |
| * @deviceContext interface for the device's the graphics context |
| * @return The deviceContext argument, for convenience. |
| */ |
| DeviceContext* setDeviceContext(DeviceContext* deviceContext); |
| |
| /** |
| * Enable or disable deferred drawing. When deferral is disabled, |
| * pending draw operations are immediately flushed and from then on, |
| * the SkDeferredCanvas behaves just like a regular SkCanvas. |
| * This method must not be called while the save/restore stack is in use. |
| * @param deferred true/false |
| */ |
| void setDeferredDrawing(bool deferred); |
| |
| // Overrides of the SkCanvas interface |
| virtual int save(SaveFlags flags) SK_OVERRIDE; |
| virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, |
| SaveFlags flags) SK_OVERRIDE; |
| virtual void restore() SK_OVERRIDE; |
| virtual bool isDrawingToLayer() const SK_OVERRIDE; |
| virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; |
| virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; |
| virtual bool rotate(SkScalar degrees) SK_OVERRIDE; |
| virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; |
| virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; |
| virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; |
| virtual bool clipRect(const SkRect& rect, SkRegion::Op op, |
| bool doAntiAlias) SK_OVERRIDE; |
| virtual bool clipPath(const SkPath& path, SkRegion::Op op, |
| bool doAntiAlias) SK_OVERRIDE; |
| virtual bool clipRegion(const SkRegion& deviceRgn, |
| SkRegion::Op op) SK_OVERRIDE; |
| virtual void clear(SkColor) SK_OVERRIDE; |
| virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; |
| virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], |
| const SkPaint& paint) SK_OVERRIDE; |
| virtual void drawRect(const SkRect& rect, const SkPaint& paint) |
| SK_OVERRIDE; |
| virtual void drawPath(const SkPath& path, const SkPaint& paint) |
| SK_OVERRIDE; |
| virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, |
| SkScalar top, const SkPaint* paint) |
| SK_OVERRIDE; |
| virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, |
| const SkRect& dst, const SkPaint* paint) |
| SK_OVERRIDE; |
| |
| virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, |
| const SkPaint* paint) SK_OVERRIDE; |
| virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, |
| const SkRect& dst, const SkPaint* paint) |
| SK_OVERRIDE; |
| virtual void drawSprite(const SkBitmap& bitmap, int left, int top, |
| const SkPaint* paint) SK_OVERRIDE; |
| virtual void drawText(const void* text, size_t byteLength, SkScalar x, |
| SkScalar y, const SkPaint& paint) SK_OVERRIDE; |
| virtual void drawPosText(const void* text, size_t byteLength, |
| const SkPoint pos[], const SkPaint& paint) |
| SK_OVERRIDE; |
| virtual void drawPosTextH(const void* text, size_t byteLength, |
| const SkScalar xpos[], SkScalar constY, |
| const SkPaint& paint) SK_OVERRIDE; |
| virtual void drawTextOnPath(const void* text, size_t byteLength, |
| const SkPath& path, const SkMatrix* matrix, |
| const SkPaint& paint) SK_OVERRIDE; |
| virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; |
| virtual void drawVertices(VertexMode vmode, int vertexCount, |
| const SkPoint vertices[], const SkPoint texs[], |
| const SkColor colors[], SkXfermode* xmode, |
| const uint16_t indices[], int indexCount, |
| const SkPaint& paint) SK_OVERRIDE; |
| virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE; |
| virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; |
| |
| private: |
| void flushIfNeeded(const SkBitmap& bitmap); |
| |
| public: |
| class DeviceContext : public SkRefCnt { |
| public: |
| virtual void prepareForDraw() {} |
| }; |
| |
| public: |
| class DeferredDevice : public SkDevice { |
| public: |
| /** |
| * Constructor |
| * @param immediateDevice device to be drawn to when flushing |
| * deferred operations |
| * @param deviceContext callback interface for managing graphics |
| * context state, can be NULL. |
| */ |
| DeferredDevice(SkDevice* immediateDevice, |
| DeviceContext* deviceContext = NULL); |
| ~DeferredDevice(); |
| |
| /** |
| * Sets the device context to be use with the device. |
| * @param deviceContext callback interface for managing graphics |
| * context state, can be NULL. |
| */ |
| void setDeviceContext(DeviceContext* deviceContext); |
| |
| /** |
| * Returns the recording canvas. |
| */ |
| SkCanvas* recordingCanvas() const {return fRecordingCanvas;} |
| |
| /** |
| * Returns the immediate (non deferred) canvas. |
| */ |
| SkCanvas* immediateCanvas() const {return fImmediateCanvas;} |
| |
| /** |
| * Returns the immediate (non deferred) device. |
| */ |
| SkDevice* immediateDevice() const {return fImmediateDevice;} |
| |
| /** |
| * Returns true if an opaque draw operation covering the entire canvas |
| * was performed since the last call to isFreshFrame(). |
| */ |
| bool isFreshFrame(); |
| |
| void flushPending(); |
| void contentsCleared(); |
| void flushIfNeeded(const SkBitmap& bitmap); |
| |
| virtual uint32_t getDeviceCapabilities() SK_OVERRIDE; |
| virtual int width() const SK_OVERRIDE; |
| virtual int height() const SK_OVERRIDE; |
| virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE; |
| |
| virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, |
| int width, int height, |
| bool isOpaque, |
| Usage usage) SK_OVERRIDE; |
| |
| virtual void writePixels(const SkBitmap& bitmap, int x, int y, |
| SkCanvas::Config8888 config8888) SK_OVERRIDE; |
| |
| protected: |
| virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE; |
| virtual bool onReadPixels(const SkBitmap& bitmap, |
| int x, int y, |
| SkCanvas::Config8888 config8888) SK_OVERRIDE; |
| |
| // The following methods are no-ops on a deferred device |
| virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) |
| SK_OVERRIDE |
| {return false;} |
| virtual void setMatrixClip(const SkMatrix&, const SkRegion&, |
| const SkClipStack&) SK_OVERRIDE |
| {} |
| virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&, |
| const SkClipStack&) SK_OVERRIDE |
| {} |
| |
| // None of the following drawing methods should ever get called on the |
| // deferred device |
| virtual void clear(SkColor color) |
| {SkASSERT(0);} |
| virtual void drawPaint(const SkDraw&, const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, |
| size_t count, const SkPoint[], |
| const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawRect(const SkDraw&, const SkRect& r, |
| const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawPath(const SkDraw&, const SkPath& path, |
| const SkPaint& paint, |
| const SkMatrix* prePathMatrix = NULL, |
| bool pathIsMutable = false) |
| {SkASSERT(0);} |
| virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, |
| const SkIRect* srcRectOrNull, |
| const SkMatrix& matrix, const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, |
| int x, int y, const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawText(const SkDraw&, const void* text, size_t len, |
| SkScalar x, SkScalar y, const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawPosText(const SkDraw&, const void* text, size_t len, |
| const SkScalar pos[], SkScalar constY, |
| int scalarsPerPos, const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawTextOnPath(const SkDraw&, const void* text, |
| size_t len, const SkPath& path, |
| const SkMatrix* matrix, |
| const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, |
| size_t len, const SkPoint pos[], |
| const SkPaint& paint, |
| const SkPath& path, |
| const SkMatrix* matrix) |
| {SkASSERT(0);} |
| virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, |
| int vertexCount, const SkPoint verts[], |
| const SkPoint texs[], const SkColor colors[], |
| SkXfermode* xmode, const uint16_t indices[], |
| int indexCount, const SkPaint& paint) |
| {SkASSERT(0);} |
| virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, |
| const SkPaint&) |
| {SkASSERT(0);} |
| private: |
| virtual void flush(); |
| |
| SkPicture fPicture; |
| SkDevice* fImmediateDevice; |
| SkCanvas* fImmediateCanvas; |
| SkCanvas* fRecordingCanvas; |
| DeviceContext* fDeviceContext; |
| bool fFreshFrame; |
| }; |
| |
| DeferredDevice* getDeferredDevice() const; |
| |
| protected: |
| virtual SkCanvas* canvasForDrawIter(); |
| |
| private: |
| bool isFullFrame(const SkRect*, const SkPaint*) const; |
| void validate() const; |
| void init(); |
| SkCanvas* fDrawingCanvas; // This points to the recording or immediate |
| // canvas, based on fDeferredDrawing |
| bool fDeferredDrawing; |
| |
| typedef SkCanvas INHERITED; |
| }; |
| |
| |
| #endif |