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