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 "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 GrTextBlobCache;
     38 class GrTextContext;
     39 class GrTextureProxy;
     40 class GrVertexBuffer;
     41 class GrSwizzle;
     42 class SkTraceMemoryDump;
     43 
     44 class SkImage;
     45 class SkSurfaceProps;
     46 
     47 class SK_API GrContext : public SkRefCnt {
     48 public:
     49     /**
     50      * Creates a GrContext for a backend context.
     51      */
     52     static GrContext* Create(GrBackend, GrBackendContext, const GrContextOptions& options);
     53     static GrContext* Create(GrBackend, GrBackendContext);
     54 
     55     /**
     56      * Only defined in test apps.
     57      */
     58     static GrContext* CreateMockContext();
     59 
     60     virtual ~GrContext();
     61 
     62     sk_sp<GrContextThreadSafeProxy> threadSafeProxy();
     63 
     64     /**
     65      * The GrContext normally assumes that no outsider is setting state
     66      * within the underlying 3D API's context/device/whatever. This call informs
     67      * the context that the state was modified and it should resend. Shouldn't
     68      * be called frequently for good performance.
     69      * The flag bits, state, is dpendent on which backend is used by the
     70      * context, either GL or D3D (possible in future).
     71      */
     72     void resetContext(uint32_t state = kAll_GrBackendState);
     73 
     74     /**
     75      * Callback function to allow classes to cleanup on GrContext destruction.
     76      * The 'info' field is filled in with the 'info' passed to addCleanUp.
     77      */
     78     typedef void (*PFCleanUpFunc)(const GrContext* context, void* info);
     79 
     80     /**
     81      * Add a function to be called from within GrContext's destructor.
     82      * This gives classes a chance to free resources held on a per context basis.
     83      * The 'info' parameter will be stored and passed to the callback function.
     84      */
     85     void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
     86         CleanUpData* entry = fCleanUpData.push();
     87 
     88         entry->fFunc = cleanUp;
     89         entry->fInfo = info;
     90     }
     91 
     92     /**
     93      * Abandons all GPU resources and assumes the underlying backend 3D API context is not longer
     94      * usable. Call this if you have lost the associated GPU context, and thus internal texture,
     95      * buffer, etc. references/IDs are now invalid. Calling this ensures that the destructors of the
     96      * GrContext and any of its created resource objects will not make backend 3D API calls. Content
     97      * rendered but not previously flushed may be lost. After this function is called all subsequent
     98      * calls on the GrContext will fail or be no-ops.
     99      *
    100      * The typical use case for this function is that the underlying 3D context was lost and further
    101      * API calls may crash.
    102      */
    103     void abandonContext();
    104 
    105     /**
    106      * This is similar to abandonContext() however the underlying 3D context is not yet lost and
    107      * the GrContext will cleanup all allocated resources before returning. After returning it will
    108      * assume that the underlying context may no longer be valid.
    109      *
    110      * The typical use case for this function is that the client is going to destroy the 3D context
    111      * but can't guarantee that GrContext will be destroyed first (perhaps because it may be ref'ed
    112      * elsewhere by either the client or Skia objects).
    113      */
    114     void releaseResourcesAndAbandonContext();
    115 
    116     ///////////////////////////////////////////////////////////////////////////
    117     // Resource Cache
    118 
    119     /**
    120      *  Return the current GPU resource cache limits.
    121      *
    122      *  @param maxResources If non-null, returns maximum number of resources that
    123      *                      can be held in the cache.
    124      *  @param maxResourceBytes If non-null, returns maximum number of bytes of
    125      *                          video memory that can be held in the cache.
    126      */
    127     void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const;
    128 
    129     /**
    130      *  Gets the current GPU resource cache usage.
    131      *
    132      *  @param resourceCount If non-null, returns the number of resources that are held in the
    133      *                       cache.
    134      *  @param maxResourceBytes If non-null, returns the total number of bytes of video memory held
    135      *                          in the cache.
    136      */
    137     void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const;
    138 
    139     /**
    140      *  Specify the GPU resource cache limits. If the current cache exceeds either
    141      *  of these, it will be purged (LRU) to keep the cache within these limits.
    142      *
    143      *  @param maxResources The maximum number of resources that can be held in
    144      *                      the cache.
    145      *  @param maxResourceBytes The maximum number of bytes of video memory
    146      *                          that can be held in the cache.
    147      */
    148     void setResourceCacheLimits(int maxResources, size_t maxResourceBytes);
    149 
    150     /**
    151      * Frees GPU created by the context. Can be called to reduce GPU memory
    152      * pressure.
    153      */
    154     void freeGpuResources();
    155 
    156     /**
    157      * Purge all the unlocked resources from the cache.
    158      * This entry point is mainly meant for timing texture uploads
    159      * and is not defined in normal builds of Skia.
    160      */
    161     void purgeAllUnlockedResources();
    162 
    163     /**
    164      * Purge GPU resources that haven't been used in the past 'ms' milliseconds, regardless of
    165      * whether the context is currently under budget.
    166      */
    167     void purgeResourcesNotUsedInMs(std::chrono::milliseconds ms);
    168 
    169     /** Access the context capabilities */
    170     const GrCaps* caps() const { return fCaps; }
    171 
    172     /**
    173      * Returns the recommended sample count for a render target when using this
    174      * context.
    175      *
    176      * @param  config the configuration of the render target.
    177      * @param  dpi the display density in dots per inch.
    178      *
    179      * @return sample count that should be perform well and have good enough
    180      *         rendering quality for the display. Alternatively returns 0 if
    181      *         MSAA is not supported or recommended to be used by default.
    182      */
    183     int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const;
    184 
    185     /**
    186      * Create both a GrRenderTarget and a matching GrRenderTargetContext to wrap it.
    187      * We guarantee that "asTexture" will succeed for renderTargetContexts created
    188      * via this entry point.
    189      */
    190     sk_sp<GrRenderTargetContext> makeRenderTargetContext(
    191                                                  SkBackingFit fit,
    192                                                  int width, int height,
    193                                                  GrPixelConfig config,
    194                                                  sk_sp<SkColorSpace> colorSpace,
    195                                                  int sampleCnt = 0,
    196                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
    197                                                  const SkSurfaceProps* surfaceProps = nullptr,
    198                                                  SkBudgeted = SkBudgeted::kYes);
    199 
    200     // Create a new render target context as above but have it backed by a deferred-style
    201     // GrRenderTargetProxy rather than one that is backed by an actual GrRenderTarget
    202     sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContext(
    203                                                  SkBackingFit fit,
    204                                                  int width, int height,
    205                                                  GrPixelConfig config,
    206                                                  sk_sp<SkColorSpace> colorSpace,
    207                                                  int sampleCnt = 0,
    208                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
    209                                                  const SkSurfaceProps* surfaceProps = nullptr,
    210                                                  SkBudgeted = SkBudgeted::kYes);
    211     /*
    212      * This method will attempt to create a renderTargetContext that has, at least, the number of
    213      * channels and precision per channel as requested in 'config' (e.g., A8 and 888 can be
    214      * converted to 8888). It may also swizzle the channels (e.g., BGRA -> RGBA).
    215      * SRGB-ness will be preserved.
    216      */
    217     sk_sp<GrRenderTargetContext> makeRenderTargetContextWithFallback(
    218                                                  SkBackingFit fit,
    219                                                  int width, int height,
    220                                                  GrPixelConfig config,
    221                                                  sk_sp<SkColorSpace> colorSpace,
    222                                                  int sampleCnt = 0,
    223                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
    224                                                  const SkSurfaceProps* surfaceProps = nullptr,
    225                                                  SkBudgeted budgeted = SkBudgeted::kYes);
    226 
    227     // Create a new render target context as above but have it backed by a deferred-style
    228     // GrRenderTargetProxy rather than one that is backed by an actual GrRenderTarget
    229     sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContextWithFallback(
    230                                                  SkBackingFit fit,
    231                                                  int width, int height,
    232                                                  GrPixelConfig config,
    233                                                  sk_sp<SkColorSpace> colorSpace,
    234                                                  int sampleCnt = 0,
    235                                                  GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
    236                                                  const SkSurfaceProps* surfaceProps = nullptr,
    237                                                  SkBudgeted budgeted = SkBudgeted::kYes);
    238 
    239     ///////////////////////////////////////////////////////////////////////////
    240     // Misc.
    241 
    242     /**
    243      * Call to ensure all drawing to the context has been issued to the
    244      * underlying 3D API.
    245      */
    246     void flush();
    247 
    248    /**
    249     * These flags can be used with the read/write pixels functions below.
    250     */
    251     enum PixelOpsFlags {
    252         /** The GrContext will not be flushed before the surface read or write. This means that
    253             the read or write may occur before previous draws have executed. */
    254         kDontFlush_PixelOpsFlag = 0x1,
    255         /** Any surface writes should be flushed to the backend 3D API after the surface operation
    256             is complete */
    257         kFlushWrites_PixelOp = 0x2,
    258         /** The src for write or dst read is unpremultiplied. This is only respected if both the
    259             config src and dst configs are an RGBA/BGRA 8888 format. */
    260         kUnpremul_PixelOpsFlag  = 0x4,
    261     };
    262 
    263     /**
    264      * Reads a rectangle of pixels from a surface.
    265      * @param surface       the surface to read from.
    266      * @param srcColorSpace color space of the surface
    267      * @param left          left edge of the rectangle to read (inclusive)
    268      * @param top           top edge of the rectangle to read (inclusive)
    269      * @param width         width of rectangle to read in pixels.
    270      * @param height        height of rectangle to read in pixels.
    271      * @param config        the pixel config of the destination buffer
    272      * @param dstColorSpace color space of the destination buffer
    273      * @param buffer        memory to read the rectangle into.
    274      * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
    275      *                      packed.
    276      * @param pixelOpsFlags see PixelOpsFlags enum above.
    277      *
    278      * @return true if the read succeeded, false if not. The read can fail because of an unsupported
    279      *         pixel configs
    280      */
    281     bool readSurfacePixels(GrSurface* surface, SkColorSpace* srcColorSpace,
    282                            int left, int top, int width, int height,
    283                            GrPixelConfig config, SkColorSpace* dstColorSpace, void* buffer,
    284                            size_t rowBytes = 0,
    285                            uint32_t pixelOpsFlags = 0);
    286 
    287     /**
    288      * Writes a rectangle of pixels to a surface.
    289      * @param surface       the surface to write to.
    290      * @param dstColorSpace color space of the surface
    291      * @param left          left edge of the rectangle to write (inclusive)
    292      * @param top           top edge of the rectangle to write (inclusive)
    293      * @param width         width of rectangle to write in pixels.
    294      * @param height        height of rectangle to write in pixels.
    295      * @param config        the pixel config of the source buffer
    296      * @param srcColorSpace color space of the source buffer
    297      * @param buffer        memory to read pixels from
    298      * @param rowBytes      number of bytes between consecutive rows. Zero
    299      *                      means rows are tightly packed.
    300      * @param pixelOpsFlags see PixelOpsFlags enum above.
    301      * @return true if the write succeeded, false if not. The write can fail because of an
    302      *         unsupported combination of surface and src configs.
    303      */
    304     bool writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpace,
    305                             int left, int top, int width, int height,
    306                             GrPixelConfig config, SkColorSpace* srcColorSpace, const void* buffer,
    307                             size_t rowBytes,
    308                             uint32_t pixelOpsFlags = 0);
    309 
    310     /**
    311      * After this returns any pending writes to the surface will have been issued to the backend 3D API.
    312      */
    313     void flushSurfaceWrites(GrSurface* surface);
    314 
    315     /**
    316      * After this returns any pending reads or writes to the surface will have been issued to the
    317      * backend 3D API.
    318      */
    319     void flushSurfaceIO(GrSurface* surface);
    320 
    321     /**
    322      * Finalizes all pending reads and writes to the surface and also performs an MSAA resolve
    323      * if necessary.
    324      *
    325      * It is not necessary to call this before reading the render target via Skia/GrContext.
    326      * GrContext will detect when it must perform a resolve before reading pixels back from the
    327      * surface or using it as a texture.
    328      */
    329     void prepareSurfaceForExternalIO(GrSurface*);
    330 
    331     /**
    332      * An ID associated with this context, guaranteed to be unique.
    333      */
    334     uint32_t uniqueID() { return fUniqueID; }
    335 
    336     ///////////////////////////////////////////////////////////////////////////
    337     // Functions intended for internal use only.
    338     GrGpu* getGpu() { return fGpu; }
    339     const GrGpu* getGpu() const { return fGpu; }
    340     GrAtlasGlyphCache* getAtlasGlyphCache() { return fAtlasGlyphCache; }
    341     GrTextBlobCache* getTextBlobCache() { return fTextBlobCache.get(); }
    342     bool abandoned() const;
    343     GrResourceProvider* resourceProvider() { return fResourceProvider; }
    344     const GrResourceProvider* resourceProvider() const { return fResourceProvider; }
    345     GrResourceCache* getResourceCache() { return fResourceCache; }
    346 
    347     /** Reset GPU stats */
    348     void resetGpuStats() const ;
    349 
    350     /** Prints cache stats to the string if GR_CACHE_STATS == 1. */
    351     void dumpCacheStats(SkString*) const;
    352     void dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
    353     void printCacheStats() const;
    354 
    355     /** Prints GPU stats to the string if GR_GPU_STATS == 1. */
    356     void dumpGpuStats(SkString*) const;
    357     void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
    358     void printGpuStats() const;
    359 
    360     /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge.
    361         this is for testing only */
    362     void setTextBlobCacheLimit_ForTesting(size_t bytes);
    363 
    364     /** Specify the sizes of the GrAtlasTextContext atlases.  The configs pointer below should be
    365         to an array of 3 entries */
    366     void setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs);
    367 
    368     /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
    369     void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
    370 
    371     /** Get pointer to atlas texture for given mask format. Note that this wraps an
    372         actively mutating texture in an SkImage. This could yield unexpected results
    373         if it gets cached or used more generally. */
    374     sk_sp<SkImage> getFontAtlasImage_ForTesting(GrMaskFormat format);
    375 
    376     GrAuditTrail* getAuditTrail() { return &fAuditTrail; }
    377 
    378     /** This is only useful for debug purposes */
    379     SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } )
    380 
    381     // Provides access to functions that aren't part of the public API.
    382     GrContextPriv contextPriv();
    383     const GrContextPriv contextPriv() const;
    384 
    385 private:
    386     GrGpu*                                  fGpu;
    387     const GrCaps*                           fCaps;
    388     GrResourceCache*                        fResourceCache;
    389     GrResourceProvider*                     fResourceProvider;
    390 
    391     sk_sp<GrContextThreadSafeProxy>         fThreadSafeProxy;
    392 
    393     GrAtlasGlyphCache*                      fAtlasGlyphCache;
    394     std::unique_ptr<GrTextBlobCache>        fTextBlobCache;
    395 
    396     bool                                    fDisableGpuYUVConversion;
    397     bool                                    fDidTestPMConversions;
    398     int                                     fPMToUPMConversion;
    399     int                                     fUPMToPMConversion;
    400 
    401     // In debug builds we guard against improper thread handling
    402     // This guard is passed to the GrDrawingManager and, from there to all the
    403     // GrRenderTargetContexts.  It is also passed to the GrResourceProvider and SkGpuDevice.
    404     mutable GrSingleOwner                   fSingleOwner;
    405 
    406     struct CleanUpData {
    407         PFCleanUpFunc fFunc;
    408         void*         fInfo;
    409     };
    410 
    411     SkTDArray<CleanUpData>                  fCleanUpData;
    412 
    413     const uint32_t                          fUniqueID;
    414 
    415     std::unique_ptr<GrDrawingManager>       fDrawingManager;
    416 
    417     GrAuditTrail                            fAuditTrail;
    418 
    419     // TODO: have the GrClipStackClip use renderTargetContexts and rm this friending
    420     friend class GrContextPriv;
    421 
    422     GrContext(); // init must be called after the constructor.
    423     bool init(GrBackend, GrBackendContext, const GrContextOptions& options);
    424 
    425     void initMockContext();
    426     void initCommon(const GrContextOptions&);
    427 
    428     /**
    429      * These functions create premul <-> unpremul effects if it is possible to generate a pair
    430      * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
    431      * return NULL. They also can perform a swizzle as part of the draw.
    432      */
    433     sk_sp<GrFragmentProcessor> createPMToUPMEffect(GrTexture*, const SkMatrix&);
    434     sk_sp<GrFragmentProcessor> createPMToUPMEffect(sk_sp<GrTextureProxy>, const SkMatrix&);
    435     sk_sp<GrFragmentProcessor> createUPMToPMEffect(sk_sp<GrTextureProxy>, const SkMatrix&);
    436     /** Called before either of the above two functions to determine the appropriate fragment
    437         processors for conversions. */
    438     void testPMConversionsIfNecessary(uint32_t flags);
    439     /** Returns true if we've determined that createPMtoUPMEffect and createUPMToPMEffect will
    440         succeed for the passed in config. Otherwise we fall back to SW conversion. */
    441     bool validPMUPMConversionExists(GrPixelConfig) const;
    442 
    443     /**
    444      * A callback similar to the above for use by the TextBlobCache
    445      * TODO move textblob draw calls below context so we can use the call above.
    446      */
    447     static void TextBlobCacheOverBudgetCB(void* data);
    448 
    449     typedef SkRefCnt INHERITED;
    450 };
    451 
    452 /**
    453  * Can be used to perform actions related to the generating GrContext in a thread safe manner. The
    454  * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext.
    455  */
    456 class GrContextThreadSafeProxy : public SkRefCnt {
    457 private:
    458     GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t uniqueID)
    459         : fCaps(std::move(caps))
    460         , fContextUniqueID(uniqueID) {}
    461 
    462     sk_sp<const GrCaps> fCaps;
    463     uint32_t            fContextUniqueID;
    464 
    465     friend class GrContext;
    466     friend class SkImage;
    467 
    468     typedef SkRefCnt INHERITED;
    469 };
    470 
    471 #endif
    472