Home | History | Annotate | Download | only in tests
      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 // This is a GPU-backend specific test.
      9 
     10 #include "Test.h"
     11 
     12 #if SK_SUPPORT_GPU
     13 #include "GrContextPriv.h"
     14 #include "GrGpuResourceRef.h"
     15 #include "GrProxyProvider.h"
     16 #include "GrRenderTargetProxy.h"
     17 #include "GrResourceProvider.h"
     18 #include "GrSurfaceProxy.h"
     19 #include "GrTexture.h"
     20 #include "GrTextureProxy.h"
     21 
     22 int32_t GrIORefProxy::getProxyRefCnt_TestOnly() const {
     23     return fRefCnt;
     24 }
     25 
     26 int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const {
     27     if (fTarget) {
     28         return fTarget->fRefCnt;
     29     }
     30 
     31     return fRefCnt;
     32 }
     33 
     34 int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const {
     35     if (fTarget) {
     36         return fTarget->fPendingReads;
     37     }
     38 
     39     return fPendingReads;
     40 }
     41 
     42 int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const {
     43     if (fTarget) {
     44         return fTarget->fPendingWrites;
     45     }
     46 
     47     return fPendingWrites;
     48 }
     49 
     50 static const int kWidthHeight = 128;
     51 
     52 static void check_refs(skiatest::Reporter* reporter,
     53                        GrTextureProxy* proxy,
     54                        int32_t expectedProxyRefs,
     55                        int32_t expectedBackingRefs,
     56                        int32_t expectedNumReads,
     57                        int32_t expectedNumWrites) {
     58     REPORTER_ASSERT(reporter, proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs);
     59     REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
     60     REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
     61     REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
     62 
     63     SkASSERT(proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs);
     64     SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
     65     SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
     66     SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
     67 }
     68 
     69 static sk_sp<GrTextureProxy> make_deferred(GrProxyProvider* proxyProvider) {
     70     GrSurfaceDesc desc;
     71     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     72     desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     73     desc.fWidth = kWidthHeight;
     74     desc.fHeight = kWidthHeight;
     75     desc.fConfig = kRGBA_8888_GrPixelConfig;
     76 
     77     return proxyProvider->createProxy(desc, SkBackingFit::kApprox, SkBudgeted::kYes,
     78                                       GrResourceProvider::kNoPendingIO_Flag);
     79 }
     80 
     81 static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider) {
     82     GrSurfaceDesc desc;
     83     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     84     desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     85     desc.fWidth = kWidthHeight;
     86     desc.fHeight = kWidthHeight;
     87     desc.fConfig = kRGBA_8888_GrPixelConfig;
     88 
     89     return proxyProvider->createInstantiatedProxy(desc, SkBackingFit::kExact, SkBudgeted::kNo);
     90 }
     91 
     92 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) {
     93     GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
     94     GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
     95 
     96     for (auto make : { make_deferred, make_wrapped }) {
     97         // A single write
     98         {
     99             sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
    100             if (proxy.get()) {
    101                 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
    102 
    103                 static const int kExpectedReads = 0;
    104                 static const int kExpectedWrites = 1;
    105 
    106                 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    107 
    108                 proxy->instantiate(resourceProvider);
    109 
    110                 // In the deferred case, this checks that the refs transfered to the GrSurface
    111                 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    112             }
    113         }
    114 
    115         // A single read
    116         {
    117             sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
    118             if (proxy.get()) {
    119                 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
    120 
    121                 static const int kExpectedReads = 1;
    122                 static const int kExpectedWrites = 0;
    123 
    124                 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    125 
    126                 proxy->instantiate(resourceProvider);
    127 
    128                 // In the deferred case, this checks that the refs transfered to the GrSurface
    129                 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    130             }
    131         }
    132 
    133         // A single read/write pair
    134         {
    135             sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
    136             if (proxy.get()) {
    137                 GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(proxy.get());
    138 
    139                 static const int kExpectedReads = 1;
    140                 static const int kExpectedWrites = 1;
    141 
    142                 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    143 
    144                 proxy->instantiate(resourceProvider);
    145 
    146                 // In the deferred case, this checks that the refs transferred to the GrSurface
    147                 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    148             }
    149         }
    150 
    151         // Multiple normal refs
    152         {
    153             sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
    154             if (proxy.get()) {
    155                 proxy->ref();
    156                 proxy->ref();
    157 
    158                 static const int kExpectedReads = 0;
    159                 static const int kExpectedWrites = 0;
    160 
    161                 check_refs(reporter, proxy.get(), 3, 3,kExpectedReads, kExpectedWrites);
    162 
    163                 proxy->instantiate(resourceProvider);
    164 
    165                 // In the deferred case, this checks that the refs transferred to the GrSurface
    166                 check_refs(reporter, proxy.get(), 3, 3, kExpectedReads, kExpectedWrites);
    167 
    168                 proxy->unref();
    169                 proxy->unref();
    170             }
    171         }
    172 
    173         // Continue using (reffing) proxy after instantiation
    174         {
    175             sk_sp<GrTextureProxy> proxy((*make)(proxyProvider));
    176             if (proxy.get()) {
    177                 proxy->ref();
    178 
    179                 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
    180 
    181                 static const int kExpectedWrites = 1;
    182 
    183                 check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites);
    184 
    185                 proxy->instantiate(resourceProvider);
    186 
    187                 // In the deferred case, this checks that the refs transfered to the GrSurface
    188                 check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites);
    189 
    190                 proxy->unref();
    191                 check_refs(reporter, proxy.get(), 1, 1, 0, kExpectedWrites);
    192 
    193                 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
    194                 check_refs(reporter, proxy.get(), 1, 1, 1, kExpectedWrites);
    195             }
    196         }
    197     }
    198 }
    199 
    200 #endif
    201