Line data Source code
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 :
20 : class GrAtlasGlyphCache;
21 : struct GrContextOptions;
22 : class GrContextPriv;
23 : class GrContextThreadSafeProxy;
24 : class GrDrawingManager;
25 : struct GrDrawOpAtlasConfig;
26 : class GrRenderTargetContext;
27 : class GrFragmentProcessor;
28 : class GrGpu;
29 : class GrIndexBuffer;
30 : class GrOvalRenderer;
31 : class GrPath;
32 : class GrPipelineBuilder;
33 : class GrResourceEntry;
34 : class GrResourceCache;
35 : class GrResourceProvider;
36 : class GrSamplerParams;
37 : class GrSurfaceProxy;
38 : class GrTextBlobCache;
39 : class GrTextContext;
40 : class GrTextureProxy;
41 : class GrVertexBuffer;
42 : class GrSwizzle;
43 : class SkTraceMemoryDump;
44 :
45 : class SkImage;
46 : class SkSurfaceProps;
47 :
48 : class SK_API GrContext : public SkRefCnt {
49 : public:
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 0 : void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
87 0 : CleanUpData* entry = fCleanUpData.push();
88 :
89 0 : entry->fFunc = cleanUp;
90 0 : entry->fInfo = info;
91 0 : }
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 : * Specify the GPU resource cache limits. If the current cache exceeds either
142 : * of these, it will be purged (LRU) to keep the cache within these limits.
143 : *
144 : * @param maxResources The maximum number of resources that can be held in
145 : * the cache.
146 : * @param maxResourceBytes The maximum number of bytes of video memory
147 : * that can be held in the cache.
148 : */
149 : void setResourceCacheLimits(int maxResources, size_t maxResourceBytes);
150 :
151 : /**
152 : * Frees GPU created by the context. Can be called to reduce GPU memory
153 : * pressure.
154 : */
155 : void freeGpuResources();
156 :
157 : /**
158 : * Purge all the unlocked resources from the cache.
159 : * This entry point is mainly meant for timing texture uploads
160 : * and is not defined in normal builds of Skia.
161 : */
162 : void purgeAllUnlockedResources();
163 :
164 : /**
165 : * Purge GPU resources that haven't been used in the past 'ms' milliseconds, regardless of
166 : * whether the context is currently under budget.
167 : */
168 : void purgeResourcesNotUsedInMs(std::chrono::milliseconds ms);
169 :
170 : /** Access the context capabilities */
171 0 : const GrCaps* caps() const { return fCaps; }
172 :
173 : /**
174 : * Returns the recommended sample count for a render target when using this
175 : * context.
176 : *
177 : * @param config the configuration of the render target.
178 : * @param dpi the display density in dots per inch.
179 : *
180 : * @return sample count that should be perform well and have good enough
181 : * rendering quality for the display. Alternatively returns 0 if
182 : * MSAA is not supported or recommended to be used by default.
183 : */
184 : int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const;
185 :
186 : /**
187 : * Create both a GrRenderTarget and a matching GrRenderTargetContext to wrap it.
188 : * We guarantee that "asTexture" will succeed for renderTargetContexts created
189 : * via this entry point.
190 : */
191 : sk_sp<GrRenderTargetContext> makeRenderTargetContext(
192 : SkBackingFit fit,
193 : int width, int height,
194 : GrPixelConfig config,
195 : sk_sp<SkColorSpace> colorSpace,
196 : int sampleCnt = 0,
197 : GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
198 : const SkSurfaceProps* surfaceProps = nullptr,
199 : SkBudgeted = SkBudgeted::kYes);
200 :
201 : // Create a new render target context as above but have it backed by a deferred-style
202 : // GrRenderTargetProxy rather than one that is backed by an actual GrRenderTarget
203 : sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContext(
204 : SkBackingFit fit,
205 : int width, int height,
206 : GrPixelConfig config,
207 : sk_sp<SkColorSpace> colorSpace,
208 : int sampleCnt = 0,
209 : GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
210 : const SkSurfaceProps* surfaceProps = nullptr,
211 : SkBudgeted = SkBudgeted::kYes);
212 : /*
213 : * This method will attempt to create a renderTargetContext that has, at least, the number of
214 : * channels and precision per channel as requested in 'config' (e.g., A8 and 888 can be
215 : * converted to 8888). It may also swizzle the channels (e.g., BGRA -> RGBA).
216 : * SRGB-ness will be preserved.
217 : */
218 : sk_sp<GrRenderTargetContext> makeRenderTargetContextWithFallback(
219 : SkBackingFit fit,
220 : int width, int height,
221 : GrPixelConfig config,
222 : sk_sp<SkColorSpace> colorSpace,
223 : int sampleCnt = 0,
224 : GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
225 : const SkSurfaceProps* surfaceProps = nullptr,
226 : SkBudgeted budgeted = SkBudgeted::kYes);
227 :
228 : // Create a new render target context as above but have it backed by a deferred-style
229 : // GrRenderTargetProxy rather than one that is backed by an actual GrRenderTarget
230 : sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContextWithFallback(
231 : SkBackingFit fit,
232 : int width, int height,
233 : GrPixelConfig config,
234 : sk_sp<SkColorSpace> colorSpace,
235 : int sampleCnt = 0,
236 : GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
237 : const SkSurfaceProps* surfaceProps = nullptr,
238 : SkBudgeted budgeted = SkBudgeted::kYes);
239 :
240 : ///////////////////////////////////////////////////////////////////////////
241 : // Misc.
242 :
243 : /**
244 : * Call to ensure all drawing to the context has been issued to the
245 : * underlying 3D API.
246 : */
247 : void flush();
248 :
249 : /**
250 : * An ID associated with this context, guaranteed to be unique.
251 : */
252 0 : uint32_t uniqueID() { return fUniqueID; }
253 :
254 : ///////////////////////////////////////////////////////////////////////////
255 : // Functions intended for internal use only.
256 0 : GrGpu* getGpu() { return fGpu; }
257 : const GrGpu* getGpu() const { return fGpu; }
258 0 : GrAtlasGlyphCache* getAtlasGlyphCache() { return fAtlasGlyphCache; }
259 0 : GrTextBlobCache* getTextBlobCache() { return fTextBlobCache.get(); }
260 : bool abandoned() const;
261 0 : GrResourceProvider* resourceProvider() { return fResourceProvider; }
262 : const GrResourceProvider* resourceProvider() const { return fResourceProvider; }
263 0 : GrResourceCache* getResourceCache() { return fResourceCache; }
264 :
265 : /** Reset GPU stats */
266 : void resetGpuStats() const ;
267 :
268 : /** Prints cache stats to the string if GR_CACHE_STATS == 1. */
269 : void dumpCacheStats(SkString*) const;
270 : void dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
271 : void printCacheStats() const;
272 :
273 : /** Prints GPU stats to the string if GR_GPU_STATS == 1. */
274 : void dumpGpuStats(SkString*) const;
275 : void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
276 : void printGpuStats() const;
277 :
278 : /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge.
279 : this is for testing only */
280 : void setTextBlobCacheLimit_ForTesting(size_t bytes);
281 :
282 : /** Specify the sizes of the GrAtlasTextContext atlases. The configs pointer below should be
283 : to an array of 3 entries */
284 : void setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs);
285 :
286 : /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
287 : void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
288 :
289 : /** Get pointer to atlas texture for given mask format. Note that this wraps an
290 : actively mutating texture in an SkImage. This could yield unexpected results
291 : if it gets cached or used more generally. */
292 : sk_sp<SkImage> getFontAtlasImage_ForTesting(GrMaskFormat format);
293 :
294 0 : GrAuditTrail* getAuditTrail() { return &fAuditTrail; }
295 :
296 : /** This is only useful for debug purposes */
297 0 : SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } )
298 :
299 : // Provides access to functions that aren't part of the public API.
300 : GrContextPriv contextPriv();
301 : const GrContextPriv contextPriv() const;
302 :
303 : private:
304 : GrGpu* fGpu;
305 : const GrCaps* fCaps;
306 : GrResourceCache* fResourceCache;
307 : GrResourceProvider* fResourceProvider;
308 :
309 : sk_sp<GrContextThreadSafeProxy> fThreadSafeProxy;
310 :
311 : GrAtlasGlyphCache* fAtlasGlyphCache;
312 : std::unique_ptr<GrTextBlobCache> fTextBlobCache;
313 :
314 : bool fDisableGpuYUVConversion;
315 : bool fDidTestPMConversions;
316 : int fPMToUPMConversion;
317 : int fUPMToPMConversion;
318 :
319 : // In debug builds we guard against improper thread handling
320 : // This guard is passed to the GrDrawingManager and, from there to all the
321 : // GrRenderTargetContexts. It is also passed to the GrResourceProvider and SkGpuDevice.
322 : mutable GrSingleOwner fSingleOwner;
323 :
324 : struct CleanUpData {
325 : PFCleanUpFunc fFunc;
326 : void* fInfo;
327 : };
328 :
329 : SkTDArray<CleanUpData> fCleanUpData;
330 :
331 : const uint32_t fUniqueID;
332 :
333 : std::unique_ptr<GrDrawingManager> fDrawingManager;
334 :
335 : GrAuditTrail fAuditTrail;
336 :
337 : // TODO: have the GrClipStackClip use renderTargetContexts and rm this friending
338 : friend class GrContextPriv;
339 :
340 : GrContext(); // init must be called after the constructor.
341 : bool init(GrBackend, GrBackendContext, const GrContextOptions& options);
342 :
343 : void initMockContext();
344 : void initCommon(const GrContextOptions&);
345 :
346 : /**
347 : * These functions create premul <-> unpremul effects if it is possible to generate a pair
348 : * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
349 : * return NULL. They also can perform a swizzle as part of the draw.
350 : */
351 : sk_sp<GrFragmentProcessor> createPMToUPMEffect(sk_sp<GrFragmentProcessor>, GrPixelConfig);
352 : sk_sp<GrFragmentProcessor> createUPMToPMEffect(sk_sp<GrFragmentProcessor>, GrPixelConfig);
353 : /** Called before either of the above two functions to determine the appropriate fragment
354 : processors for conversions. */
355 : void testPMConversionsIfNecessary(uint32_t flags);
356 : /** Returns true if we've determined that createPMtoUPMEffect and createUPMToPMEffect will
357 : succeed for the passed in config. Otherwise we fall back to SW conversion. */
358 : bool validPMUPMConversionExists(GrPixelConfig) const;
359 :
360 : /**
361 : * A callback similar to the above for use by the TextBlobCache
362 : * TODO move textblob draw calls below context so we can use the call above.
363 : */
364 : static void TextBlobCacheOverBudgetCB(void* data);
365 :
366 : typedef SkRefCnt INHERITED;
367 : };
368 :
369 : /**
370 : * Can be used to perform actions related to the generating GrContext in a thread safe manner. The
371 : * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext.
372 : */
373 0 : class GrContextThreadSafeProxy : public SkRefCnt {
374 : private:
375 0 : GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t uniqueID)
376 0 : : fCaps(std::move(caps))
377 0 : , fContextUniqueID(uniqueID) {}
378 :
379 : sk_sp<const GrCaps> fCaps;
380 : uint32_t fContextUniqueID;
381 :
382 : friend class GrContext;
383 : friend class SkImage;
384 :
385 : typedef SkRefCnt INHERITED;
386 : };
387 :
388 : #endif
|