blob: df1e8ee9011cf1028757222bd618e356db49ed8a [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();
Greg Daniel261b8aa2017-10-23 09:37:36 -040037 if (!context->caps()->mipMapSupport()) {
38 return;
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 Phillipsd21b2a52017-12-12 13:01:25 -050045 GrBackendTexture backendTex = context->getGpu()->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) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -050072 context->getGpu()->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) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -050081 context->getGpu()->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 {
90 REPORTER_ASSERT(reporter, !texture->texturePriv().mipMapsAreDirty());
91 }
92 } else {
Greg Daniele252f082017-10-23 16:05:23 -040093 REPORTER_ASSERT(reporter, GrMipMapped::kNo == texture->texturePriv().mipMapped());
Greg Daniel177e6952017-10-12 12:27:11 -040094 }
Robert Phillipsd21b2a52017-12-12 13:01:25 -050095 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel177e6952017-10-12 12:27:11 -040096 }
97 }
98}
99
Greg Daniel261b8aa2017-10-23 09:37:36 -0400100// Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator
101// based on if we will use mips in the draw and the mip status of the GrBackendTexture.
102DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, ctxInfo) {
Greg Daniel261b8aa2017-10-23 09:37:36 -0400103 GrContext* context = ctxInfo.grContext();
104 if (!context->caps()->mipMapSupport()) {
105 return;
106 }
107 for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
108 for (auto willUseMips : {false, true}) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500109 GrBackendTexture backendTex = context->getGpu()->createTestingOnlyBackendTexture(
Greg Daniel261b8aa2017-10-23 09:37:36 -0400110 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, mipMapped);
111
Greg Daniel261b8aa2017-10-23 09:37:36 -0400112 sk_sp<SkImage> image = SkImage::MakeFromTexture(context, backendTex,
113 kTopLeft_GrSurfaceOrigin,
Greg Danielf5d87582017-12-18 14:48:15 -0500114 kRGBA_8888_SkColorType,
115 kPremul_SkAlphaType, nullptr,
116 nullptr, nullptr);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400117
118 GrTextureProxy* proxy = as_IB(image)->peekProxy();
119 REPORTER_ASSERT(reporter, proxy);
120 if (!proxy) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500121 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400122 return;
123 }
124
125 REPORTER_ASSERT(reporter, proxy->priv().isInstantiated());
126
127 sk_sp<GrTexture> texture = sk_ref_sp(proxy->priv().peekTexture());
128 REPORTER_ASSERT(reporter, texture);
129 if (!texture) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500130 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400131 return;
132 }
133
134 std::unique_ptr<SkImageGenerator> imageGen = GrBackendTextureImageGenerator::Make(
135 texture, kTopLeft_GrSurfaceOrigin, nullptr, kPremul_SkAlphaType, nullptr);
136 REPORTER_ASSERT(reporter, imageGen);
137 if (!imageGen) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500138 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400139 return;
140 }
141
142 SkIPoint origin = SkIPoint::Make(0,0);
143 // The transfer function behavior isn't used in the generator so set we set it
144 // arbitrarily here.
145 SkTransferFunctionBehavior behavior = SkTransferFunctionBehavior::kIgnore;
146 SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
147 kPremul_SkAlphaType);
148 sk_sp<GrTextureProxy> genProxy = imageGen->generateTexture(context, imageInfo,
149 origin, behavior,
150 willUseMips);
151
152 REPORTER_ASSERT(reporter, genProxy);
153 if (!genProxy) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500154 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400155 return;
156 }
157
Greg Daniele728f672018-01-17 10:52:04 -0500158 if (GrSurfaceProxy::LazyState::kNot != genProxy->lazyInstantiationState()) {
159 genProxy->priv().doLazyInstantiation(context->contextPriv().resourceProvider());
160 }
161
Greg Daniel261b8aa2017-10-23 09:37:36 -0400162 REPORTER_ASSERT(reporter, genProxy->priv().isInstantiated());
163
164 GrTexture* genTexture = genProxy->priv().peekTexture();
165 REPORTER_ASSERT(reporter, genTexture);
166 if (!genTexture) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500167 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400168 return;
169 }
170
Robert Phillipsb67821d2017-12-13 15:00:45 -0500171 GrBackendTexture genBackendTex = genTexture->getBackendTexture();
Greg Daniel261b8aa2017-10-23 09:37:36 -0400172
Robert Phillipsb67821d2017-12-13 15:00:45 -0500173 if (const GrGLTextureInfo* genTexInfo = genBackendTex.getGLTextureInfo()) {
Greg Daniel261b8aa2017-10-23 09:37:36 -0400174 const GrGLTextureInfo* origTexInfo = backendTex.getGLTextureInfo();
Greg Daniel261b8aa2017-10-23 09:37:36 -0400175 if (willUseMips && GrMipMapped::kNo == mipMapped) {
176 // We did a copy so the texture IDs should be different
177 REPORTER_ASSERT(reporter, origTexInfo->fID != genTexInfo->fID);
178 } else {
179 REPORTER_ASSERT(reporter, origTexInfo->fID == genTexInfo->fID);
180 }
Greg Daniel261b8aa2017-10-23 09:37:36 -0400181#ifdef SK_VULKAN
Robert Phillipsb67821d2017-12-13 15:00:45 -0500182 } else if (const GrVkImageInfo* genImageInfo = genBackendTex.getVkImageInfo()) {
Greg Daniel261b8aa2017-10-23 09:37:36 -0400183 const GrVkImageInfo* origImageInfo = backendTex.getVkImageInfo();
Greg Daniel261b8aa2017-10-23 09:37:36 -0400184 if (willUseMips && GrMipMapped::kNo == mipMapped) {
185 // We did a copy so the texture IDs should be different
186 REPORTER_ASSERT(reporter, origImageInfo->fImage != genImageInfo->fImage);
187 } else {
188 REPORTER_ASSERT(reporter, origImageInfo->fImage == genImageInfo->fImage);
189 }
190#endif
Greg Daniel261b8aa2017-10-23 09:37:36 -0400191 } else {
192 REPORTER_ASSERT(reporter, false);
193 }
194
195 // Must make sure the uses of the backend texture have finished (we possibly have a
196 // queued up copy) before we delete the backend texture. Thus we use readPixels here
197 // just to force the synchronization.
198 sk_sp<GrSurfaceContext> surfContext =
199 context->contextPriv().makeWrappedSurfaceContext(genProxy, nullptr);
200
201 SkBitmap bitmap;
202 bitmap.allocPixels(imageInfo);
203 surfContext->readPixels(imageInfo, bitmap.getPixels(), 0, 0, 0, 0);
204
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500205 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel261b8aa2017-10-23 09:37:36 -0400206 }
207 }
208}
209
Greg Daniel45d63032017-10-30 13:41:26 -0400210// Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the
211// resource we took the snapshot of.
212DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest, reporter, ctxInfo) {
213 GrContext* context = ctxInfo.grContext();
214 if (!context->caps()->mipMapSupport()) {
215 return;
216 }
217
Robert Phillips6be756b2018-01-16 15:07:54 -0500218 auto resourceProvider = context->contextPriv().resourceProvider();
219
Greg Daniel45d63032017-10-30 13:41:26 -0400220 for (auto willUseMips : {false, true}) {
221 for (auto isWrapped : {false, true}) {
222 GrMipMapped mipMapped = willUseMips ? GrMipMapped::kYes : GrMipMapped::kNo;
223 sk_sp<SkSurface> surface;
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500224 GrBackendTexture backendTex = context->getGpu()->createTestingOnlyBackendTexture(
225 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, true, mipMapped);
Greg Daniel45d63032017-10-30 13:41:26 -0400226 if (isWrapped) {
Greg Daniel45d63032017-10-30 13:41:26 -0400227 surface = SkSurface::MakeFromBackendTexture(context,
228 backendTex,
229 kTopLeft_GrSurfaceOrigin,
230 0,
Greg Danielfaa095e2017-12-19 13:15:02 -0500231 kRGBA_8888_SkColorType,
Greg Daniel45d63032017-10-30 13:41:26 -0400232 nullptr,
233 nullptr);
234 } else {
235 SkImageInfo info = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
236 kPremul_SkAlphaType);
237 surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
238 kTopLeft_GrSurfaceOrigin, nullptr,
239 willUseMips);
240 }
241 REPORTER_ASSERT(reporter, surface);
242 if (!surface) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500243 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400244 }
245 SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice();
246 GrTextureProxy* texProxy = device->accessRenderTargetContext()->asTextureProxy();
247 REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
248
Robert Phillips6be756b2018-01-16 15:07:54 -0500249 texProxy->instantiate(resourceProvider);
Greg Daniel45d63032017-10-30 13:41:26 -0400250 GrTexture* texture = texProxy->priv().peekTexture();
251 REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
252
253 sk_sp<SkImage> image = surface->makeImageSnapshot();
254 REPORTER_ASSERT(reporter, image);
255 if (!image) {
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500256 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400257 }
258 texProxy = as_IB(image)->peekProxy();
259 REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped());
260
Robert Phillips6be756b2018-01-16 15:07:54 -0500261 texProxy->instantiate(resourceProvider);
Greg Daniel45d63032017-10-30 13:41:26 -0400262 texture = texProxy->priv().peekTexture();
263 REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped());
264
265 // Must flush the context to make sure all the cmds (copies, etc.) from above are sent
266 // to the gpu before we delete the backendHandle.
267 context->flush();
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500268 context->getGpu()->deleteTestingOnlyBackendTexture(&backendTex);
Greg Daniel45d63032017-10-30 13:41:26 -0400269 }
270 }
271}
Greg Daniel261b8aa2017-10-23 09:37:36 -0400272
Greg Daniel177e6952017-10-12 12:27:11 -0400273#endif