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 "GrRenderTargetProxy.h"
     16 #include "GrResourceProvider.h"
     17 #include "GrSurfaceProxy.h"
     18 #include "GrTexture.h"
     19 #include "GrTextureProxy.h"
     20 
     21 int32_t GrIORefProxy::getProxyRefCnt_TestOnly() const {
     22     return fRefCnt;
     23 }
     24 
     25 int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const {
     26     if (fTarget) {
     27         return fTarget->fRefCnt;
     28     }
     29 
     30     return fRefCnt;
     31 }
     32 
     33 int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const {
     34     if (fTarget) {
     35         return fTarget->fPendingReads;
     36     }
     37 
     38     return fPendingReads;
     39 }
     40 
     41 int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const {
     42     if (fTarget) {
     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                        GrTextureProxy* 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<GrTextureProxy> make_deferred(GrContext* context) {
     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(context->resourceProvider(), desc,
     76                                         SkBackingFit::kApprox, SkBudgeted::kYes,
     77                                         GrResourceProvider::kNoPendingIO_Flag);
     78 }
     79 
     80 static sk_sp<GrTextureProxy> make_wrapped(GrContext* context) {
     81     GrSurfaceDesc desc;
     82     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     83     desc.fWidth = kWidthHeight;
     84     desc.fHeight = kWidthHeight;
     85     desc.fConfig = kRGBA_8888_GrPixelConfig;
     86 
     87     sk_sp<GrTexture> tex(context->resourceProvider()->createTexture(desc, SkBudgeted::kNo));
     88 
     89     return GrSurfaceProxy::MakeWrapped(std::move(tex));
     90 }
     91 
     92 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) {
     93     GrResourceProvider* provider = ctxInfo.grContext()->resourceProvider();
     94 
     95     for (auto make : { make_deferred, make_wrapped }) {
     96         // A single write
     97         {
     98             sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
     99 
    100             GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
    101 
    102             static const int kExpectedReads = 0;
    103             static const int kExpectedWrites = 1;
    104 
    105             check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    106 
    107             proxy->instantiate(provider);
    108 
    109             // In the deferred case, this checks that the refs transfered to the GrSurface
    110             check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    111         }
    112 
    113         // A single read
    114         {
    115             sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
    116 
    117             GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
    118 
    119             static const int kExpectedReads = 1;
    120             static const int kExpectedWrites = 0;
    121 
    122             check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    123 
    124             proxy->instantiate(provider);
    125 
    126             // In the deferred case, this checks that the refs transfered to the GrSurface
    127             check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    128         }
    129 
    130         // A single read/write pair
    131         {
    132             sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
    133 
    134             GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(proxy.get());
    135 
    136             static const int kExpectedReads = 1;
    137             static const int kExpectedWrites = 1;
    138 
    139             check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    140 
    141             proxy->instantiate(provider);
    142 
    143             // In the deferred case, this checks that the refs transferred to the GrSurface
    144             check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
    145         }
    146 
    147         // Multiple normal refs
    148         {
    149             sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
    150             proxy->ref();
    151             proxy->ref();
    152 
    153             static const int kExpectedReads = 0;
    154             static const int kExpectedWrites = 0;
    155 
    156             check_refs(reporter, proxy.get(), 3, 3,kExpectedReads, kExpectedWrites);
    157 
    158             proxy->instantiate(provider);
    159 
    160             // In the deferred case, this checks that the refs transferred to the GrSurface
    161             check_refs(reporter, proxy.get(), 3, 3, kExpectedReads, kExpectedWrites);
    162 
    163             proxy->unref();
    164             proxy->unref();
    165         }
    166 
    167         // Continue using (reffing) proxy after instantiation
    168         {
    169             sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
    170             proxy->ref();
    171 
    172             GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
    173 
    174             static const int kExpectedWrites = 1;
    175 
    176             check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites);
    177 
    178             proxy->instantiate(provider);
    179 
    180             // In the deferred case, this checks that the refs transfered to the GrSurface
    181             check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites);
    182 
    183             proxy->unref();
    184             check_refs(reporter, proxy.get(), 1, 1, 0, kExpectedWrites);
    185 
    186             GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
    187             check_refs(reporter, proxy.get(), 1, 1, 1, kExpectedWrites);
    188         }
    189     }
    190 }
    191 
    192 #endif
    193