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