GrMipMappedTest.cpp revision 261b8aa1de8562f79c1a7c515d968787e027a2c8
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// Test that the correct mip map states are on the GrTextures when wrapping GrBackendTextures in 32// SkImages and SkSurfaces 33DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) { 34 GrContext* context = ctxInfo.grContext(); 35 if (!context->caps()->mipMapSupport()) { 36 return; 37 } 38 for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) { 39 for (auto isRT : {false, true}) { 40 // CreateTestingOnlyBackendTexture currently doesn't support uploading data to mip maps 41 // so we don't send any. However, we pretend there is data for the checks below which is 42 // fine since we are never actually using these textures for any work on the gpu. 43 GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture( 44 nullptr, 8, 8, kRGBA_8888_GrPixelConfig, isRT, mipMapped); 45 46 GrBackend backend = context->contextPriv().getBackend(); 47 GrBackendTexture backendTex = GrTest::CreateBackendTexture(backend, 48 8, 49 8, 50 kRGBA_8888_GrPixelConfig, 51 mipMapped, 52 backendHandle); 53 54 GrTextureProxy* proxy; 55 sk_sp<SkImage> image; 56 if (isRT) { 57 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture( 58 context, 59 backendTex, 60 kTopLeft_GrSurfaceOrigin, 61 0, 62 nullptr, 63 nullptr); 64 65 SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice(); 66 proxy = device->accessRenderTargetContext()->asTextureProxy(); 67 } else { 68 image = SkImage::MakeFromTexture(context, backendTex, 69 kTopLeft_GrSurfaceOrigin, 70 kPremul_SkAlphaType, nullptr); 71 proxy = as_IB(image)->peekProxy(); 72 } 73 REPORTER_ASSERT(reporter, proxy); 74 if (!proxy) { 75 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 76 return; 77 } 78 79 REPORTER_ASSERT(reporter, proxy->priv().isInstantiated()); 80 81 GrTexture* texture = proxy->priv().peekTexture(); 82 REPORTER_ASSERT(reporter, texture); 83 if (!texture) { 84 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 85 return; 86 } 87 88 if (GrMipMapped::kYes == mipMapped) { 89 REPORTER_ASSERT(reporter, texture->texturePriv().hasMipMaps()); 90 if (isRT) { 91 REPORTER_ASSERT(reporter, texture->texturePriv().mipMapsAreDirty()); 92 } else { 93 REPORTER_ASSERT(reporter, !texture->texturePriv().mipMapsAreDirty()); 94 } 95 } else { 96 REPORTER_ASSERT(reporter, !texture->texturePriv().hasMipMaps()); 97 } 98 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 99 } 100 } 101} 102 103// Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator 104// based on if we will use mips in the draw and the mip status of the GrBackendTexture. 105DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, ctxInfo) { 106 static const int kSize = 8; 107 108 GrContext* context = ctxInfo.grContext(); 109 if (!context->caps()->mipMapSupport()) { 110 return; 111 } 112 for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) { 113 for (auto willUseMips : {false, true}) { 114 GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture( 115 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, mipMapped); 116 117 GrBackend backend = context->contextPriv().getBackend(); 118 GrBackendTexture backendTex = GrTest::CreateBackendTexture(backend, 119 kSize, 120 kSize, 121 kRGBA_8888_GrPixelConfig, 122 mipMapped, 123 backendHandle); 124 125 sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backendTex, 126 kTopLeft_GrSurfaceOrigin, 127 kPremul_SkAlphaType, nullptr); 128 129 GrTextureProxy* proxy = as_IB(image)->peekProxy(); 130 REPORTER_ASSERT(reporter, proxy); 131 if (!proxy) { 132 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 133 return; 134 } 135 136 REPORTER_ASSERT(reporter, proxy->priv().isInstantiated()); 137 138 sk_sp<GrTexture> texture = sk_ref_sp(proxy->priv().peekTexture()); 139 REPORTER_ASSERT(reporter, texture); 140 if (!texture) { 141 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 142 return; 143 } 144 145 std::unique_ptr<SkImageGenerator> imageGen = GrBackendTextureImageGenerator::Make( 146 texture, kTopLeft_GrSurfaceOrigin, nullptr, kPremul_SkAlphaType, nullptr); 147 REPORTER_ASSERT(reporter, imageGen); 148 if (!imageGen) { 149 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 150 return; 151 } 152 153 SkIPoint origin = SkIPoint::Make(0,0); 154 // The transfer function behavior isn't used in the generator so set we set it 155 // arbitrarily here. 156 SkTransferFunctionBehavior behavior = SkTransferFunctionBehavior::kIgnore; 157 SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, 158 kPremul_SkAlphaType); 159 sk_sp<GrTextureProxy> genProxy = imageGen->generateTexture(context, imageInfo, 160 origin, behavior, 161 willUseMips); 162 163 REPORTER_ASSERT(reporter, genProxy); 164 if (!genProxy) { 165 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 166 return; 167 } 168 169 REPORTER_ASSERT(reporter, genProxy->priv().isInstantiated()); 170 171 GrTexture* genTexture = genProxy->priv().peekTexture(); 172 REPORTER_ASSERT(reporter, genTexture); 173 if (!genTexture) { 174 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 175 return; 176 } 177 178 GrBackendObject genBackendObject = genTexture->getTextureHandle(); 179 180 if (kOpenGL_GrBackend == backend) { 181 const GrGLTextureInfo* origTexInfo = backendTex.getGLTextureInfo(); 182 GrGLTextureInfo* genTexInfo = (GrGLTextureInfo*)genBackendObject; 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 } else if (kVulkan_GrBackend == backend) { 190#ifdef SK_VULKAN 191 const GrVkImageInfo* origImageInfo = backendTex.getVkImageInfo(); 192 GrVkImageInfo* genImageInfo = (GrVkImageInfo*)genBackendObject; 193 if (willUseMips && GrMipMapped::kNo == mipMapped) { 194 // We did a copy so the texture IDs should be different 195 REPORTER_ASSERT(reporter, origImageInfo->fImage != genImageInfo->fImage); 196 } else { 197 REPORTER_ASSERT(reporter, origImageInfo->fImage == genImageInfo->fImage); 198 } 199#endif 200 } else if (kMetal_GrBackend == backend) { 201 REPORTER_ASSERT(reporter, false); 202 } else { 203 REPORTER_ASSERT(reporter, false); 204 } 205 206 // Must make sure the uses of the backend texture have finished (we possibly have a 207 // queued up copy) before we delete the backend texture. Thus we use readPixels here 208 // just to force the synchronization. 209 sk_sp<GrSurfaceContext> surfContext = 210 context->contextPriv().makeWrappedSurfaceContext(genProxy, nullptr); 211 212 SkBitmap bitmap; 213 bitmap.allocPixels(imageInfo); 214 surfContext->readPixels(imageInfo, bitmap.getPixels(), 0, 0, 0, 0); 215 216 context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); 217 } 218 } 219} 220 221 222#endif 223