blob: e7c98633d7979c622e80d3528e4d31412fb880f3 [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
Greg Daniel177e6952017-10-12 12:27:11 -040010#include "GrBackendSurface.h"
Greg Daniel261b8aa2017-10-23 09:37:36 -040011#include "GrBackendTextureImageGenerator.h"
Greg Daniel177e6952017-10-12 12:27:11 -040012#include "GrContext.h"
13#include "GrContextPriv.h"
14#include "GrGpu.h"
15#include "GrRenderTargetContext.h"
Greg Daniel261b8aa2017-10-23 09:37:36 -040016#include "GrSemaphore.h"
Greg Daniel177e6952017-10-12 12:27:11 -040017#include "GrSurfaceProxyPriv.h"
18#include "GrTest.h"
19#include "GrTexturePriv.h"
20#include "GrTextureProxy.h"
21#include "SkCanvas.h"
22#include "SkImage_Base.h"
23#include "SkGpuDevice.h"
Greg Daniel261b8aa2017-10-23 09:37:36 -040024#include "SkPoint.h"
Greg Daniel177e6952017-10-12 12:27:11 -040025#include "SkSurface.h"
26#include "SkSurface_Gpu.h"
27#include "Test.h"
28
Greg Daniel45d63032017-10-30 13:41:26 -040029static constexpr int kSize = 8;
30
Greg Daniel177e6952017-10-12 12:27:11 -040031// 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();
Brian Salomonc7fe0f72018-05-11 10:14:21 -040035 if (!context->contextPriv().caps()->mipMapSupport()) {
Greg Daniel261b8aa2017-10-23 09:37:36 -040036 return;
37 }
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050038 GrGpu* gpu = context->contextPriv().getGpu();
39
Greg Daniel177e6952017-10-12 12:27:11 -040040 for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
41 for (auto isRT : {false, true}) {
42 // CreateTestingOnlyBackendTexture currently doesn't support uploading data to mip maps
43 // so we don't send any. However, we pretend there is data for the checks below which is
44 // fine since we are never actually using these textures for any work on the gpu.
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050045 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips57e08282017-11-16 14:59:48 -050046 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, isRT, mipMapped);
Greg Daniel177e6952017-10-12 12:27:11 -040047
Robert Phillipse0070c02017-11-13 12:47:24 -050048 sk_sp<GrTextureProxy> proxy;
Greg Daniel177e6952017-10-12 12:27:11 -040049 sk_sp<SkImage> image;
50 if (isRT) {
51 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(
52 context,
53 backendTex,
54 kTopLeft_GrSurfaceOrigin,
55 0,
Greg Danielfaa095e2017-12-19 13:15:02 -050056 kRGBA_8888_SkColorType,
Greg Daniel177e6952017-10-12 12:27:11 -040057 nullptr,
58 nullptr);
59
60 SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
Robert Phillipse0070c02017-11-13 12:47:24 -050061 proxy = device->accessRenderTargetContext()->asTextureProxyRef();
Greg Daniel177e6952017-10-12 12:27:11 -040062 } else {
63 image = SkImage::MakeFromTexture(context, backendTex,
64 kTopLeft_GrSurfaceOrigin,
Greg Danielf5d87582017-12-18 14:48:15 -050065 kRGBA_8888_SkColorType,
66 kPremul_SkAlphaType, nullptr,
67 nullptr, nullptr);
Robert Phillipse0070c02017-11-13 12:47:24 -050068 proxy = as_IB(image)->asTextureProxyRef();
Greg Daniel177e6952017-10-12 12:27:11 -040069 }
70 REPORTER_ASSERT(reporter, proxy);
71 if (!proxy) {
Brian Salomon26102cb2018-03-09 09:33:19 -050072 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel177e6952017-10-12 12:27:11 -040073 return;
74 }
75
76 REPORTER_ASSERT(reporter, proxy->priv().isInstantiated());
77
78 GrTexture* texture = proxy->priv().peekTexture();
79 REPORTER_ASSERT(reporter, texture);
80 if (!texture) {
Brian Salomon26102cb2018-03-09 09:33:19 -050081 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel177e6952017-10-12 12:27:11 -040082 return;
83 }
84
85 if (GrMipMapped::kYes == mipMapped) {
Greg Daniele252f082017-10-23 16:05:23 -040086 REPORTER_ASSERT(reporter, GrMipMapped::kYes == texture->texturePriv().mipMapped());
Greg Daniel177e6952017-10-12 12:27:11 -040087 if (isRT) {
88 REPORTER_ASSERT(reporter, texture->texturePriv().mipMapsAreDirty());
89 } else {
Brian Salomon94575462018-06-21 17:00:26 -040090#if 1
91 // This is temporarily checks that the new image DOES have dirty MIP levels. See
92 // comment in SkImage_Gpu.cpp, new_wrapped_texture_common().
93 REPORTER_ASSERT(reporter, texture->texturePriv().mipMapsAreDirty());
94#else
Greg Daniel177e6952017-10-12 12:27:11 -040095 REPORTER_ASSERT(reporter, !texture->texturePriv().mipMapsAreDirty());
Brian Salomon94575462018-06-21 17:00:26 -040096#endif
Greg Daniel177e6952017-10-12 12:27:11 -040097 }
98 } else {
Greg Daniele252f082017-10-23 16:05:23 -040099 REPORTER_ASSERT(reporter, GrMipMapped::kNo == texture->texturePriv().mipMapped());
Greg Daniel177e6952017-10-12 12:27:11 -0400100 }
Brian Salomon26102cb2018-03-09 09:33:19 -0500101 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel177e6952017-10-12 12:27:11 -0400102 }
103 }
104}
105
Greg Daniel261b8aa2017-10-23 09:37:36 -0400106// Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator
107// based on if we will use mips in the draw and the mip status of the GrBackendTexture.
108DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, ctxInfo) {
Greg Daniel261b8aa2017-10-23 09:37:36 -0400109 GrContext* context = ctxInfo.grContext();
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400110 if (!context->contextPriv().caps()->mipMapSupport()) {
Greg Daniel261b8aa2017-10-23 09:37:36 -0400111 return;
112 }
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500113 GrGpu* gpu = context->contextPriv().getGpu();
114
Greg Daniel261b8aa2017-10-23 09:37:36 -0400115 for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
116 for (auto willUseMips : {false, true}) {
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500117 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Greg Daniel261b8aa2017-10-23 09:37:36 -0400118 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, mipMapped);
119
Greg Daniel261b8aa2017-10-23 09:37:36 -0400120 sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backendTex,
121 kTopLeft_GrSurfaceOrigin,
Greg Danielf5d87582017-12-18 14:48:15 -0500122 kRGBA_8888_SkColorType,
123 kPremul_SkAlphaType, nullptr,
124 nullptr, nullptr);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400125
126 GrTextureProxy* proxy = as_IB(image)->peekProxy();
127 REPORTER_ASSERT(reporter, proxy);
128 if (!proxy) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500129 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400130 return;
131 }
132
133 REPORTER_ASSERT(reporter, proxy->priv().isInstantiated());
134
135 sk_sp<GrTexture> texture = sk_ref_sp(proxy->priv().peekTexture());
136 REPORTER_ASSERT(reporter, texture);
137 if (!texture) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500138 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400139 return;
140 }
141
142 std::unique_ptr<SkImageGenerator> imageGen = GrBackendTextureImageGenerator::Make(
Brian Osman052ef692018-03-27 09:56:31 -0400143 texture, kTopLeft_GrSurfaceOrigin, nullptr, kRGBA_8888_SkColorType,
144 kPremul_SkAlphaType, nullptr);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400145 REPORTER_ASSERT(reporter, imageGen);
146 if (!imageGen) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500147 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400148 return;
149 }
150
151 SkIPoint origin = SkIPoint::Make(0,0);
152 // The transfer function behavior isn't used in the generator so set we set it
153 // arbitrarily here.
154 SkTransferFunctionBehavior behavior = SkTransferFunctionBehavior::kIgnore;
155 SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
156 kPremul_SkAlphaType);
157 sk_sp<GrTextureProxy> genProxy = imageGen->generateTexture(context, imageInfo,
158 origin, behavior,
159 willUseMips);
160
161 REPORTER_ASSERT(reporter, genProxy);
162 if (!genProxy) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500163 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400164 return;
165 }
166
Greg Daniele728f672018-01-17 10:52:04 -0500167 if (GrSurfaceProxy::LazyState::kNot != genProxy->lazyInstantiationState()) {
168 genProxy->priv().doLazyInstantiation(context->contextPriv().resourceProvider());
Greg Danielf6f7b672018-02-15 13:06:26 -0500169 } else if (!genProxy->priv().isInstantiated()) {
170 genProxy->instantiate(context->contextPriv().resourceProvider());
Greg Daniele728f672018-01-17 10:52:04 -0500171 }
172
Greg Daniel261b8aa2017-10-23 09:37:36 -0400173 REPORTER_ASSERT(reporter, genProxy->priv().isInstantiated());
Greg Danielbddcc952018-01-24 13:22:24 -0500174 if (!genProxy->priv().isInstantiated()) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500175 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Danielbddcc952018-01-24 13:22:24 -0500176 return;
177 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400178
179 GrTexture* genTexture = genProxy->priv().peekTexture();
180 REPORTER_ASSERT(reporter, genTexture);
181 if (!genTexture) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500182 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400183 return;
184 }
185
Robert Phillipsb67821d2017-12-13 15:00:45 -0500186 GrBackendTexture genBackendTex = genTexture->getBackendTexture();
Greg Daniel261b8aa2017-10-23 09:37:36 -0400187
Greg Daniel52e16d92018-04-10 09:34:07 -0400188 if (kOpenGL_GrBackend == genBackendTex.backend()) {
189 GrGLTextureInfo genTexInfo;
190 GrGLTextureInfo origTexInfo;
191 if (genBackendTex.getGLTextureInfo(&genTexInfo) &&
192 backendTex.getGLTextureInfo(&origTexInfo)) {
193 if (willUseMips && GrMipMapped::kNo == mipMapped) {
194 // We did a copy so the texture IDs should be different
195 REPORTER_ASSERT(reporter, origTexInfo.fID != genTexInfo.fID);
196 } else {
197 REPORTER_ASSERT(reporter, origTexInfo.fID == genTexInfo.fID);
198 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400199 } else {
Greg Daniel52e16d92018-04-10 09:34:07 -0400200 ERRORF(reporter, "Failed to get GrGLTextureInfo");
Greg Daniel261b8aa2017-10-23 09:37:36 -0400201 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400202#ifdef SK_VULKAN
Greg Daniel52e16d92018-04-10 09:34:07 -0400203 } else if (kVulkan_GrBackend == genBackendTex.backend()) {
204 GrVkImageInfo genImageInfo;
205 GrVkImageInfo origImageInfo;
206 if (genBackendTex.getVkImageInfo(&genImageInfo) &&
207 backendTex.getVkImageInfo(&origImageInfo)) {
208 if (willUseMips && GrMipMapped::kNo == mipMapped) {
209 // We did a copy so the texture IDs should be different
210 REPORTER_ASSERT(reporter, origImageInfo.fImage != genImageInfo.fImage);
211 } else {
212 REPORTER_ASSERT(reporter, origImageInfo.fImage == genImageInfo.fImage);
213 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400214 } else {
Greg Daniel52e16d92018-04-10 09:34:07 -0400215 ERRORF(reporter, "Failed to get GrVkImageInfo");
Greg Daniel261b8aa2017-10-23 09:37:36 -0400216 }
217#endif
Greg Daniel261b8aa2017-10-23 09:37:36 -0400218 } else {
219 REPORTER_ASSERT(reporter, false);
220 }
221
222 // Must make sure the uses of the backend texture have finished (we possibly have a
Greg Daniel26b50a42018-03-08 09:49:58 -0500223 // queued up copy) before we delete the backend texture.
224 context->flush();
225 gpu->testingOnly_flushGpuAndSync();
Greg Daniel261b8aa2017-10-23 09:37:36 -0400226
Brian Salomon26102cb2018-03-09 09:33:19 -0500227 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400228 }
229 }
230}
231
Greg Daniel45d63032017-10-30 13:41:26 -0400232// Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the
233// resource we took the snapshot of.
234DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest, reporter, ctxInfo) {
235 GrContext* context = ctxInfo.grContext();
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400236 if (!context->contextPriv().caps()->mipMapSupport()) {
Greg Daniel45d63032017-10-30 13:41:26 -0400237 return;
238 }
239
Robert Phillips6be756b2018-01-16 15:07:54 -0500240 auto resourceProvider = context->contextPriv().resourceProvider();
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500241 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips6be756b2018-01-16 15:07:54 -0500242
Greg Daniel45d63032017-10-30 13:41:26 -0400243 for (auto willUseMips : {false, true}) {
244 for (auto isWrapped : {false, true}) {
245 GrMipMapped mipMapped = willUseMips ? GrMipMapped::kYes : GrMipMapped::kNo;
246 sk_sp<SkSurface> surface;
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500247 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500248 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, true, mipMapped);
Greg Daniel45d63032017-10-30 13:41:26 -0400249 if (isWrapped) {
Greg Daniel45d63032017-10-30 13:41:26 -0400250 surface = SkSurface::MakeFromBackendTexture(context,
251 backendTex,
252 kTopLeft_GrSurfaceOrigin,
253 0,
Greg Danielfaa095e2017-12-19 13:15:02 -0500254 kRGBA_8888_SkColorType,
Greg Daniel45d63032017-10-30 13:41:26 -0400255 nullptr,
256 nullptr);
257 } else {
258 SkImageInfo info = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
259 kPremul_SkAlphaType);
260 surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
261 kTopLeft_GrSurfaceOrigin, nullptr,
262 willUseMips);
263 }
264 REPORTER_ASSERT(reporter, surface);
265 if (!surface) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500266 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400267 }
268 SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
269 GrTextureProxy* texProxy = device->accessRenderTargetContext()->asTextureProxy();
270 REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
271
Robert Phillips6be756b2018-01-16 15:07:54 -0500272 texProxy->instantiate(resourceProvider);
Greg Daniel45d63032017-10-30 13:41:26 -0400273 GrTexture* texture = texProxy->priv().peekTexture();
274 REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
275
276 sk_sp<SkImage> image = surface->makeImageSnapshot();
277 REPORTER_ASSERT(reporter, image);
278 if (!image) {
Brian Salomon26102cb2018-03-09 09:33:19 -0500279 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400280 }
281 texProxy = as_IB(image)->peekProxy();
282 REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
283
Robert Phillips6be756b2018-01-16 15:07:54 -0500284 texProxy->instantiate(resourceProvider);
Greg Daniel45d63032017-10-30 13:41:26 -0400285 texture = texProxy->priv().peekTexture();
286 REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
287
288 // Must flush the context to make sure all the cmds (copies, etc.) from above are sent
289 // to the gpu before we delete the backendHandle.
290 context->flush();
Greg Danield2d367d2018-04-16 10:24:45 -0400291 gpu->testingOnly_flushGpuAndSync();
Brian Salomon26102cb2018-03-09 09:33:19 -0500292 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400293 }
294 }
295}