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