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 "GrRenderTargetPriv.h"
     14 #include "GrRenderTargetProxy.h"
     15 #include "GrResourceProvider.h"
     16 #include "GrSurfaceProxy.h"
     17 #include "GrTextureProxy.h"
     18 
     19 int32_t GrIORefProxy::getProxyRefCnt_TestOnly() const {
     20     return fRefCnt;
     21 }
     22 
     23 int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const {
     24     if (fTarget) {
     25         return fTarget->fRefCnt;
     26     }
     27 
     28     return fRefCnt;
     29 }
     30 
     31 int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const {
     32     if (fTarget) {
     33         SkASSERT(!fPendingReads);
     34         return fTarget->fPendingReads;
     35     }
     36 
     37     return fPendingReads;
     38 }
     39 
     40 int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const {
     41     if (fTarget) {
     42         SkASSERT(!fPendingWrites);
     43         return fTarget->fPendingWrites;
     44     }
     45 
     46     return fPendingWrites;
     47 }
     48 
     49 static const int kWidthHeight = 128;
     50 
     51 static void check_refs(skiatest::Reporter* reporter,
     52                        GrSurfaceProxy* proxy,
     53                        int32_t expectedProxyRefs,
     54                        int32_t expectedBackingRefs,
     55                        int32_t expectedNumReads,
     56                        int32_t expectedNumWrites) {
     57     REPORTER_ASSERT(reporter, proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs);
     58     REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
     59     REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
     60     REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
     61 
     62     SkASSERT(proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs);
     63     SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
     64     SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
     65     SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
     66 }
     67 
     68 static sk_sp<GrSurfaceProxy> make_deferred(GrResourceProvider* provider) {
     69     GrSurfaceDesc desc;
     70     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     71     desc.fWidth = kWidthHeight;
     72     desc.fHeight = kWidthHeight;
     73     desc.fConfig = kRGBA_8888_GrPixelConfig;
     74 
     75     return GrSurfaceProxy::MakeDeferred(provider, desc,
     76                                         SkBackingFit::kApprox, SkBudgeted::kYes);
     77 }
     78 
     79 static sk_sp<GrSurfaceProxy> make_wrapped(GrResourceProvider* provider) {
     80     GrSurfaceDesc desc;
     81     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     82     desc.fWidth = kWidthHeight;
     83     desc.fHeight = kWidthHeight;
     84     desc.fConfig = kRGBA_8888_GrPixelConfig;
     85 
     86     sk_sp<GrTexture> tex(provider->createTexture(desc, SkBudgeted::kNo));
     87 
     88     // Flush the IOWrite from the initial discard or it will confuse the later ref count checks
     89     tex->flushWrites();
     90 
     91     return GrSurfaceProxy::MakeWrapped(std::move(tex));
     92 }
     93 
     94 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) {
     95     GrResourceProvider* provider = ctxInfo.grContext()->resourceProvider();
     96     const GrCaps& caps = *ctxInfo.grContext()->caps();
     97 
     98     // Currently the op itself takes a pending write and the render target op list does as well.
     99     static const int kWritesForDiscard = 2;
    100     for (auto make : { make_deferred, make_wrapped }) {
    101         // A single write
    102         {
    103             sk_sp<GrSurfaceProxy> sProxy((*make)(provider));
    104 
    105             GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get());
    106 
    107             check_refs(reporter, sProxy.get(), 1, 1, 0, 1);
    108 
    109             // In the deferred case, the discard op created on instantiation adds an
    110             // extra ref and write
    111             bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() &&
    112                                        caps.discardRenderTargetSupport();
    113             int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0);
    114 
    115             sProxy->instantiate(provider);
    116 
    117             // In the deferred case, this checks that the refs transfered to the GrSurface
    118             check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites);
    119         }
    120 
    121         // A single read
    122         {
    123             sk_sp<GrSurfaceProxy> sProxy((*make)(provider));
    124 
    125             GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get());
    126 
    127             check_refs(reporter, sProxy.get(), 1, 1, 1, 0);
    128 
    129             // In the deferred case, the discard op created on instantiation adds an
    130             // extra ref and write
    131             bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() &&
    132                                        caps.discardRenderTargetSupport();
    133             int expectedWrites = proxyGetsDiscardRef ? kWritesForDiscard : 0;
    134 
    135             sProxy->instantiate(provider);
    136 
    137             // In the deferred case, this checks that the refs transfered to the GrSurface
    138             check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites);
    139         }
    140 
    141         // A single read/write pair
    142         {
    143             sk_sp<GrSurfaceProxy> sProxy((*make)(provider));
    144 
    145             GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(sProxy.get());
    146 
    147             check_refs(reporter, sProxy.get(), 1, 1, 1, 1);
    148 
    149             // In the deferred case, the discard op created on instantiation adds an
    150             // extra ref and write
    151             bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() &&
    152                                        caps.discardRenderTargetSupport();
    153             int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0);
    154 
    155             sProxy->instantiate(provider);
    156 
    157             // In the deferred case, this checks that the refs transferred to the GrSurface
    158             check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites);
    159         }
    160 
    161         // Multiple normal refs
    162         {
    163             sk_sp<GrSurfaceProxy> sProxy((*make)(provider));
    164             sProxy->ref();
    165             sProxy->ref();
    166 
    167             check_refs(reporter, sProxy.get(), 3, 3, 0, 0);
    168 
    169             bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() &&
    170                                        caps.discardRenderTargetSupport();
    171             int expectedWrites = proxyGetsDiscardRef ? kWritesForDiscard : 0;
    172 
    173             sProxy->instantiate(provider);
    174 
    175             // In the deferred case, this checks that the refs transferred to the GrSurface
    176             check_refs(reporter, sProxy.get(), 3, 3, 0, expectedWrites);
    177 
    178             sProxy->unref();
    179             sProxy->unref();
    180         }
    181 
    182         // Continue using (reffing) proxy after instantiation
    183         {
    184             sk_sp<GrSurfaceProxy> sProxy((*make)(provider));
    185             sProxy->ref();
    186 
    187             GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get());
    188 
    189             check_refs(reporter, sProxy.get(), 2, 2, 0, 1);
    190 
    191             bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() &&
    192                                        caps.discardRenderTargetSupport();
    193             int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0);
    194 
    195             sProxy->instantiate(provider);
    196 
    197             // In the deferred case, this checks that the refs transfered to the GrSurface
    198             check_refs(reporter, sProxy.get(), 2, 2, 0, expectedWrites);
    199 
    200             sProxy->unref();
    201             check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites);
    202 
    203             GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get());
    204             check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites);
    205         }
    206     }
    207 }
    208 #endif
    209