Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2013 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 #include "SkTypes.h"
      9 
     10 #if SK_SUPPORT_GPU
     11 
     12 #include "GrContext.h"
     13 #include "GrContextPriv.h"
     14 #include "GrGpu.h"
     15 #include "GrResourceProvider.h"
     16 #include "GrTest.h"
     17 #include "GrTexture.h"
     18 #include "GrSurfacePriv.h"
     19 #include "SkMipMap.h"
     20 #include "Test.h"
     21 
     22 // Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
     23 // and render targets to GrSurface all work as expected.
     24 DEF_GPUTEST_FOR_NULLGL_CONTEXT(GrSurface, reporter, ctxInfo) {
     25     GrContext* context = ctxInfo.grContext();
     26     GrSurfaceDesc desc;
     27     desc.fConfig = kRGBA_8888_GrPixelConfig;
     28     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     29     desc.fWidth = 256;
     30     desc.fHeight = 256;
     31     desc.fSampleCnt = 0;
     32     sk_sp<GrSurface> texRT1 = context->resourceProvider()->createTexture(desc, SkBudgeted::kNo);
     33 
     34     REPORTER_ASSERT(reporter, texRT1.get() == texRT1->asRenderTarget());
     35     REPORTER_ASSERT(reporter, texRT1.get() == texRT1->asTexture());
     36     REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
     37                     texRT1->asTexture());
     38     REPORTER_ASSERT(reporter, texRT1->asRenderTarget() ==
     39                     static_cast<GrSurface*>(texRT1->asTexture()));
     40     REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
     41                     static_cast<GrSurface*>(texRT1->asTexture()));
     42 
     43     desc.fFlags = kNone_GrSurfaceFlags;
     44     sk_sp<GrTexture> tex1 = context->resourceProvider()->createTexture(desc, SkBudgeted::kNo);
     45     REPORTER_ASSERT(reporter, nullptr == tex1->asRenderTarget());
     46     REPORTER_ASSERT(reporter, tex1.get() == tex1->asTexture());
     47     REPORTER_ASSERT(reporter, static_cast<GrSurface*>(tex1.get()) == tex1->asTexture());
     48 
     49     GrBackendObject backendTexHandle = context->getGpu()->createTestingOnlyBackendTexture(
     50         nullptr, 256, 256, kRGBA_8888_GrPixelConfig);
     51     GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
     52                                                                256,
     53                                                                256,
     54                                                                kRGBA_8888_GrPixelConfig,
     55                                                                backendTexHandle);
     56 
     57     sk_sp<GrSurface> texRT2 = context->resourceProvider()->wrapBackendTexture(
     58         backendTex, kTopLeft_GrSurfaceOrigin, kRenderTarget_GrBackendTextureFlag, 0,
     59         kBorrow_GrWrapOwnership);
     60 
     61     REPORTER_ASSERT(reporter, texRT2.get() == texRT2->asRenderTarget());
     62     REPORTER_ASSERT(reporter, texRT2.get() == texRT2->asTexture());
     63     REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
     64                     texRT2->asTexture());
     65     REPORTER_ASSERT(reporter, texRT2->asRenderTarget() ==
     66                     static_cast<GrSurface*>(texRT2->asTexture()));
     67     REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
     68                     static_cast<GrSurface*>(texRT2->asTexture()));
     69 
     70     context->getGpu()->deleteTestingOnlyBackendTexture(backendTexHandle);
     71 }
     72 
     73 // This test checks that the isConfigTexturable and isConfigRenderable are
     74 // consistent with createTexture's result.
     75 DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
     76     GrContext* context = ctxInfo.grContext();
     77     GrResourceProvider* resourceProvider = context->resourceProvider();
     78     const GrCaps* caps = context->caps();
     79 
     80     GrPixelConfig configs[] = {
     81         kUnknown_GrPixelConfig,
     82         kAlpha_8_GrPixelConfig,
     83         kGray_8_GrPixelConfig,
     84         kRGB_565_GrPixelConfig,
     85         kRGBA_4444_GrPixelConfig,
     86         kRGBA_8888_GrPixelConfig,
     87         kBGRA_8888_GrPixelConfig,
     88         kSRGBA_8888_GrPixelConfig,
     89         kSBGRA_8888_GrPixelConfig,
     90         kRGBA_8888_sint_GrPixelConfig,
     91         kRGBA_float_GrPixelConfig,
     92         kRG_float_GrPixelConfig,
     93         kAlpha_half_GrPixelConfig,
     94         kRGBA_half_GrPixelConfig,
     95     };
     96     SkASSERT(kGrPixelConfigCnt == SK_ARRAY_COUNT(configs));
     97 
     98     GrSurfaceDesc desc;
     99     desc.fWidth = 64;
    100     desc.fHeight = 64;
    101 
    102     // Enough space for the first mip of our largest pixel config
    103     const size_t pixelBufferSize = desc.fWidth * desc.fHeight *
    104                                    GrBytesPerPixel(kRGBA_float_GrPixelConfig);
    105     std::unique_ptr<char[]> pixelData(new char[pixelBufferSize]);
    106     memset(pixelData.get(), 0, pixelBufferSize);
    107 
    108     // We re-use the same mip level objects (with updated pointers and rowBytes) for each config
    109     const int levelCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
    110     std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[levelCount]);
    111 
    112     for (GrPixelConfig config : configs) {
    113         for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
    114             desc.fFlags = kNone_GrSurfaceFlags;
    115             desc.fOrigin = origin;
    116             desc.fSampleCnt = 0;
    117             desc.fConfig = config;
    118 
    119             sk_sp<GrSurface> tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
    120             REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigTexturable(desc.fConfig));
    121 
    122             size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
    123             for (int i = 0; i < levelCount; ++i) {
    124                 texels[i].fPixels = pixelData.get();
    125                 texels[i].fRowBytes = rowBytes >> i;
    126             }
    127             sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferredMipMap(resourceProvider,
    128                                                                              desc, SkBudgeted::kNo,
    129                                                                              texels.get(),
    130                                                                              levelCount);
    131             REPORTER_ASSERT(reporter, SkToBool(proxy.get()) ==
    132                             (caps->isConfigTexturable(desc.fConfig) &&
    133                              caps->mipMapSupport() &&
    134                              !GrPixelConfigIsSint(desc.fConfig)));
    135 
    136             desc.fFlags = kRenderTarget_GrSurfaceFlag;
    137             tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
    138             REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, false));
    139 
    140             desc.fSampleCnt = 4;
    141             tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
    142             REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, true));
    143         }
    144     }
    145 }
    146 
    147 #include "GrDrawingManager.h"
    148 #include "GrSurfaceProxy.h"
    149 #include "GrTextureContext.h"
    150 
    151 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info) {
    152     static constexpr int kSize = 100;
    153     GrSurfaceDesc desc;
    154     desc.fWidth = desc.fHeight = kSize;
    155     std::unique_ptr<uint32_t[]> data(new uint32_t[kSize * kSize]);
    156     GrContext* context = context_info.grContext();
    157     for (int c = 0; c <= kLast_GrPixelConfig; ++c) {
    158         desc.fConfig = static_cast<GrPixelConfig>(c);
    159         if (!context_info.grContext()->caps()->isConfigTexturable(desc.fConfig)) {
    160             continue;
    161         }
    162         desc.fFlags = kPerformInitialClear_GrSurfaceFlag;
    163         for (bool rt : {false, true}) {
    164             if (rt && !context->caps()->isConfigRenderable(desc.fConfig, false)) {
    165                 continue;
    166             }
    167             desc.fFlags |= rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
    168             for (bool mipped : {false, true}) {
    169                 desc.fIsMipMapped = mipped;
    170                 for (GrSurfaceOrigin origin :
    171                      {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
    172                     desc.fOrigin = origin;
    173                     for (bool approx : {false, true}) {
    174                         auto resourceProvider = context->resourceProvider();
    175                         // Try directly creating the texture.
    176                         // Do this twice in an attempt to hit the cache on the second time through.
    177                         for (int i = 0; i < 2; ++i) {
    178                             sk_sp<GrTexture> tex;
    179                             if (approx) {
    180                                 tex = sk_sp<GrTexture>(
    181                                         resourceProvider->createApproxTexture(desc, 0));
    182                             } else {
    183                                 tex = resourceProvider->createTexture(desc, SkBudgeted::kYes);
    184                             }
    185                             if (!tex) {
    186                                 continue;
    187                             }
    188                             auto proxy = GrSurfaceProxy::MakeWrapped(std::move(tex));
    189                             auto texCtx = context->contextPriv().makeWrappedSurfaceContext(
    190                                     std::move(proxy), nullptr);
    191                             SkImageInfo info = SkImageInfo::Make(
    192                                     kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    193                             memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t));
    194                             if (texCtx->readPixels(info, data.get(), 0, 0, 0)) {
    195                                 uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0;
    196                                 for (int i = 0; i < kSize * kSize; ++i) {
    197                                     if (cmp != data.get()[i]) {
    198                                         ERRORF(reporter, "Failed on config %d", desc.fConfig);
    199                                         break;
    200                                     }
    201                                 }
    202                             }
    203                             memset(data.get(), 0xBC, kSize * kSize * sizeof(uint32_t));
    204                             // Here we overwrite the texture so that the second time through we
    205                             // test against recycling without reclearing.
    206                             if (0 == i) {
    207                                 texCtx->writePixels(info, data.get(), 0, 0, 0);
    208                             }
    209                         }
    210                         context->purgeAllUnlockedResources();
    211 
    212                         // Try creating the texture as a deferred proxy.
    213                         for (int i = 0; i < 2; ++i) {
    214                             auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
    215                                     desc, approx ? SkBackingFit::kApprox : SkBackingFit::kExact,
    216                                     SkBudgeted::kYes);
    217                             if (!surfCtx) {
    218                                 continue;
    219                             }
    220                             SkImageInfo info = SkImageInfo::Make(
    221                                     kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    222                             memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t));
    223                             if (surfCtx->readPixels(info, data.get(), 0, 0, 0)) {
    224                                 uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0;
    225                                 for (int i = 0; i < kSize * kSize; ++i) {
    226                                     if (cmp != data.get()[i]) {
    227                                         ERRORF(reporter, "Failed on config %d", desc.fConfig);
    228                                         break;
    229                                     }
    230                                 }
    231                             }
    232                             // Here we overwrite the texture so that the second time through we
    233                             // test against recycling without reclearing.
    234                             if (0 == i) {
    235                                 surfCtx->writePixels(info, data.get(), 0, 0, 0);
    236                             }
    237                         }
    238                         context->purgeAllUnlockedResources();
    239                     }
    240                 }
    241             }
    242         }
    243     }
    244 }
    245 #endif
    246