Home | History | Annotate | Download | only in gpu
      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      */
     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 */
    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      */
    248     uint32_t uniqueID() { return fUniqueID; }
    249 
    250     ///////////////////////////////////////////////////////////////////////////
    251     // Functions intended for internal use only.
    252     GrGpu* getGpu() { return fGpu; }
    253     const GrGpu* getGpu() const { return fGpu; }
    254     GrAtlasGlyphCache* getAtlasGlyphCache() { return fAtlasGlyphCache; }
    255     GrTextBlobCache* getTextBlobCache() { return fTextBlobCache.get(); }
    256     bool abandoned() const;
    257     GrResourceProvider* resourceProvider() { return fResourceProvider; }
    258     const GrResourceProvider* resourceProvider() const { return fResourceProvider; }
    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 
    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:
    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