Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2017 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 "GrBackendSurface.h"
     13 #include "GrBackendTextureImageGenerator.h"
     14 #include "GrContext.h"
     15 #include "GrContextPriv.h"
     16 #include "GrGpu.h"
     17 #include "GrRenderTargetContext.h"
     18 #include "GrSemaphore.h"
     19 #include "GrSurfaceProxyPriv.h"
     20 #include "GrTest.h"
     21 #include "GrTexturePriv.h"
     22 #include "GrTextureProxy.h"
     23 #include "SkCanvas.h"
     24 #include "SkImage_Base.h"
     25 #include "SkGpuDevice.h"
     26 #include "SkPoint.h"
     27 #include "SkSurface.h"
     28 #include "SkSurface_Gpu.h"
     29 #include "Test.h"
     30 
     31 static constexpr int kSize = 8;
     32 
     33 // Test that the correct mip map states are on the GrTextures when wrapping GrBackendTextures in
     34 // SkImages and SkSurfaces
     35 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) {
     36     GrContext* context = ctxInfo.grContext();
     37     if (!context->caps()->mipMapSupport()) {
     38         return;
     39     }
     40     GrGpu* gpu = context->contextPriv().getGpu();
     41 
     42     for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
     43         for (auto isRT : {false, true}) {
     44             // CreateTestingOnlyBackendTexture currently doesn't support uploading data to mip maps
     45             // so we don't send any. However, we pretend there is data for the checks below which is
     46             // fine since we are never actually using these textures for any work on the gpu.
     47             GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
     48                     nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, isRT, mipMapped);
     49 
     50             sk_sp<GrTextureProxy> proxy;
     51             sk_sp<SkImage> image;
     52             if (isRT) {
     53                 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(
     54                                                                            context,
     55                                                                            backendTex,
     56                                                                            kTopLeft_GrSurfaceOrigin,
     57                                                                            0,
     58                                                                            kRGBA_8888_SkColorType,
     59                                                                            nullptr,
     60                                                                            nullptr);
     61 
     62                 SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
     63                 proxy = device->accessRenderTargetContext()->asTextureProxyRef();
     64             } else {
     65                 image = SkImage::MakeFromTexture(context, backendTex,
     66                                                  kTopLeft_GrSurfaceOrigin,
     67                                                  kRGBA_8888_SkColorType,
     68                                                  kPremul_SkAlphaType, nullptr,
     69                                                  nullptr, nullptr);
     70                 proxy = as_IB(image)->asTextureProxyRef();
     71             }
     72             REPORTER_ASSERT(reporter, proxy);
     73             if (!proxy) {
     74                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
     75                 return;
     76             }
     77 
     78             REPORTER_ASSERT(reporter, proxy->priv().isInstantiated());
     79 
     80             GrTexture* texture = proxy->priv().peekTexture();
     81             REPORTER_ASSERT(reporter, texture);
     82             if (!texture) {
     83                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
     84                 return;
     85             }
     86 
     87             if (GrMipMapped::kYes == mipMapped) {
     88                 REPORTER_ASSERT(reporter, GrMipMapped::kYes == texture->texturePriv().mipMapped());
     89                 if (isRT) {
     90                     REPORTER_ASSERT(reporter, texture->texturePriv().mipMapsAreDirty());
     91                 } else {
     92                     REPORTER_ASSERT(reporter, !texture->texturePriv().mipMapsAreDirty());
     93                 }
     94             } else {
     95                 REPORTER_ASSERT(reporter, GrMipMapped::kNo == texture->texturePriv().mipMapped());
     96             }
     97             gpu->deleteTestingOnlyBackendTexture(&backendTex);
     98         }
     99     }
    100 }
    101 
    102 // Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator
    103 // based on if we will use mips in the draw and the mip status of the GrBackendTexture.
    104 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, ctxInfo) {
    105     GrContext* context = ctxInfo.grContext();
    106     if (!context->caps()->mipMapSupport()) {
    107         return;
    108     }
    109     GrGpu* gpu = context->contextPriv().getGpu();
    110 
    111     for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
    112         for (auto willUseMips : {false, true}) {
    113             GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
    114                     nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, mipMapped);
    115 
    116             sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backendTex,
    117                                                             kTopLeft_GrSurfaceOrigin,
    118                                                             kRGBA_8888_SkColorType,
    119                                                             kPremul_SkAlphaType, nullptr,
    120                                                             nullptr, nullptr);
    121 
    122             GrTextureProxy* proxy = as_IB(image)->peekProxy();
    123             REPORTER_ASSERT(reporter, proxy);
    124             if (!proxy) {
    125                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    126                 return;
    127             }
    128 
    129             REPORTER_ASSERT(reporter, proxy->priv().isInstantiated());
    130 
    131             sk_sp<GrTexture> texture = sk_ref_sp(proxy->priv().peekTexture());
    132             REPORTER_ASSERT(reporter, texture);
    133             if (!texture) {
    134                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    135                 return;
    136             }
    137 
    138             std::unique_ptr<SkImageGenerator> imageGen = GrBackendTextureImageGenerator::Make(
    139                     texture, kTopLeft_GrSurfaceOrigin, nullptr, kPremul_SkAlphaType, nullptr);
    140             REPORTER_ASSERT(reporter, imageGen);
    141             if (!imageGen) {
    142                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    143                 return;
    144             }
    145 
    146             SkIPoint origin = SkIPoint::Make(0,0);
    147             // The transfer function behavior isn't used in the generator so set we set it
    148             // arbitrarily here.
    149             SkTransferFunctionBehavior behavior = SkTransferFunctionBehavior::kIgnore;
    150             SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
    151                                                       kPremul_SkAlphaType);
    152             sk_sp<GrTextureProxy> genProxy = imageGen->generateTexture(context, imageInfo,
    153                                                                        origin, behavior,
    154                                                                        willUseMips);
    155 
    156             REPORTER_ASSERT(reporter, genProxy);
    157             if (!genProxy) {
    158                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    159                 return;
    160             }
    161 
    162             if (GrSurfaceProxy::LazyState::kNot != genProxy->lazyInstantiationState()) {
    163                 genProxy->priv().doLazyInstantiation(context->contextPriv().resourceProvider());
    164             }
    165 
    166             REPORTER_ASSERT(reporter, genProxy->priv().isInstantiated());
    167             if (!genProxy->priv().isInstantiated()) {
    168                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    169                 return;
    170             }
    171 
    172             GrTexture* genTexture = genProxy->priv().peekTexture();
    173             REPORTER_ASSERT(reporter, genTexture);
    174             if (!genTexture) {
    175                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    176                 return;
    177             }
    178 
    179             GrBackendTexture genBackendTex = genTexture->getBackendTexture();
    180 
    181             if (const GrGLTextureInfo* genTexInfo = genBackendTex.getGLTextureInfo()) {
    182                 const GrGLTextureInfo* origTexInfo = backendTex.getGLTextureInfo();
    183                 if (willUseMips && GrMipMapped::kNo == mipMapped) {
    184                     // We did a copy so the texture IDs should be different
    185                     REPORTER_ASSERT(reporter, origTexInfo->fID != genTexInfo->fID);
    186                 } else {
    187                     REPORTER_ASSERT(reporter, origTexInfo->fID == genTexInfo->fID);
    188                 }
    189 #ifdef SK_VULKAN
    190             } else if (const GrVkImageInfo* genImageInfo = genBackendTex.getVkImageInfo()) {
    191                 const GrVkImageInfo* origImageInfo = backendTex.getVkImageInfo();
    192                 if (willUseMips && GrMipMapped::kNo == mipMapped) {
    193                     // We did a copy so the texture IDs should be different
    194                     REPORTER_ASSERT(reporter, origImageInfo->fImage != genImageInfo->fImage);
    195                 } else {
    196                     REPORTER_ASSERT(reporter, origImageInfo->fImage == genImageInfo->fImage);
    197                 }
    198 #endif
    199             } else {
    200                 REPORTER_ASSERT(reporter, false);
    201             }
    202 
    203             // Must make sure the uses of the backend texture have finished (we possibly have a
    204             // queued up copy) before we delete the backend texture.
    205             context->flush();
    206             gpu->testingOnly_flushGpuAndSync();
    207 
    208             gpu->deleteTestingOnlyBackendTexture(&backendTex);
    209         }
    210     }
    211 }
    212 
    213 // Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the
    214 // resource we took the snapshot of.
    215 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest, reporter, ctxInfo) {
    216     GrContext* context = ctxInfo.grContext();
    217     if (!context->caps()->mipMapSupport()) {
    218         return;
    219     }
    220 
    221     auto resourceProvider = context->contextPriv().resourceProvider();
    222     GrGpu* gpu = context->contextPriv().getGpu();
    223 
    224     for (auto willUseMips : {false, true}) {
    225         for (auto isWrapped : {false, true}) {
    226             GrMipMapped mipMapped = willUseMips ? GrMipMapped::kYes : GrMipMapped::kNo;
    227             sk_sp<SkSurface> surface;
    228             GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
    229                     nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, true, mipMapped);
    230             if (isWrapped) {
    231                 surface = SkSurface::MakeFromBackendTexture(context,
    232                                                             backendTex,
    233                                                             kTopLeft_GrSurfaceOrigin,
    234                                                             0,
    235                                                             kRGBA_8888_SkColorType,
    236                                                             nullptr,
    237                                                             nullptr);
    238             } else {
    239                 SkImageInfo info = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
    240                                                      kPremul_SkAlphaType);
    241                 surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
    242                                                       kTopLeft_GrSurfaceOrigin, nullptr,
    243                                                       willUseMips);
    244             }
    245             REPORTER_ASSERT(reporter, surface);
    246             if (!surface) {
    247                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    248             }
    249             SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
    250             GrTextureProxy* texProxy = device->accessRenderTargetContext()->asTextureProxy();
    251             REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
    252 
    253             texProxy->instantiate(resourceProvider);
    254             GrTexture* texture = texProxy->priv().peekTexture();
    255             REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
    256 
    257             sk_sp<SkImage> image = surface->makeImageSnapshot();
    258             REPORTER_ASSERT(reporter, image);
    259             if (!image) {
    260                 gpu->deleteTestingOnlyBackendTexture(&backendTex);
    261             }
    262             texProxy = as_IB(image)->peekProxy();
    263             REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
    264 
    265             texProxy->instantiate(resourceProvider);
    266             texture = texProxy->priv().peekTexture();
    267             REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
    268 
    269             // Must flush the context to make sure all the cmds (copies, etc.) from above are sent
    270             // to the gpu before we delete the backendHandle.
    271             context->flush();
    272             gpu->deleteTestingOnlyBackendTexture(&backendTex);
    273         }
    274     }
    275 }
    276 
    277 #endif
    278