aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/SkGpuDevice.h
blob: c712ca9b4c3a24f1f5aa715a3fbd822a1c43c87c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

/*
 * Copyright 2010 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkGpuDevice_DEFINED
#define SkGpuDevice_DEFINED

#include "SkGr.h"
#include "SkBitmap.h"
#include "SkDevice.h"
#include "SkPicture.h"
#include "SkRegion.h"
#include "SkSurface.h"
#include "GrContext.h"
#include "GrSurfacePriv.h"

struct SkDrawProcs;
struct GrSkDrawProcs;

class GrAccelData;
struct GrCachedLayer;
class GrTextContext;

/**
 *  Subclass of SkBaseDevice, which directs all drawing to the GrGpu owned by the
 *  canvas.
 */
class SK_API SkGpuDevice : public SkBaseDevice {
public:
    enum Flags {
        kNeedClear_Flag = 1 << 0,  //!< Surface requires an initial clear
    };

    /**
     * Creates an SkGpuDevice from a GrRenderTarget.
     */
    static SkGpuDevice* Create(GrRenderTarget* target, const SkSurfaceProps*, unsigned flags = 0);

    /**
     * New device that will create an offscreen renderTarget based on the ImageInfo and
     * sampleCount. The Budgeted param controls whether the device's backing store counts against
     * the resource cache budget. On failure, returns NULL.
     */
    static SkGpuDevice* Create(GrContext*, SkSurface::Budgeted, const SkImageInfo&,
                               int sampleCount, const SkSurfaceProps*, unsigned flags = 0);

    virtual ~SkGpuDevice();

    SkGpuDevice* cloneDevice(const SkSurfaceProps& props) {
        SkBaseDevice* dev = this->onCreateDevice(CreateInfo(this->imageInfo(), kPossible_TileUsage,
                                                            props.pixelGeometry()),
                                                 NULL);
        return static_cast<SkGpuDevice*>(dev);
    }

    GrContext* context() const { return fContext; }

    // set all pixels to 0
    void clearAll();

    void replaceRenderTarget(bool shouldRetainContent);

    GrRenderTarget* accessRenderTarget() SK_OVERRIDE;

    SkImageInfo imageInfo() const SK_OVERRIDE {
        return fRenderTarget ? fRenderTarget->surfacePriv().info() : SkImageInfo::MakeUnknown();
    }

    const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }

    void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
                            const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
    virtual void drawRect(const SkDraw&, const SkRect& r,
                          const SkPaint& paint) SK_OVERRIDE;
    virtual void drawRRect(const SkDraw&, const SkRRect& r,
                           const SkPaint& paint) SK_OVERRIDE;
    virtual void drawDRRect(const SkDraw& draw, const SkRRect& outer,
                            const SkRRect& inner, const SkPaint& paint) SK_OVERRIDE;
    virtual void drawOval(const SkDraw&, const SkRect& oval,
                          const SkPaint& paint) SK_OVERRIDE;
    virtual void drawPath(const SkDraw&, const SkPath& path,
                          const SkPaint& paint, const SkMatrix* prePathMatrix,
                          bool pathIsMutable) SK_OVERRIDE;
    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
                            const SkMatrix&, const SkPaint&) SK_OVERRIDE;
    virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
                                const SkRect* srcOrNull, const SkRect& dst,
                                const SkPaint& paint,
                                SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE;
    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
                            int x, int y, const SkPaint& paint) SK_OVERRIDE;
    virtual void drawText(const SkDraw&, const void* text, size_t len,
                          SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
                             const SkScalar pos[], int scalarsPerPos,
                             const SkPoint& offset, const SkPaint&) SK_OVERRIDE;
    virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
                              const SkPaint& paint, SkDrawFilter* drawFilter) SK_OVERRIDE;
    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&) SK_OVERRIDE;
    virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
                            const SkPaint&) SK_OVERRIDE;

    void flush() SK_OVERRIDE;

    void onAttachToCanvas(SkCanvas* canvas) SK_OVERRIDE;
    void onDetachFromCanvas() SK_OVERRIDE;

    const SkBitmap& onAccessBitmap() SK_OVERRIDE;

    bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE;
    virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
                             const SkImageFilter::Context&,
                             SkBitmap*, SkIPoint*) SK_OVERRIDE;

    bool filterTexture(GrContext*, GrTexture*, const SkImageFilter*,
                       const SkImageFilter::Context&,
                       SkBitmap* result, SkIPoint* offset);

