1
2/*
3 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10
11#ifndef SkGpuDevice_DEFINED
12#define SkGpuDevice_DEFINED
13
14#include "SkGr.h"
15#include "SkBitmap.h"
16#include "SkDevice.h"
17#include "SkRegion.h"
18#include "GrContext.h"
19
20struct SkDrawProcs;
21struct GrSkDrawProcs;
22class GrTextContext;
23
24/**
25 *  Subclass of SkDevice, which directs all drawing to the GrGpu owned by the
26 *  canvas.
27 */
28class SK_API SkGpuDevice : public SkDevice {
29public:
30    /**
31     *  New device that will create an offscreen renderTarget based on the
32     *  config, width, height.
33     *
34     *  usage is a special flag that should only be set by SkCanvas
35     *  internally.
36     */
37    SkGpuDevice(GrContext*, SkBitmap::Config,
38                int width, int height,
39                SkDevice::Usage usage = SkDevice::kGeneral_Usage);
40
41    /**
42     *  New device that will render to the specified renderTarget.
43     */
44    SkGpuDevice(GrContext*, GrRenderTarget*);
45
46    /**
47     *  New device that will render to the texture (as a rendertarget).
48     *  The GrTexture's asRenderTarget() must be non-NULL or device will not
49     *  function.
50     */
51    SkGpuDevice(GrContext*, GrTexture*);
52
53    virtual ~SkGpuDevice();
54
55    GrContext* context() const { return fContext; }
56
57    /**
58     *  Override from SkGpuDevice, so we can set our FBO to be the render target
59     *  The canvas parameter must be a SkGpuCanvas
60     */
61    virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
62                           const SkClipStack& clipStack) SK_OVERRIDE;
63
64    virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
65
66    // overrides from SkDevice
67
68    virtual void clear(SkColor color) SK_OVERRIDE;
69    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
70                             SkCanvas::Config8888 config8888) SK_OVERRIDE;
71
72    virtual void setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
73                               const SkClipStack&) SK_OVERRIDE;
74
75    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
76    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
77                            const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
78    virtual void drawRect(const SkDraw&, const SkRect& r,
79                          const SkPaint& paint) SK_OVERRIDE;
80    virtual void drawPath(const SkDraw&, const SkPath& path,
81                          const SkPaint& paint, const SkMatrix* prePathMatrix,
82                          bool pathIsMutable) SK_OVERRIDE;
83    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
84                            const SkIRect* srcRectOrNull,
85                            const SkMatrix&, const SkPaint&) SK_OVERRIDE;
86    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
87                            int x, int y, const SkPaint& paint);
88    virtual void drawText(const SkDraw&, const void* text, size_t len,
89                          SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
90    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
91                             const SkScalar pos[], SkScalar constY,
92                             int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
93    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
94                                const SkPath& path, const SkMatrix* matrix,
95                                const SkPaint&) SK_OVERRIDE;
96    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
97                              const SkPoint verts[], const SkPoint texs[],
98                              const SkColor colors[], SkXfermode* xmode,
99                              const uint16_t indices[], int indexCount,
100                              const SkPaint&) SK_OVERRIDE;
101    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
102                            const SkPaint&) SK_OVERRIDE;
103    virtual bool filterTextFlags(const SkPaint&, TextFlags*) SK_OVERRIDE;
104
105    virtual void flush();
106
107    /**
108     * Make's this device's rendertarget current in the underlying 3D API.
109     * Also implicitly flushes.
110     */
111    virtual void makeRenderTargetCurrent();
112
113    virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
114                             const SkMatrix& ctm,
115                             SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
116
117protected:
118    typedef GrContext::TextureCacheEntry TexCache;
119    enum TexType {
120        kBitmap_TexType,
121        kDeviceRenderTarget_TexType,
122        kSaveLayerDeviceRenderTarget_TexType
123    };
124    TexCache lockCachedTexture(const SkBitmap& bitmap,
125                               const GrSamplerState* sampler,
126                               TexType type = kBitmap_TexType);
127    bool isBitmapInTextureCache(const SkBitmap& bitmap,
128                                const GrSamplerState& sampler) const;
129    void unlockCachedTexture(TexCache);
130
131    class SkAutoCachedTexture {
132    public:
133        SkAutoCachedTexture();
134        SkAutoCachedTexture(SkGpuDevice* device,
135                            const SkBitmap& bitmap,
136                            const GrSamplerState* sampler,
137                            GrTexture** texture);
138        ~SkAutoCachedTexture();
139
140        GrTexture* set(SkGpuDevice*, const SkBitmap&, const GrSamplerState*);
141
142    private:
143        SkGpuDevice*    fDevice;
144        TexCache        fTex;
145    };
146    friend class SkAutoTexCache;
147
148    // overrides from SkDevice
149    virtual bool onReadPixels(const SkBitmap& bitmap,
150                              int x, int y,
151                              SkCanvas::Config8888 config8888) SK_OVERRIDE;
152
153
154private:
155    GrContext*      fContext;
156
157    GrSkDrawProcs*  fDrawProcs;
158
159    // state for our offscreen render-target
160    TexCache            fCache;
161    GrTexture*          fTexture;
162    GrRenderTarget*     fRenderTarget;
163    bool                fNeedClear;
164    bool                fNeedPrepareRenderTarget;
165
166    // called from rt and tex cons
167    void initFromRenderTarget(GrContext*, GrRenderTarget*);
168
169    // doesn't set the texture/sampler/matrix state
170    // caller needs to null out GrPaint's texture if
171    // non-textured drawing is desired.
172    // Set constantColor to true if a constant color
173    // will be used.  This is an optimization, and can
174    // always be set to false. constantColor should
175    // never be true if justAlpha is true.
176    bool skPaint2GrPaintNoShader(const SkPaint& skPaint,
177                                 bool justAlpha,
178                                 GrPaint* grPaint,
179                                 bool constantColor);
180
181    // uses the SkShader to setup paint, act used to
182    // hold lock on cached texture and free it when
183    // destroyed.
184    // If there is no shader, constantColor will
185    // be passed to skPaint2GrPaintNoShader.  Otherwise
186    // it is ignored.
187    bool skPaint2GrPaintShader(const SkPaint& skPaint,
188                               SkAutoCachedTexture* act,
189                               const SkMatrix& ctm,
190                               GrPaint* grPaint,
191                               bool constantColor);
192
193    // override from SkDevice
194    virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
195                                               int width, int height,
196                                               bool isOpaque,
197                                               Usage usage);
198
199    SkDrawProcs* initDrawForText(GrTextContext*);
200    bool bindDeviceAsTexture(GrPaint* paint);
201
202    void prepareRenderTarget(const SkDraw&);
203    bool shouldTileBitmap(const SkBitmap& bitmap,
204                          const GrSamplerState& sampler,
205                          const SkIRect* srcRectPtr,
206                          int* tileSize) const;
207    void internalDrawBitmap(const SkDraw&, const SkBitmap&,
208                            const SkIRect&, const SkMatrix&, GrPaint* grPaint);
209
210    typedef SkDevice INHERITED;
211};
212
213#endif
214
215