blob: e35677904454852df6ebb025041854ef4ee8cf24 [file] [log] [blame]
Greg Daniel177e6952017-10-12 12:27:11 -04001/*
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"
Greg Daniel261b8aa2017-10-23 09:37:36 -040013#include "GrBackendTextureImageGenerator.h"
Greg Daniel177e6952017-10-12 12:27:11 -040014#include "GrContext.h"
15#include "GrContextPriv.h"
16#include "GrGpu.h"
17#include "GrRenderTargetContext.h"
Greg Daniel261b8aa2017-10-23 09:37:36 -040018#include "GrSemaphore.h"
Greg Daniel177e6952017-10-12 12:27:11 -040019#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"
Greg Daniel261b8aa2017-10-23 09:37:36 -040026#include "SkPoint.h"
Greg Daniel177e6952017-10-12 12:27:11 -040027#include "SkSurface.h"
28#include "SkSurface_Gpu.h"
29#include "Test.h"
30
Greg Daniel45d63032017-10-30 13:41:26 -040031static constexpr int kSize = 8;
32
Greg Daniel177e6952017-10-12 12:27:11 -040033// Test that the correct mip map states are on the GrTextures when wrapping GrBackendTextures in
34// SkImages and SkSurfaces
35DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) {
36 GrContext* context = ctxInfo.grContext();
Brian Salomonc7fe0f72018-05-11 10:14:21 -040037 if (!context->contextPriv().caps()->mipMapSupport()) {
Greg Daniel261b8aa2017-10-23 09:37:36 -040038 return;
39 }
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050040 GrGpu* gpu = context->contextPriv().getGpu();
41
Greg Daniel177e6952017-10-12 12:27:11 -040042 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.
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050047 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips57e08282017-11-16 14:59:48 -050048 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, isRT, mipMapped);
Greg Daniel177e6952017-10-12 12:27:11 -040049
Robert Phillipse0070c02017-11-13 12:47:24 -050050 sk_sp<GrTextureProxy> proxy;
Greg Daniel177e6952017-10-12 12:27:11 -040051 sk_sp<SkImage> image;
52 if (isRT) {
53 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(
54 context,
55 backendTex,
56 kTopLeft_GrSurfaceOrigin,
57 0,
Greg Danielfaa095e2017-12-19 13:15:02 -050058 kRGBA_8888_SkColorType,
Greg Daniel177e6952017-10-12 12:27:11 -040059 nullptr,
60 nullptr);
61
62 SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
Robert Phillipse0070c02017-11-13 12:47:24 -050063 proxy = device->accessRenderTargetContext()->asTextureProxyRef();
Greg Daniel177e6952017-10-12 12:27:11 -040064 } else {
65 image = SkImage::MakeFromTexture(context, backendTex,
66 kTopLeft_GrSurfaceOrigin,
Greg Danielf5d87582017-12-18 14:48:15 -050067 kRGBA_8888_SkColorType,
68 kPremul_SkAlphaType, nullptr,
69 nullptr, nullptr);
Robert Phillipse0070c02017-11-13 12:47:24 -050070 proxy = as_IB(image)->asTextureProxyRef();
Greg Daniel177e6952017-10-12 12:27:11 -040071 }
72 REPORTER_ASSERT(reporter, proxy);
73 if (!proxy) {
Brian Salomon26102cb2018-03-09 09:33:19 -050074 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel177e6952017-10-12 12:27:11 -040075 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) {
Brian Salomon26102cb2018-03-09 09:33:19 -050083 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel177e6952017-10-12 12:27:11 -040084 return;
85 }
86
87 if (GrMipMapped::kYes == mipMapped) {
Greg Daniele252f082017-10-23 16:05:23 -040088 REPORTER_ASSERT(reporter, GrMipMapped::kYes == texture->texturePriv().mipMapped());
Greg Daniel177e6952017-10-12 12:27:11 -040089 if (isRT) {
90 REPORTER_ASSERT(reporter, texture->texturePriv().mipMapsAreDirty());
91 } else {
92 REPORTER_ASSERT(reporter, !texture->texturePriv().mipMapsAreDirty());
93 }
94 } else {
Greg Daniele252f082017-10-23 16:05:23 -040095 REPORTER_ASSERT(reporter, GrMipMapped::kNo == texture->texturePriv().mipMapped());
Greg Daniel177e6952017-10-12 12:27:11 -040096 }
Brian Salomon26102cb2018-03-09 09:33:19 -050097 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel177e6952017-10-12 12:27:11 -040098 }
99 }
100}
101
Greg Daniel261b8aa2017-10-23 09:37:36 -0400102// 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.
104DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, ctxInfo) {
Greg Daniel261b8aa2017-10-23 09:37:36 -0400105 GrContext* context = ctxInfo.grContext();
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400106 if (!context->contextPriv().caps()->mipMapSupport()) {
Greg Daniel261b8aa2017-10-23 09:37:36 -0400107 return;
108 }
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500109 GrGpu* gpu = context->contextPriv().getGpu();
110
Greg Daniel261b8aa2017-10-23 09:37:36 -0400111 for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
112 for (auto willUseMips : {false, true}) {
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500113 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Greg Daniel261b8aa2017-10-23 09:37:36 -0400114 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, mipMapped);
115
Greg Daniel261b8aa2017-10-23 09:37:36 -0400116 sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backendTex,
117 kTopLeft_GrSurfaceOrigin,
Greg Danielf5d87582017-12-18 14:48:15 -0500118 kRGBA_8888_SkColorType,
119 kPremul_SkAlphaType, nullptr,
120 nullptr, nullptr);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400121
122 GrTextureProxy* proxy = as_IB(image)->peekProxy();
123 REPORTER_ASSERT(reporter, proxy);
124 if (!proxy) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500125 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400126 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) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500134 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400135 return;
136 }
137
138 std::unique_ptr<SkImageGenerator> imageGen = GrBackendTextureImageGenerator::Make(
Brian Osman052ef692018-03-27 09:56:31 -0400139 texture, kTopLeft_GrSurfaceOrigin, nullptr, kRGBA_8888_SkColorType,
140 kPremul_SkAlphaType, nullptr);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400141 REPORTER_ASSERT(reporter, imageGen);
142 if (!imageGen) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500143 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400144 return;
145 }
146
147 SkIPoint origin = SkIPoint::Make(0,0);
148 // The transfer function behavior isn't used in the generator so set we set it
149 // arbitrarily here.
150 SkTransferFunctionBehavior behavior = SkTransferFunctionBehavior::kIgnore;
151 SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
152 kPremul_SkAlphaType);
153 sk_sp<GrTextureProxy> genProxy = imageGen->generateTexture(context, imageInfo,
154 origin, behavior,
155 willUseMips);
156
157 REPORTER_ASSERT(reporter, genProxy);
158 if (!genProxy) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500159 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400160 return;
161 }
162
Greg Daniele728f672018-01-17 10:52:04 -0500163 if (GrSurfaceProxy::LazyState::kNot != genProxy->lazyInstantiationState()) {
164 genProxy->priv().doLazyInstantiation(context->contextPriv().resourceProvider());
Greg Danielf6f7b672018-02-15 13:06:26 -0500165 } else if (!genProxy->priv().isInstantiated()) {
166 genProxy->instantiate(context->contextPriv().resourceProvider());
Greg Daniele728f672018-01-17 10:52:04 -0500167 }
168
Greg Daniel261b8aa2017-10-23 09:37:36 -0400169 REPORTER_ASSERT(reporter, genProxy->priv().isInstantiated());
Greg Danielbddcc952018-01-24 13:22:24 -0500170 if (!genProxy->priv().isInstantiated()) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500171 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Danielbddcc952018-01-24 13:22:24 -0500172 return;
173 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400174
175 GrTexture* genTexture = genProxy->priv().peekTexture();
176 REPORTER_ASSERT(reporter, genTexture);
177 if (!genTexture) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500178 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400179 return;
180 }
181
Robert Phillipsb67821d2017-12-13 15:00:45 -0500182 GrBackendTexture genBackendTex = genTexture->getBackendTexture();
Greg Daniel261b8aa2017-10-23 09:37:36 -0400183
Greg Daniel52e16d92018-04-10 09:34:07 -0400184 if (kOpenGL_GrBackend == genBackendTex.backend()) {
185 GrGLTextureInfo genTexInfo;
186 GrGLTextureInfo origTexInfo;
187 if (genBackendTex.getGLTextureInfo(&genTexInfo) &&
188 backendTex.getGLTextureInfo(&origTexInfo)) {
189 if (willUseMips && GrMipMapped::kNo == mipMapped) {
190 // We did a copy so the texture IDs should be different
191 REPORTER_ASSERT(reporter, origTexInfo.fID != genTexInfo.fID);
192 } else {
193 REPORTER_ASSERT(reporter, origTexInfo.fID == genTexInfo.fID);
194 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400195 } else {
Greg Daniel52e16d92018-04-10 09:34:07 -0400196 ERRORF(reporter, "Failed to get GrGLTextureInfo");
Greg Daniel261b8aa2017-10-23 09:37:36 -0400197 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400198#ifdef SK_VULKAN
Greg Daniel52e16d92018-04-10 09:34:07 -0400199 } else if (kVulkan_GrBackend == genBackendTex.backend()) {
200 GrVkImageInfo genImageInfo;
201 GrVkImageInfo origImageInfo;
202 if (genBackendTex.getVkImageInfo(&genImageInfo) &&
203 backendTex.getVkImageInfo(&origImageInfo)) {
204 if (willUseMips && GrMipMapped::kNo == mipMapped) {
205 // We did a copy so the texture IDs should be different
206 REPORTER_ASSERT(reporter, origImageInfo.fImage != genImageInfo.fImage);
207 } else {
208 REPORTER_ASSERT(reporter, origImageInfo.fImage == genImageInfo.fImage);
209 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400210 } else {
Greg Daniel52e16d92018-04-10 09:34:07 -0400211 ERRORF(reporter, "Failed to get GrVkImageInfo");
Greg Daniel261b8aa2017-10-23 09:37:36 -0400212 }
213#endif
Greg Daniel261b8aa2017-10-23 09:37:36 -0400214 } else {
215 REPORTER_ASSERT(reporter, false);
216 }
217
218 // Must make sure the uses of the backend texture have finished (we possibly have a
Greg Daniel26b50a42018-03-08 09:49:58 -0500219 // queued up copy) before we delete the backend texture.
220 context->flush();
221 gpu->testingOnly_flushGpuAndSync();
Greg Daniel261b8aa2017-10-23 09:37:36 -0400222
Brian Salomon26102cb2018-03-09 09:33:19 -0500223 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400224 }
225 }
226}
227
Greg Daniel45d63032017-10-30 13:41:26 -0400228// Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the
229// resource we took the snapshot of.
230DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest, reporter, ctxInfo) {
231 GrContext* context = ctxInfo.grContext();
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400232 if (!context->contextPriv().caps()->mipMapSupport()) {
Greg Daniel45d63032017-10-30 13:41:26 -0400233 return;
234 }
235
Robert Phillips6be756b2018-01-16 15:07:54 -0500236 auto resourceProvider = context->contextPriv().resourceProvider();
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500237 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips6be756b2018-01-16 15:07:54 -0500238
Greg Daniel45d63032017-10-30 13:41:26 -0400239 for (auto willUseMips : {false, true}) {
240 for (auto isWrapped : {false, true}) {
241 GrMipMapped mipMapped = willUseMips ? GrMipMapped::kYes : GrMipMapped::kNo;
242 sk_sp<SkSurface> surface;
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500243 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500244 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, true, mipMapped);
Greg Daniel45d63032017-10-30 13:41:26 -0400245 if (isWrapped) {
Greg Daniel45d63032017-10-30 13:41:26 -0400246 surface = SkSurface::MakeFromBackendTexture(context,
247 backendTex,
248 kTopLeft_GrSurfaceOrigin,
249 0,
Greg Danielfaa095e2017-12-19 13:15:02 -0500250 kRGBA_8888_SkColorType,
Greg Daniel45d63032017-10-30 13:41:26 -0400251 nullptr,
252 nullptr);
253 } else {
254 SkImageInfo info = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
255 kPremul_SkAlphaType);
256 surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
257 kTopLeft_GrSurfaceOrigin, nullptr,
258 willUseMips);
259 }
260 REPORTER_ASSERT(reporter, surface);
261 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500262 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400263 }
264 SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
265 GrTextureProxy* texProxy = device->accessRenderTargetContext()->asTextureProxy();
266 REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
267
Robert Phillips6be756b2018-01-16 15:07:54 -0500268 texProxy->instantiate(resourceProvider);
Greg Daniel45d63032017-10-30 13:41:26 -0400269 GrTexture* texture = texProxy->priv().peekTexture();
270 REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
271
272 sk_sp<SkImage> image = surface->makeImageSnapshot();
273 REPORTER_ASSERT(reporter, image);
274 if (!image) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500275 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400276 }
277 texProxy = as_IB(image)->peekProxy();
278 REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
279
Robert Phillips6be756b2018-01-16 15:07:54 -0500280 texProxy->instantiate(resourceProvider);
Greg Daniel45d63032017-10-30 13:41:26 -0400281 texture = texProxy->priv().peekTexture();
282 REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
283
284 // Must flush the context to make sure all the cmds (copies, etc.) from above are sent
285 // to the gpu before we delete the backendHandle.
286 context->flush();
Greg Danield2d367d2018-04-16 10:24:45 -0400287 gpu->testingOnly_flushGpuAndSync();
Brian Salomon26102cb2018-03-09 09:33:19 -0500288 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400289 }
290 }
291}
Greg Daniel261b8aa2017-10-23 09:37:36 -0400292
Greg Daniel177e6952017-10-12 12:27:11 -0400293#endif