LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/private - GrSurfaceProxy.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 83 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 35 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2016 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 GrSurfaceProxy_DEFINED
       9             : #define GrSurfaceProxy_DEFINED
      10             : 
      11             : #include "GrGpuResource.h"
      12             : #include "GrSurface.h"
      13             : 
      14             : #include "SkRect.h"
      15             : 
      16             : class GrCaps;
      17             : class GrRenderTargetOpList;
      18             : class GrRenderTargetProxy;
      19             : class GrResourceProvider;
      20             : class GrSurfaceContext;
      21             : class GrSurfaceProxyPriv;
      22             : class GrTextureOpList;
      23             : class GrTextureProxy;
      24             : 
      25             : //#define SK_DISABLE_DEFERRED_PROXIES 1
      26             : 
      27             : // This class replicates the functionality GrIORef<GrSurface> but tracks the
      28             : // utilitization for later resource allocation (for the deferred case) and
      29             : // forwards on the utilization in the wrapped case
      30             : class GrIORefProxy : public SkNoncopyable {
      31             : public:
      32           0 :     void ref() const {
      33           0 :         this->validate();
      34             : 
      35           0 :         ++fRefCnt;
      36           0 :         if (fTarget) {
      37           0 :             fTarget->ref();
      38             :         }
      39           0 :     }
      40             : 
      41           0 :     void unref() const {
      42           0 :         this->validate();
      43             : 
      44           0 :         if (fTarget) {
      45           0 :             fTarget->unref();
      46             :         }
      47             : 
      48           0 :         if (!(--fRefCnt)) {
      49           0 :             delete this;
      50           0 :             return;
      51             :         }
      52             : 
      53           0 :         this->validate();
      54             :     }
      55             : 
      56           0 :     void validate() const {
      57             : #ifdef SK_DEBUG    
      58           0 :         SkASSERT(fRefCnt >= 1);
      59           0 :         SkASSERT(fPendingReads >= 0);
      60           0 :         SkASSERT(fPendingWrites >= 0);
      61           0 :         SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 1);
      62             : 
      63           0 :         if (fTarget) {
      64           0 :             SkASSERT(!fPendingReads && !fPendingWrites);
      65             :             // The backing GrSurface can have more refs than the proxy if the proxy
      66             :             // started off wrapping an external resource (that came in with refs).
      67             :             // The GrSurface should never have fewer refs than the proxy however.
      68           0 :             SkASSERT(fTarget->fRefCnt >= fRefCnt);
      69             :         }
      70             : #endif
      71           0 :     }
      72             : 
      73             :     int32_t getProxyRefCnt_TestOnly() const;
      74             :     int32_t getBackingRefCnt_TestOnly() const;
      75             :     int32_t getPendingReadCnt_TestOnly() const;
      76             :     int32_t getPendingWriteCnt_TestOnly() const;
      77             : 
      78             : protected:
      79           0 :     GrIORefProxy() : fTarget(nullptr), fRefCnt(1), fPendingReads(0), fPendingWrites(0) {}
      80           0 :     GrIORefProxy(sk_sp<GrSurface> surface) : fRefCnt(1), fPendingReads(0), fPendingWrites(0) {
      81             :         // Since we're manually forwarding on refs & unrefs we don't want sk_sp doing
      82             :         // anything extra.
      83           0 :         fTarget = surface.release();
      84           0 :     }
      85           0 :     virtual ~GrIORefProxy() {
      86             :         // We don't unref 'fTarget' here since the 'unref' method will already
      87             :         // have forwarded on the unref call that got use here.
      88           0 :     }
      89             : 
      90             :     // This GrIORefProxy was deferred before but has just been instantiated. To
      91             :     // make all the reffing & unreffing work out we now need to transfer any deferred
      92             :     // refs & unrefs to the new GrSurface
      93           0 :     void transferRefs() {
      94           0 :         SkASSERT(fTarget);
      95             : 
      96           0 :         fTarget->fRefCnt += (fRefCnt-1); // don't xfer the proxy's creation ref
      97           0 :         fTarget->fPendingReads += fPendingReads;
      98           0 :         fTarget->fPendingWrites += fPendingWrites;
      99             : 
     100           0 :         fPendingReads = 0;
     101           0 :         fPendingWrites = 0;
     102           0 :     }
     103             : 
     104           0 :     bool internalHasPendingIO() const {
     105           0 :         if (fTarget) {
     106           0 :             return fTarget->internalHasPendingIO();
     107             :         }
     108             : 
     109           0 :         return SkToBool(fPendingWrites | fPendingReads);
     110             :     }
     111             : 
     112           0 :     bool internalHasPendingWrite() const {
     113           0 :         if (fTarget) {
     114           0 :             return fTarget->internalHasPendingWrite();
     115             :         }
     116             : 
     117           0 :         return SkToBool(fPendingWrites);
     118             :     }
     119             : 
     120             :     // For deferred proxies this will be null. For wrapped proxies it will point to the
     121             :     // wrapped resource.
     122             :     GrSurface* fTarget;
     123             : 
     124             : private:
     125             :     // This class is used to manage conversion of refs to pending reads/writes.
     126             :     friend class GrGpuResourceRef;
     127             :     template <typename, GrIOType> friend class GrPendingIOResource;
     128             : 
     129             :     void addPendingRead() const {
     130             :         this->validate();
     131             : 
     132             :         if (fTarget) {
     133             :             fTarget->addPendingRead();
     134             :             return;
     135             :         }
     136             : 
     137             :         ++fPendingReads;
     138             :     }
     139             : 
     140             :     void completedRead() const {
     141             :         this->validate();
     142             : 
     143             :         if (fTarget) {
     144             :             fTarget->completedRead();
     145             :             return;
     146             :         }
     147             :     
     148             :         SkFAIL("How was the read completed if the Proxy hasn't been instantiated?");
     149             :     }
     150             : 
     151             :     void addPendingWrite() const {
     152             :         this->validate();
     153             : 
     154             :         if (fTarget) {
     155             :             fTarget->addPendingWrite();
     156             :             return;
     157             :         }
     158             : 
     159             :         ++fPendingWrites;
     160             :     }
     161             : 
     162             :     void completedWrite() const {
     163             :         this->validate();
     164             : 
     165             :         if (fTarget) {
     166             :             fTarget->completedWrite();
     167             :             return;
     168             :         }
     169             :     
     170             :         SkFAIL("How was the write completed if the Proxy hasn't been instantiated?");
     171             :     }
     172             : 
     173             :     mutable int32_t fRefCnt;
     174             :     mutable int32_t fPendingReads;
     175             :     mutable int32_t fPendingWrites;
     176             : };
     177             : 
     178             : class GrSurfaceProxy : public GrIORefProxy {
     179             : public:
     180             :     static sk_sp<GrSurfaceProxy> MakeWrapped(sk_sp<GrSurface>);
     181             :     static sk_sp<GrTextureProxy> MakeWrapped(sk_sp<GrTexture>);
     182             : 
     183             :     static sk_sp<GrTextureProxy> MakeDeferred(GrResourceProvider*,
     184             :                                               const GrSurfaceDesc&, SkBackingFit,
     185             :                                               SkBudgeted, uint32_t flags = 0);
     186             : 
     187             :     // TODO: need to refine ownership semantics of 'srcData' if we're in completely
     188             :     // deferred mode
     189             :     static sk_sp<GrTextureProxy> MakeDeferred(GrResourceProvider*,
     190             :                                               const GrSurfaceDesc&, SkBudgeted,
     191             :                                               const void* srcData, size_t rowBytes);
     192             : 
     193             :     static sk_sp<GrSurfaceProxy> MakeWrappedBackend(GrContext*, GrBackendTextureDesc&);
     194             : 
     195           0 :     const GrSurfaceDesc& desc() const { return fDesc; }
     196             : 
     197           0 :     GrSurfaceOrigin origin() const {
     198           0 :         SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin ||
     199             :                  kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
     200           0 :         return fDesc.fOrigin;
     201             :     }
     202           0 :     int width() const { return fDesc.fWidth; }
     203           0 :     int height() const { return fDesc.fHeight; }
     204           0 :     GrPixelConfig config() const { return fDesc.fConfig; }
     205             : 
     206             :     class UniqueID {
     207             :     public:
     208           0 :         static UniqueID InvalidID() {
     209           0 :             return UniqueID(uint32_t(SK_InvalidUniqueID));
     210             :         }
     211             : 
     212             :         // wrapped
     213           0 :         explicit UniqueID(const GrGpuResource::UniqueID& id) : fID(id.asUInt()) { }
     214             :         // deferred
     215           0 :         UniqueID() : fID(GrGpuResource::CreateUniqueID()) { }
     216             : 
     217           0 :         uint32_t asUInt() const { return fID; }
     218             : 
     219           0 :         bool operator==(const UniqueID& other) const {
     220           0 :             return fID == other.fID;
     221             :         }
     222             :         bool operator!=(const UniqueID& other) const {
     223             :             return !(*this == other);
     224             :         }
     225             : 
     226           0 :         void makeInvalid() { fID = SK_InvalidUniqueID; }
     227             :         bool isInvalid() const { return SK_InvalidUniqueID == fID; }
     228             : 
     229             :     private:
     230           0 :         explicit UniqueID(uint32_t id) : fID(id) {}
     231             : 
     232             :         uint32_t fID;
     233             :     };
     234             : 
     235             :     /*
     236             :      * The contract for the uniqueID is:
     237             :      *   for wrapped resources:
     238             :      *      the uniqueID will match that of the wrapped resource
     239             :      *
     240             :      *   for deferred resources:
     241             :      *      the uniqueID will be different from the real resource, when it is allocated
     242             :      *      the proxy's uniqueID will not change across the instantiate call
     243             :      *
     244             :      *    the uniqueIDs of the proxies and the resources draw from the same pool
     245             :      *
     246             :      * What this boils down to is that the uniqueID of a proxy can be used to consistently
     247             :      * track/identify a proxy but should never be used to distinguish between
     248             :      * resources and proxies - beware!
     249             :      */
     250           0 :     UniqueID uniqueID() const { return fUniqueID; }
     251             : 
     252             :     GrSurface* instantiate(GrResourceProvider* resourceProvider);
     253             : 
     254             :     /**
     255             :      * Helper that gets the width and height of the surface as a bounding rectangle.
     256             :      */
     257           0 :     SkRect getBoundsRect() const { return SkRect::MakeIWH(this->width(), this->height()); }
     258             : 
     259             :     int worstCaseWidth(const GrCaps& caps) const;
     260             :     int worstCaseHeight(const GrCaps& caps) const;
     261             : 
     262             :     /**
     263             :      * @return the texture proxy associated with the surface proxy, may be NULL.
     264             :      */
     265           0 :     virtual GrTextureProxy* asTextureProxy() { return nullptr; }
     266           0 :     virtual const GrTextureProxy* asTextureProxy() const { return nullptr; }
     267             : 
     268             :     /**
     269             :      * @return the render target proxy associated with the surface proxy, may be NULL.
     270             :      */
     271           0 :     virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; }
     272           0 :     virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; }
     273             : 
     274             :     /**
     275             :      * Does the resource count against the resource budget?
     276             :      */
     277           0 :     SkBudgeted isBudgeted() const { return fBudgeted; }
     278             : 
     279             :     void setLastOpList(GrOpList* opList);
     280           0 :     GrOpList* getLastOpList() { return fLastOpList; }
     281             : 
     282             :     GrRenderTargetOpList* getLastRenderTargetOpList();
     283             :     GrTextureOpList* getLastTextureOpList();
     284             : 
     285             :     /**
     286             :      * Retrieves the amount of GPU memory that will be or currently is used by this resource 
     287             :      * in bytes. It is approximate since we aren't aware of additional padding or copies made
     288             :      * by the driver.
     289             :      *
     290             :      * @return the amount of GPU memory used in bytes
     291             :      */
     292           0 :     size_t gpuMemorySize() const {
     293           0 :         if (kInvalidGpuMemorySize == fGpuMemorySize) {
     294           0 :             fGpuMemorySize = this->onGpuMemorySize();
     295           0 :             SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
     296             :         }
     297           0 :         return fGpuMemorySize;
     298             :     }
     299             : 
     300             :     // Helper function that creates a temporary SurfaceContext to perform the copy
     301             :     // It always returns a kExact-backed proxy bc it is used when converting an SkSpecialImage
     302             :     // to an SkImage.
     303             :     static sk_sp<GrTextureProxy> Copy(GrContext*, GrSurfaceProxy* src,
     304             :                                       SkIRect srcRect, SkBudgeted);
     305             : 
     306             :     // Copy the entire 'src'
     307             :     // It always returns a kExact-backed proxy bc it is used in SkGpuDevice::snapSpecial
     308             :     static sk_sp<GrTextureProxy> Copy(GrContext* context, GrSurfaceProxy* src,
     309             :                                       SkBudgeted budgeted);
     310             : 
     311             :     // Test-only entry point - should decrease in use as proxies propagate
     312             :     static sk_sp<GrSurfaceContext> TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
     313             :                                             GrSurfaceProxy* srcProxy);
     314             : 
     315             :     bool isWrapped_ForTesting() const;
     316             : 
     317             :     SkDEBUGCODE(void validate(GrContext*) const;)
     318             : 
     319             :     // Provides access to functions that aren't part of the public API.
     320             :     GrSurfaceProxyPriv priv();
     321             :     const GrSurfaceProxyPriv priv() const;
     322             : 
     323             : protected:
     324             :     // Deferred version
     325           0 :     GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags)
     326           0 :         : fDesc(desc)
     327             :         , fFit(fit)
     328             :         , fBudgeted(budgeted)
     329             :         , fFlags(flags)
     330             :         // fMipColorMode is only valid for texturable proxies
     331             :         , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy)
     332             :         , fGpuMemorySize(kInvalidGpuMemorySize)
     333           0 :         , fLastOpList(nullptr) {
     334             :         // Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources
     335           0 :     }
     336             : 
     337             :     // Wrapped version
     338             :     GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit);
     339             : 
     340             :     virtual ~GrSurfaceProxy();
     341             : 
     342             :     friend class GrSurfaceProxyPriv;
     343             : 
     344             :     // Methods made available via GrSurfaceProxyPriv
     345           0 :     bool hasPendingIO() const {
     346           0 :         return this->internalHasPendingIO();
     347             :     }
     348             : 
     349           0 :     bool hasPendingWrite() const {
     350           0 :         return this->internalHasPendingWrite();
     351             :     }
     352             : 
     353             :     // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource.
     354             :     GrSurfaceDesc        fDesc;
     355             :     SkBackingFit         fFit;      // always exact for wrapped resources
     356             :     mutable SkBudgeted   fBudgeted; // set from the backing resource for wrapped resources
     357             :                                     // mutable bc of SkSurface/SkImage wishy-washiness
     358             :     const uint32_t       fFlags;
     359             : 
     360             :     SkDestinationSurfaceColorMode fMipColorMode;
     361             : 
     362             :     const UniqueID       fUniqueID; // set from the backing resource for wrapped resources
     363             : 
     364             :     static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
     365           0 :     SkDEBUGCODE(size_t getRawGpuMemorySize_debugOnly() const { return fGpuMemorySize; })
     366             : 
     367             : private:
     368             :     virtual size_t onGpuMemorySize() const = 0;
     369             : 
     370             :     // This entry is lazily evaluated so, when the proxy wraps a resource, the resource
     371             :     // will be called but, when the proxy is deferred, it will compute the answer itself.
     372             :     // If the proxy computes its own answer that answer is checked (in debug mode) in
     373             :     // the instantiation method.
     374             :     mutable size_t      fGpuMemorySize;
     375             : 
     376             :     // The last opList that wrote to or is currently going to write to this surface
     377             :     // The opList can be closed (e.g., no render target context is currently bound
     378             :     // to this renderTarget).
     379             :     // This back-pointer is required so that we can add a dependancy between
     380             :     // the opList used to create the current contents of this surface
     381             :     // and the opList of a destination surface to which this one is being drawn or copied.
     382             :     GrOpList* fLastOpList;
     383             : 
     384             : 
     385             :     typedef GrIORefProxy INHERITED;
     386             : };
     387             : 
     388             : #endif

Generated by: LCOV version 1.13