• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 GrContext_DEFINED
9 #define GrContext_DEFINED
10 
11 #include "GrCaps.h"
12 #include "GrColor.h"
13 #include "SkMatrix.h"
14 #include "SkPathEffect.h"
15 #include "SkTypes.h"
16 #include "../private/GrAuditTrail.h"
17 #include "../private/GrSingleOwner.h"
18 
19 class GrAtlasGlyphCache;
20 struct GrContextOptions;
21 class GrContextPriv;
22 class GrContextThreadSafeProxy;
23 class GrDrawingManager;
24 struct GrDrawOpAtlasConfig;
25 class GrRenderTargetContext;
26 class GrFragmentProcessor;
27 class GrGpu;
28 class GrIndexBuffer;
29 class GrOvalRenderer;
30 class GrPath;
31 class GrResourceEntry;
32 class GrResourceCache;
33 class GrResourceProvider;
34 class GrSamplerParams;
35 class GrSurfaceProxy;
36 class GrTextBlobCache;
37 class GrTextContext;
38 class GrTextureProxy;
39 class GrVertexBuffer;
40 class GrSwizzle;
41 class SkTraceMemoryDump;
42 
43 class SkImage;
44 class SkSurfaceProps;
45 
46 class SK_API GrContext : public SkRefCnt {
47 public:
48     /**
49      * Creates a GrContext for a backend context.
50      */
51     static GrContext* Create(GrBackend, GrBackendContext, const GrContextOptions& options);
52     static GrContext* Create(GrBackend, GrBackendContext);
53 
54 #ifdef SK_METAL
55     /**
56      * Makes a GrContext which uses Metal as the backend. The device parameter is an MTLDevice
57      * and queue is an MTLCommandQueue which should be used by the backend. These objects must
58      * have a ref on them which can be transferred to Ganesh which will release the ref when the
59      * GrContext is destroyed.
60      */
61     static sk_sp<GrContext> MakeMetal(void* device, void* queue, const GrContextOptions& options);
62 #endif
63 
64     virtual ~GrContext();
65 
66     sk_sp<GrContextThreadSafeProxy> threadSafeProxy();
67 
68     /**
69      * The GrContext normally assumes that no outsider is setting state
70      * within the underlying 3D API's context/device/whatever. This call informs
71      * the context that the state was modified and it should resend. Shouldn't
72      * be called frequently for good performance.
73      * The flag bits, state, is dpendent on which backend is used by the
74      * context, either GL or D3D (possible in future).
75      */
76     void resetContext(uint32_t state = kAll_GrBackendState);
77 
78     /**
79      * Callback function to allow classes to cleanup on GrContext destruction.
80      * The 'info' field is filled in with the 'info' passed to addCleanUp.
81      */
82     typedef void (*PFCleanUpFunc)(const GrContext* context, void* info);
83 
84     /**
85      * Add a function to be called from within GrContext's destructor.
86      * This gives classes a chance to free resources held on a per context basis.
87      * The 'info' parameter will be stored and passed to the callback function.
88      */
addCleanUp(PFCleanUpFunc cleanUp,void * info)89     void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
90         CleanUpData* entry = fCleanUpData.push();
91 
92         entry->fFunc = cleanUp;
93         entry->fInfo = info;
94     }
95 
96     /**
97      * Abandons all GPU resources and assumes the underlying backend 3D API context is not longer
98      * usable. Call this if you have lost the associated GPU context, and thus internal texture,
99      * buffer, etc. references/IDs are now invalid. Calling this ensures that the destructors of the
100      * GrContext and any of its created resource objects will not make backend 3D API calls. Content
101      * rendered but not previously flushed may be lost. After this function is called all subsequent
102      * calls on the GrContext will fail or be no-ops.
103      *
104      * The typical use case for this function is that the underlying 3D context was lost and further
105      * API calls may crash.
106      */
107     void abandonContext();
108 
109     /**
110      * This is similar to abandonContext() however the underlying 3D context is not yet lost and
111      * the GrContext will cleanup all allocated resources before returning. After returning it will
112      * assume that the underlying context may no longer be valid.
113      *
114      * The typical use case for this function is that the client is going to destroy the 3D context
115      * but can't guarantee that GrContext will be destroyed first (perhaps because it may be ref'ed
116      * elsewhere by either the client or Skia objects).
117      */
118     void releaseResourcesAndAbandonContext();
119 
120     ///////////////////////////////////////////////////////////////////////////
121     // Resource Cache
122 
123     /**
124      *  Return the current GPU resource cache limits.
125      *
126      *  @param maxResources If non-null, returns maximum number of resources that
127      *                      can be held in the cache.
128      *  @param maxResourceBytes If non-null, returns maximum number of bytes of
129      *                          video memory that can be held in the cache.
130      */
131     void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const;
132 
133     /**
134      *  Gets the current GPU resource cache usage.
135      *
136      *  @param resourceCount If non-null, returns the number of resources that are held in the
137      *                       cache.
138      *  @param maxResourceBytes If non-null, returns the total number of bytes of video memory held
139      *                          in the cache.
140      */
141     void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const;
142 
143     /**
144      *  Gets the number of bytes in the cache consumed by purgeable (e.g. unlocked) resources.
145      */
146     size_t getResourceCachePurgeableBytes() const;
147 
148     /**
149      *  Specify the GPU resource cache limits. If the current cache exceeds either
150      *  of these, it will be purged (LRU) to keep the cache within these limits.
151      *
152      *  @param maxResources The maximum number of resources that can be held in
153      *                      the cache.
154      *  @param maxResourceBytes The maximum number of bytes of video memory
155      *                          that can be held in the cache.
156      */
157     void setResourceCacheLimits(int maxResources, size_t maxResourceBytes);
158 
159     /**
160      * Frees GPU created by the context. Can be called to reduce GPU memory
161      * pressure.
162      */
163     void freeGpuResources();
164 
165     /**
166      * Purge all the unlocked resources from the cache.
167      * This entry point is mainly meant for timing texture uploads
168      * and is not defined in normal builds of Skia.
169      */
170     void purgeAllUnlockedResources();
171 
172     /**
173      * Purge GPU resources that haven't been used in the past 'ms' milliseconds, regardless of
174      * whether the context is currently under budget.
175      */
176     void purgeResourcesNotUsedInMs(std::chrono::milliseconds ms);
177 
178     /**
179      * Purge unlocked resources from the cache until the the provided byte count has been reached
180      * or we have purged all unlocked resources. The default policy is to purge in LRU order, but
181      * can be overridden to prefer purging scratch resources (in LRU order) prior to purging other
182      * resource types.
183      *
184      * @param maxBytesToPurge the desired number of bytes to be purged.
185      * @param preferScratchResources If true scratch resources will be purged prior to other
186      *                               resource types.
187      */
188     void purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources);
189 
190     /** Access the context capabilities */
caps()191     const GrCaps* caps() const { return fCaps; }
192 
193     /**
194      * Returns the recommended sample count for a render target when using this
195      * context.
196      *
197      * @param  config the configuration of the render target.
198      * @param  dpi the display density in dots per inch.
199      *
200      * @return sample count that should be perform well and have good enough
201      *         rendering quality for the display. Alternatively returns 0 if
202      *         MSAA is not supported or recommended to be used by default.
203      */
204     int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const;
205 
206     /*
207      * Create a new render target context backed by a deferred-style
208      * GrRenderTargetProxy. We guarantee that "asTextureProxy" will succeed for
209      * renderTargetContexts created via this entry point.
210      */
211     sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContext(
212                                                  SkBackingFit fit,
213                                                  int width, int height,
214                                                  GrPixelConfig config,
215                                                  sk_sp<SkColorSpace> colorSpace,
216                                                  int sampleCnt = 0,
217                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
218                                                  const SkSurfaceProps* surfaceProps = nullptr,
219                                                  SkBudgeted = SkBudgeted::kYes);
220     /*
221      * This method will attempt to create a renderTargetContext that has, at least, the number of
222      * channels and precision per channel as requested in 'config' (e.g., A8 and 888 can be
223      * converted to 8888). It may also swizzle the channels (e.g., BGRA -> RGBA).
224      * SRGB-ness will be preserved.
225      */
226     sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContextWithFallback(
227                                                  SkBackingFit fit,
228                                                  int width, int height,
229                                                  GrPixelConfig config,
230                                                  sk_sp<SkColorSpace> colorSpace,
231                                                  int sampleCnt = 0,
232                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
233                                                  const SkSurfaceProps* surfaceProps = nullptr,
234                                                  SkBudgeted budgeted = SkBudgeted::kYes);
235 
236     ///////////////////////////////////////////////////////////////////////////
237     // Misc.
238 
239     /**
240      * Call to ensure all drawing to the context has been issued to the
241      * underlying 3D API.
242      */
243     void flush();
244 
245     /**
246      * An ID associated with this context, guaranteed to be unique.
247      */
uniqueID()248     uint32_t uniqueID() { return fUniqueID; }
249 
250     ///////////////////////////////////////////////////////////////////////////
251     // Functions intended for internal use only.
getGpu()252     GrGpu* getGpu() { return fGpu; }
getGpu()253     const GrGpu* getGpu() const { return fGpu; }
getAtlasGlyphCache()254     GrAtlasGlyphCache* getAtlasGlyphCache() { return fAtlasGlyphCache; }
getTextBlobCache()255     GrTextBlobCache* getTextBlobCache() { return fTextBlobCache.get(); }
256     bool abandoned() const;
resourceProvider()257     GrResourceProvider* resourceProvider() { return fResourceProvider; }
resourceProvider()258     const GrResourceProvider* resourceProvider() const { return fResourceProvider; }
getResourceCache()259     GrResourceCache* getResourceCache() { return fResourceCache; }
260 
261     /** Reset GPU stats */
262     void resetGpuStats() const ;
263 
264     /** Prints cache stats to the string if GR_CACHE_STATS == 1. */
265     void dumpCacheStats(SkString*) const;
266     void dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
267     void printCacheStats() const;
268 
269     /** Prints GPU stats to the string if GR_GPU_STATS == 1. */
270     void dumpGpuStats(SkString*) const;
271     void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
272     void printGpuStats() const;
273 
274     /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge.
275         this is for testing only */
276     void setTextBlobCacheLimit_ForTesting(size_t bytes);
277 
278     /** Specify the sizes of the GrAtlasTextContext atlases.  The configs pointer below should be
279         to an array of 3 entries */
280     void setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs);
281 
282     /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
283     void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
284 
285     /** Get pointer to atlas texture for given mask format. Note that this wraps an
286         actively mutating texture in an SkImage. This could yield unexpected results
287         if it gets cached or used more generally. */
288     sk_sp<SkImage> getFontAtlasImage_ForTesting(GrMaskFormat format);
289 
getAuditTrail()290     GrAuditTrail* getAuditTrail() { return &fAuditTrail; }
291 
292     /** This is only useful for debug purposes */
293     SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } )
294 
295     // Provides access to functions that aren't part of the public API.
296     GrContextPriv contextPriv();
297     const GrContextPriv contextPriv() const;
298 
299 private:
300     GrGpu*                                  fGpu;
301     const GrCaps*                           fCaps;
302     GrResourceCache*                        fResourceCache;
303     GrResourceProvider*                     fResourceProvider;
304 
305     sk_sp<GrContextThreadSafeProxy>         fThreadSafeProxy;
306 
307     GrAtlasGlyphCache*                      fAtlasGlyphCache;
308     std::unique_ptr<GrTextBlobCache>        fTextBlobCache;
309 
310     bool                                    fDisableGpuYUVConversion;
311     bool                                    fDidTestPMConversions;
312     // true if the PM/UPM conversion succeeded; false otherwise
313     bool                                    fPMUPMConversionsRoundTrip;
314 
315     // In debug builds we guard against improper thread handling
316     // This guard is passed to the GrDrawingManager and, from there to all the
317     // GrRenderTargetContexts.  It is also passed to the GrResourceProvider and SkGpuDevice.
318     mutable GrSingleOwner                   fSingleOwner;
319 
320     struct CleanUpData {
321         PFCleanUpFunc fFunc;
322         void*         fInfo;
323     };
324 
325     SkTDArray<CleanUpData>                  fCleanUpData;
326 
327     const uint32_t                          fUniqueID;
328 
329     std::unique_ptr<GrDrawingManager>       fDrawingManager;
330 
331     GrAuditTrail                            fAuditTrail;
332 
333     GrBackend                               fBackend;
334 
335     // TODO: have the GrClipStackClip use renderTargetContexts and rm this friending
336     friend class GrContextPriv;
337 
338     GrContext(); // init must be called after the constructor.
339     bool init(GrBackend, GrBackendContext, const GrContextOptions& options);
340     bool init(const GrContextOptions& options);
341 
342     /**
343      * These functions create premul <-> unpremul effects. If the second argument is 'true', they
344      * use the specialized round-trip effects from GrConfigConversionEffect, otherwise they
345      * create effects that do naive multiply or divide.
346      */
347     sk_sp<GrFragmentProcessor> createPMToUPMEffect(sk_sp<GrFragmentProcessor>,
348                                                    bool useConfigConversionEffect);
349     sk_sp<GrFragmentProcessor> createUPMToPMEffect(sk_sp<GrFragmentProcessor>,
350                                                    bool useConfigConversionEffect);
351 
352     /**
353      * Returns true if createPMtoUPMEffect and createUPMToPMEffect will succeed for non-sRGB 8888
354      * configs. In other words, did we find a pair of round-trip preserving conversion effects?
355      */
356     bool validPMUPMConversionExists();
357 
358     /**
359      * A callback similar to the above for use by the TextBlobCache
360      * TODO move textblob draw calls below context so we can use the call above.
361      */
362     static void TextBlobCacheOverBudgetCB(void* data);
363 
364     typedef SkRefCnt INHERITED;
365 };
366 
367 /**
368  * Can be used to perform actions related to the generating GrContext in a thread safe manner. The
369  * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext.
370  */
371 class GrContextThreadSafeProxy : public SkRefCnt {
372 private:
GrContextThreadSafeProxy(sk_sp<const GrCaps> caps,uint32_t uniqueID)373     GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t uniqueID)
374         : fCaps(std::move(caps))
375         , fContextUniqueID(uniqueID) {}
376 
377     sk_sp<const GrCaps> fCaps;
378     uint32_t            fContextUniqueID;
379 
380     friend class GrContext;
381     friend class SkImage;
382 
383     typedef SkRefCnt INHERITED;
384 };
385 
386 #endif
387