protected:
    bool onReadPixels(const SkImageInfo&, void*, size_t, int, int) SK_OVERRIDE;
    bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE;
    bool onShouldDisableLCD(const SkPaint&) const SK_OVERRIDE;

    /**  PRIVATE / EXPERIMENTAL -- do not call */
    virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture,
                                          const SkMatrix*, const SkPaint*) SK_OVERRIDE;

private:
    GrContext*                      fContext;
    GrSkDrawProcs*                  fDrawProcs;
    SkAutoTUnref<const SkClipStack> fClipStack;
    SkIPoint                        fClipOrigin;
    GrClip                          fClip;
    GrTextContext*                  fTextContext;
    SkSurfaceProps                  fSurfaceProps;
    GrRenderTarget*                 fRenderTarget;
    // remove when our clients don't rely on accessBitmap()
    SkBitmap                        fLegacyBitmap;
    bool                            fNeedClear;

    SkGpuDevice(GrRenderTarget*, const SkSurfaceProps*, unsigned flags);

    SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) SK_OVERRIDE;

    SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE;

    SkImageFilter::Cache* getImageFilterCache() SK_OVERRIDE;

    bool forceConservativeRasterClip() const SK_OVERRIDE { return true; }

    // sets the render target and clip on context
    void prepareDraw(const SkDraw&);

    /**
     * Implementation for both drawBitmap and drawBitmapRect.
     */
    void drawBitmapCommon(const SkDraw&,
                          const SkBitmap& bitmap,
                          const SkRect* srcRectPtr,
                          const SkSize* dstSizePtr,      // ignored iff srcRectPtr == NULL
                          const SkPaint&,
                          SkCanvas::DrawBitmapRectFlags flags);

    /**
     * Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
     * matrix, clip, and the device's render target has already been set on GrContext.
     */

    // The tileSize and clippedSrcRect will be valid only if true is returned.
    bool shouldTileBitmap(const SkBitmap& bitmap,
                          const SkMatrix& viewMatrix,
                          const GrTextureParams& sampler,
                          const SkRect* srcRectPtr,
                          int maxTileSize,
                          int* tileSize,
                          SkIRect* clippedSrcRect) const;
    void internalDrawBitmap(const SkBitmap&,
                            const SkMatrix& viewMatrix,
                            const SkRect&,
                            const GrTextureParams& params,
                            const SkPaint& paint,
                            SkCanvas::DrawBitmapRectFlags flags,
                            bool bicubic,
                            bool needsTextureDomain);
    void drawTiledBitmap(const SkBitmap& bitmap,
                         const SkMatrix& viewMatrix,
                         const SkRect& srcRect,
                         const SkIRect& clippedSrcRect,
                         const GrTextureParams& params,
                         const SkPaint& paint,
                         SkCanvas::DrawBitmapRectFlags flags,
                         int tileSize,
                         bool bicubic);

    void internalDrawPath(const SkPath& origSrcPath, const SkPaint& paint,
                          const SkMatrix& origViewMatrix, const SkMatrix* prePathMatrix,
                          const SkIRect& clipBounds, bool pathIsMutable);

    bool drawDashLine(const SkPoint pts[2], const SkPaint& paint);

    static SkPicture::AccelData::Key ComputeAccelDataKey();

    static GrRenderTarget* CreateRenderTarget(GrContext*, SkSurface::Budgeted, const SkImageInfo&,
                                              int sampleCount);

    friend class GrTextContext;
    typedef SkBaseDevice INHERITED;
};

#endif