1/*
2 * Copyright 2010 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkGpuDevice_DEFINED
9#define SkGpuDevice_DEFINED
10
11#include "SkGr.h"
12#include "SkBitmap.h"
13#include "SkClipStackDevice.h"
14#include "SkPicture.h"
15#include "SkRegion.h"
16#include "SkSurface.h"
17#include "GrClipStackClip.h"
18#include "GrRenderTargetContext.h"
19#include "GrContext.h"
20#include "GrTypes.h"
21
22class GrAccelData;
23class GrTextureMaker;
24class GrTextureProducer;
25struct GrCachedLayer;
26
27class SkSpecialImage;
28
29/**
30 *  Subclass of SkBaseDevice, which directs all drawing to the GrGpu owned by the
31 *  canvas.
32 */
33class SkGpuDevice : public SkClipStackDevice {
34public:
35    enum InitContents {
36        kClear_InitContents,
37        kUninit_InitContents
38    };
39
40    /**
41     * Creates an SkGpuDevice from a GrRenderTargetContext whose backing width/height is
42     * different than its actual width/height (e.g., approx-match scratch texture).
43     */
44    static sk_sp<SkGpuDevice> Make(GrContext*, sk_sp<GrRenderTargetContext> renderTargetContext,
45                                   int width, int height, InitContents);
46
47    /**
48     * New device that will create an offscreen renderTarget based on the ImageInfo and
49     * sampleCount. The mipMapped flag tells the gpu to create the underlying render target with
50     * mips. The Budgeted param controls whether the device's backing store counts against the
51     * resource cache budget. On failure, returns nullptr.
52     * This entry point creates a kExact backing store. It is used when creating SkGpuDevices
53     * for SkSurfaces.
54     */
55    static sk_sp<SkGpuDevice> Make(GrContext*, SkBudgeted, const SkImageInfo&,
56                                   int sampleCount, GrSurfaceOrigin, const SkSurfaceProps*,
57                                   GrMipMapped mipMapped, InitContents);
58
59    ~SkGpuDevice() override {}
60
61    GrContext* context() const override { return fContext.get(); }
62
63    // set all pixels to 0
64    void clearAll();
65
66    void replaceRenderTargetContext(bool shouldRetainContent);
67
68    GrRenderTargetContext* accessRenderTargetContext() override;
69
70    void drawPaint(const SkPaint& paint) override;
71    void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[],
72                    const SkPaint& paint) override;
73    void drawRect(const SkRect& r, const SkPaint& paint) override;
74    void drawRRect(const SkRRect& r, const SkPaint& paint) override;
75    void drawDRRect(const SkRRect& outer, const SkRRect& inner,
76                    const SkPaint& paint) override;
77    void drawRegion(const SkRegion& r, const SkPaint& paint) override;
78    void drawOval(const SkRect& oval, const SkPaint& paint) override;
79    void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
80                 bool useCenter, const SkPaint& paint) override;
81    void drawPath(const SkPath& path, const SkPaint& paint,
82                  const SkMatrix* prePathMatrix, bool pathIsMutable) override;
83    void drawBitmap(const SkBitmap&, SkScalar x, SkScalar y,
84                    const SkPaint&) override;
85    void drawBitmapRect(const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst,
86                        const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
87    void drawSprite(const SkBitmap& bitmap, int x, int y,
88                    const SkPaint& paint) override;
89    void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
90                  const SkPaint&) override;
91    void drawPosText(const void* text, size_t len, const SkScalar pos[],
92                     int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
93    void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
94                      const SkPaint& paint, SkDrawFilter* drawFilter) override;
95    void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&) override;
96    void drawShadow(const SkPath&, const SkDrawShadowRec&) override;
97    void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
98                   const SkColor[], int count, SkBlendMode, const SkPaint&) override;
99    void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
100
101    void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;
102    void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
103                       const SkPaint&, SkCanvas::SrcRectConstraint) override;
104
105    void drawImageNine(const SkImage* image, const SkIRect& center,
106                       const SkRect& dst, const SkPaint& paint) override;
107    void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
108                        const SkRect& dst, const SkPaint& paint) override;
109
110    void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
111                          const SkRect& dst, const SkPaint&) override;
112    void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
113                           const SkRect& dst, const SkPaint&) override;
114
115    void drawSpecial(SkSpecialImage*, int left, int top, const SkPaint& paint,
116                     SkImage*, const SkMatrix&) override;
117    sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
118    sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
119    sk_sp<SkSpecialImage> snapSpecial() override;
120
121    void flush() override;
122    GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
123                                                   GrBackendSemaphore signalSemaphores[]);
124    bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores);
125
126    bool onAccessPixels(SkPixmap*) override;
127
128protected:
129    bool onReadPixels(const SkPixmap&, int, int) override;
130    bool onWritePixels(const SkPixmap&, int, int) override;
131    bool onShouldDisableLCD(const SkPaint&) const final;
132
133private:
134    // We want these unreffed in RenderTargetContext, GrContext order.
135    sk_sp<GrContext>             fContext;
136    sk_sp<GrRenderTargetContext> fRenderTargetContext;
137
138    SkISize                      fSize;
139    bool                         fOpaque;
140
141    enum Flags {
142        kNeedClear_Flag = 1 << 0,  //!< Surface requires an initial clear
143        kIsOpaque_Flag  = 1 << 1,  //!< Hint from client that rendering to this device will be
144                                   //   opaque even if the config supports alpha.
145    };
146    static bool CheckAlphaTypeAndGetFlags(const SkImageInfo* info, InitContents init,
147                                          unsigned* flags);
148
149    SkGpuDevice(GrContext*, sk_sp<GrRenderTargetContext>, int width, int height, unsigned flags);
150
151    SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
152
153    sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
154
155    SkImageFilterCache* getImageFilterCache() override;
156
157    bool forceConservativeRasterClip() const override { return true; }
158
159    GrClipStackClip clip() const { return GrClipStackClip(&this->cs()); }
160
161    /**
162     * Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
163     * matrix, clip, and the device's render target has already been set on GrContext.
164     */
165
166    // The tileSize and clippedSrcRect will be valid only if true is returned.
167    bool shouldTileImageID(uint32_t imageID,
168                           const SkIRect& imageRect,
169                           const SkMatrix& viewMatrix,
170                           const SkMatrix& srcToDstRectMatrix,
171                           const GrSamplerState& params,
172                           const SkRect* srcRectPtr,
173                           int maxTileSize,
174                           int* tileSize,
175                           SkIRect* clippedSubset) const;
176    // Just returns the predicate, not the out-tileSize or out-clippedSubset, as they are not
177    // needed at the moment.
178    bool shouldTileImage(const SkImage* image, const SkRect* srcRectPtr,
179                         SkCanvas::SrcRectConstraint constraint, SkFilterQuality quality,
180                         const SkMatrix& viewMatrix, const SkMatrix& srcToDstRect) const;
181
182    sk_sp<SkSpecialImage> filterTexture(SkSpecialImage*,
183                                        int left, int top,
184                                        SkIPoint* offset,
185                                        const SkImageFilter* filter);
186
187    // Splits bitmap into tiles of tileSize and draws them using separate textures for each tile.
188    void drawTiledBitmap(const SkBitmap& bitmap,
189                         const SkMatrix& viewMatrix,
190                         const SkMatrix& srcToDstMatrix,
191                         const SkRect& srcRect,
192                         const SkIRect& clippedSrcRect,
193                         const GrSamplerState& params,
194                         const SkPaint& paint,
195                         SkCanvas::SrcRectConstraint,
196                         int tileSize,
197                         bool bicubic);
198
199    // Used by drawTiledBitmap to draw each tile.
200    void drawBitmapTile(const SkBitmap&,
201                        const SkMatrix& viewMatrix,
202                        const SkRect& dstRect,
203                        const SkRect& srcRect,
204                        const GrSamplerState& samplerState,
205                        const SkPaint& paint,
206                        SkCanvas::SrcRectConstraint,
207                        bool bicubic,
208                        bool needsTextureDomain);
209
210    void drawPinnedTextureProxy(sk_sp<GrTextureProxy>,
211                                uint32_t pinnedUniqueID,
212                                SkColorSpace*,
213                                SkAlphaType alphaType,
214                                const SkRect* srcRect,
215                                const SkRect* dstRect,
216                                SkCanvas::SrcRectConstraint,
217                                const SkMatrix& viewMatrix,
218                                const SkPaint&);
219
220    void drawTextureMaker(GrTextureMaker* maker,
221                          int imageW,
222                          int imageH,
223                          const SkRect* srcRect,
224                          const SkRect* dstRect,
225                          SkCanvas::SrcRectConstraint,
226                          const SkMatrix& viewMatrix,
227                          const SkPaint&);
228
229    void drawTextureProducer(GrTextureProducer*,
230                             const SkRect* srcRect,
231                             const SkRect* dstRect,
232                             SkCanvas::SrcRectConstraint,
233                             const SkMatrix& viewMatrix,
234                             const SkPaint&);
235
236    void drawTextureProducerImpl(GrTextureProducer*,
237                                 const SkRect& clippedSrcRect,
238                                 const SkRect& clippedDstRect,
239                                 SkCanvas::SrcRectConstraint,
240                                 const SkMatrix& viewMatrix,
241                                 const SkMatrix& srcToDstMatrix,
242                                 const SkPaint&);
243
244    void drawProducerLattice(GrTextureProducer*, std::unique_ptr<SkLatticeIter>, const SkRect& dst,
245                             const SkPaint&);
246
247    void drawStrokedLine(const SkPoint pts[2], const SkPaint&);
248
249    void wireframeVertices(SkVertices::VertexMode, int vertexCount, const SkPoint verts[],
250                           SkBlendMode, const uint16_t indices[], int indexCount, const SkPaint&);
251
252    static sk_sp<GrRenderTargetContext> MakeRenderTargetContext(GrContext*,
253                                                                SkBudgeted,
254                                                                const SkImageInfo&,
255                                                                int sampleCount,
256                                                                GrSurfaceOrigin,
257                                                                const SkSurfaceProps*,
258                                                                GrMipMapped);
259
260    friend class GrAtlasTextContext;
261    friend class SkSurface_Gpu;      // for access to surfaceProps
262    typedef SkClipStackDevice INHERITED;
263};
264
265#endif
266