blob: d11a836101f5d2e4da462736e74a4d623ffaabbe [file] [log] [blame]
Robert Phillips7ffbcf92017-12-04 12:52:46 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkBitmap.h"
9#include "include/core/SkCanvas.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040010#include "include/core/SkColor.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkColorSpace.h"
Robert Phillips4d5594d2020-02-21 14:24:40 -050012#include "include/core/SkDeferredDisplayList.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkDeferredDisplayListRecorder.h"
14#include "include/core/SkImage.h"
15#include "include/core/SkImageInfo.h"
16#include "include/core/SkPaint.h"
17#include "include/core/SkPromiseImageTexture.h"
18#include "include/core/SkRect.h"
19#include "include/core/SkRefCnt.h"
20#include "include/core/SkSurface.h"
21#include "include/core/SkSurfaceCharacterization.h"
22#include "include/core/SkSurfaceProps.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040023#include "include/core/SkTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "include/gpu/GrBackendSurface.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040025#include "include/gpu/GrContextThreadSafeProxy.h"
Robert Phillips6d344c32020-07-06 10:56:46 -040026#include "include/gpu/GrDirectContext.h"
Robert Phillipsc8ae4942020-07-20 10:56:01 -040027#include "include/gpu/GrRecordingContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "include/gpu/GrTypes.h"
29#include "include/gpu/gl/GrGLTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "include/private/GrTypesPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050031#include "src/core/SkDeferredDisplayListPriv.h"
32#include "src/gpu/GrCaps.h"
Adlai Hollera0693042020-10-14 11:23:11 -040033#include "src/gpu/GrDirectContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050034#include "src/gpu/GrGpu.h"
Robert Phillipsc8ae4942020-07-20 10:56:01 -040035#include "src/gpu/GrRecordingContextPriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040036#include "src/gpu/GrRenderTargetProxy.h"
37#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050038#include "src/gpu/gl/GrGLDefines.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040039#include "src/image/SkImage_GpuBase.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050040#include "src/image/SkSurface_Gpu.h"
41#include "tests/Test.h"
Robert Phillipsee5fd132019-05-07 13:29:22 -040042#include "tests/TestUtils.h"
Brian Salomonf9b00422020-10-08 16:00:14 -040043#include "tools/gpu/BackendSurfaceFactory.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050044#include "tools/gpu/GrContextFactory.h"
Brian Salomon72050802020-10-12 20:45:06 -040045#include "tools/gpu/ManagedBackendTexture.h"
Brian Salomone6662542021-02-23 10:45:39 -050046#include "tools/gpu/ProxyUtils.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040047
48#include <initializer_list>
49#include <memory>
50#include <utility>
Robert Phillipsfc711a22018-02-13 17:03:00 -050051
Robert Phillips3cd54322019-07-10 09:28:59 -040052#ifdef SK_VULKAN
53#include "src/gpu/vk/GrVkCaps.h"
Greg Daniel007d97d2020-11-04 10:50:39 -050054#include "src/gpu/vk/GrVkSecondaryCBDrawContext.h"
Robert Phillips3cd54322019-07-10 09:28:59 -040055#endif
56
Robert Phillips7ffbcf92017-12-04 12:52:46 -050057class SurfaceParameters {
58public:
Greg Daniel007d97d2020-11-04 10:50:39 -050059 static const int kNumParams = 13;
Robert Phillips3cd54322019-07-10 09:28:59 -040060 static const int kFBO0Count = 9;
Greg Daniel007d97d2020-11-04 10:50:39 -050061 static const int kVkSCBCount = 12;
Robert Phillips7ffbcf92017-12-04 12:52:46 -050062
Robert Phillipsc8ae4942020-07-20 10:56:01 -040063 SurfaceParameters(GrRecordingContext* rContext)
64 : fBackend(rContext->backend())
Brian Salomonf9b00422020-10-08 16:00:14 -040065 , fCanBeProtected(false)
Robert Phillipsb45f47d2019-02-03 17:17:54 -050066 , fWidth(64)
Robert Phillips7ffbcf92017-12-04 12:52:46 -050067 , fHeight(64)
68 , fOrigin(kTopLeft_GrSurfaceOrigin)
69 , fColorType(kRGBA_8888_SkColorType)
70 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -050071 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -050072 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
Robert Phillipsb45f47d2019-02-03 17:17:54 -050073 , fShouldCreateMipMaps(true)
74 , fUsesGLFBO0(false)
Robert Phillips3cd54322019-07-10 09:28:59 -040075 , fIsTextureable(true)
Greg Daniel638b2e82020-08-27 14:29:00 -040076 , fIsProtected(GrProtected::kNo)
Greg Daniel007d97d2020-11-04 10:50:39 -050077 , fVkRTSupportsInputAttachment(false)
78 , fForVulkanSecondaryCommandBuffer(false) {
Robert Phillips3cd54322019-07-10 09:28:59 -040079#ifdef SK_VULKAN
Brian Salomonf9b00422020-10-08 16:00:14 -040080 if (rContext->backend() == GrBackendApi::kVulkan) {
81 auto vkCaps = static_cast<const GrVkCaps*>(rContext->priv().caps());
82 fCanBeProtected = vkCaps->supportsProtectedMemory();
83 if (fCanBeProtected) {
84 fIsProtected = GrProtected::kYes;
85 }
Robert Phillips3cd54322019-07-10 09:28:59 -040086 }
87#endif
Brian Salomonf9b00422020-10-08 16:00:14 -040088 if (!rContext->priv().caps()->mipmapSupport()) {
89 fShouldCreateMipMaps = false;
90 }
Robert Phillipse8fabb22018-02-04 14:33:21 -050091 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -050092
93 int sampleCount() const { return fSampleCount; }
94
Robert Phillipsbe77a022018-04-03 17:17:05 -040095 void setColorType(SkColorType ct) { fColorType = ct; }
Robert Phillipsd8f79a22019-06-24 13:25:42 -040096 SkColorType colorType() const { return fColorType; }
Robert Phillipsbe77a022018-04-03 17:17:05 -040097 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
Brian Salomonf9b00422020-10-08 16:00:14 -040098 void disableTextureability() {
99 fIsTextureable = false;
100 fShouldCreateMipMaps = false;
101 }
Brian Salomon4687bdd2019-05-09 16:28:04 -0400102 void setShouldCreateMipMaps(bool shouldCreateMipMaps) {
103 fShouldCreateMipMaps = shouldCreateMipMaps;
104 }
Greg Daniel638b2e82020-08-27 14:29:00 -0400105 void setVkRTInputAttachmentSupport(bool inputSupport) {
106 fVkRTSupportsInputAttachment = inputSupport;
107 }
Greg Daniel007d97d2020-11-04 10:50:39 -0500108 void setForVulkanSecondaryCommandBuffer(bool forVkSCB) {
109 fForVulkanSecondaryCommandBuffer = forVkSCB;
110 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400111
Brian Salomonf9b00422020-10-08 16:00:14 -0400112 // Modify the SurfaceParameters in just one way. Returns false if the requested modification had
113 // no effect.
114 bool modify(int i) {
115 bool changed = false;
116 auto set = [&changed](auto& var, auto value) {
117 if (var != value) {
118 changed = true;
119 }
120 var = value;
121 };
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500122 switch (i) {
123 case 0:
Brian Salomonf9b00422020-10-08 16:00:14 -0400124 set(fWidth, 63);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500125 break;
126 case 1:
Brian Salomonf9b00422020-10-08 16:00:14 -0400127 set(fHeight, 63);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500128 break;
129 case 2:
Brian Salomonf9b00422020-10-08 16:00:14 -0400130 set(fOrigin, kBottomLeft_GrSurfaceOrigin);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500131 break;
132 case 3:
Brian Salomonf9b00422020-10-08 16:00:14 -0400133 set(fColorType, kRGBA_F16_SkColorType);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500134 break;
135 case 4:
Brian Osman37f99882018-08-09 10:26:57 -0400136 // This just needs to be a colorSpace different from that returned by MakeSRGB().
137 // In this case we just change the gamut.
Brian Salomonf9b00422020-10-08 16:00:14 -0400138 set(fColorSpace, SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
139 SkNamedGamut::kAdobeRGB));
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500140 break;
Brian Salomonf9b00422020-10-08 16:00:14 -0400141 case 5:
142 set(fSampleCount, 4);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500143 break;
144 case 6:
Brian Salomonf9b00422020-10-08 16:00:14 -0400145 set(fSurfaceProps, SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry));
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500146 break;
147 case 7:
Brian Salomonf9b00422020-10-08 16:00:14 -0400148 set(fSurfaceProps, SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
149 kUnknown_SkPixelGeometry));
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500150 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500151 case 8:
Brian Salomonf9b00422020-10-08 16:00:14 -0400152 set(fShouldCreateMipMaps, false);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500153 break;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500154 case 9:
155 if (GrBackendApi::kOpenGL == fBackend) {
Brian Salomonf9b00422020-10-08 16:00:14 -0400156 set(fUsesGLFBO0, true);
157 set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability
158 set(fIsTextureable, false);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500159 }
160 break;
161 case 10:
Brian Salomonf9b00422020-10-08 16:00:14 -0400162 set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability
163 set(fIsTextureable, false);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500164 break;
Robert Phillips3cd54322019-07-10 09:28:59 -0400165 case 11:
Brian Salomonf9b00422020-10-08 16:00:14 -0400166 if (fCanBeProtected) {
167 set(fIsProtected, GrProtected(!static_cast<bool>(fIsProtected)));
168 }
Robert Phillips3cd54322019-07-10 09:28:59 -0400169 break;
Greg Daniel007d97d2020-11-04 10:50:39 -0500170 case 12:
171 if (GrBackendApi::kVulkan == fBackend) {
172 set(fForVulkanSecondaryCommandBuffer, true);
173 set(fUsesGLFBO0, false);
174 set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability
175 set(fIsTextureable, false);
176 set(fVkRTSupportsInputAttachment, false);
177 }
178 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500179 }
Brian Salomonf9b00422020-10-08 16:00:14 -0400180 return changed;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500181 }
182
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400183 SkSurfaceCharacterization createCharacterization(GrDirectContext* dContext) const {
184 size_t maxResourceBytes = dContext->getResourceCacheLimit();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500185
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400186 if (!dContext->colorTypeSupportedAsSurface(fColorType)) {
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400187 return SkSurfaceCharacterization();
188 }
189
Robert Phillipsfc711a22018-02-13 17:03:00 -0500190 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
191 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
192 kPremul_SkAlphaType, fColorSpace);
193
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400194 GrBackendFormat backendFormat = dContext->defaultBackendFormat(fColorType,
195 GrRenderable::kYes);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400196 if (!backendFormat.isValid()) {
197 return SkSurfaceCharacterization();
198 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500199
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400200 SkSurfaceCharacterization c = dContext->threadSafeProxy()->createCharacterization(
Robert Phillipsfc711a22018-02-13 17:03:00 -0500201 maxResourceBytes, ii, backendFormat, fSampleCount,
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500202 fOrigin, fSurfaceProps, fShouldCreateMipMaps,
Greg Daniel638b2e82020-08-27 14:29:00 -0400203 fUsesGLFBO0, fIsTextureable, fIsProtected,
Greg Daniel007d97d2020-11-04 10:50:39 -0500204 fVkRTSupportsInputAttachment,
205 fForVulkanSecondaryCommandBuffer);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400206 return c;
207 }
208
209 // Create a DDL whose characterization captures the current settings
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400210 sk_sp<SkDeferredDisplayList> createDDL(GrDirectContext* dContext) const {
211 SkSurfaceCharacterization c = this->createCharacterization(dContext);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500212 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500213
214 SkDeferredDisplayListRecorder r(c);
215 SkCanvas* canvas = r.getCanvas();
216 if (!canvas) {
217 return nullptr;
218 }
219
220 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
221 return r.detach();
222 }
223
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500224 // Create the surface with the current set of parameters
Brian Salomonf9b00422020-10-08 16:00:14 -0400225 sk_sp<SkSurface> make(GrDirectContext* dContext) const {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400226 const SkSurfaceCharacterization c = this->createCharacterization(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400227
John Rosasco24cbdab2019-09-25 14:14:35 -0700228#ifdef SK_GL
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500229 if (fUsesGLFBO0) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400230 if (GrBackendApi::kOpenGL != dContext->backend()) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500231 return nullptr;
232 }
233
234 GrGLFramebufferInfo fboInfo;
235 fboInfo.fFBOID = 0;
236 fboInfo.fFormat = GR_GL_RGBA8;
237 static constexpr int kStencilBits = 8;
238 GrBackendRenderTarget backendRT(fWidth, fHeight, 1, kStencilBits, fboInfo);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500239
240 if (!backendRT.isValid()) {
241 return nullptr;
242 }
243
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400244 sk_sp<SkSurface> result = SkSurface::MakeFromBackendRenderTarget(dContext, backendRT,
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400245 fOrigin, fColorType,
246 fColorSpace,
247 &fSurfaceProps);
Robert Phillips9907e6e2019-06-25 14:47:04 -0400248 SkASSERT(result->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400249 return result;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500250 }
John Rosasco24cbdab2019-09-25 14:14:35 -0700251#endif
Robert Phillipsc046ff02019-07-01 10:34:03 -0400252
Greg Daniel007d97d2020-11-04 10:50:39 -0500253 // We can't make SkSurfaces for vulkan secondary command buffers.
254 if (fForVulkanSecondaryCommandBuffer) {
255 return nullptr;
256 }
257
Robert Phillipsbe77a022018-04-03 17:17:05 -0400258 sk_sp<SkSurface> surface;
Brian Salomonf9b00422020-10-08 16:00:14 -0400259 if (fIsTextureable) {
260 surface = sk_gpu_test::MakeBackendTextureSurface(dContext,
261 {fWidth, fHeight},
262 fOrigin,
263 fSampleCount,
264 fColorType,
265 fColorSpace,
266 GrMipmapped(fShouldCreateMipMaps),
267 fIsProtected,
268 &fSurfaceProps);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400269 } else {
Brian Salomonf9b00422020-10-08 16:00:14 -0400270 // Create a surface w/ the current parameters but make it non-textureable
271 SkASSERT(!fShouldCreateMipMaps);
272 surface = sk_gpu_test::MakeBackendRenderTargetSurface(dContext,
273 {fWidth, fHeight},
274 fOrigin,
275 fSampleCount,
276 fColorType,
277 fColorSpace,
278 fIsProtected,
279 &fSurfaceProps);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400280 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500281
282 if (!surface) {
Robert Phillipsc046ff02019-07-01 10:34:03 -0400283 SkASSERT(!c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500284 return nullptr;
285 }
286
Brian Salomonf9b00422020-10-08 16:00:14 -0400287 GrBackendTexture texture =
288 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
289 if (texture.isValid()) {
290 SkASSERT(c.isCompatible(texture));
291 }
Robert Phillipsc046ff02019-07-01 10:34:03 -0400292 SkASSERT(c.isValid());
Robert Phillips9907e6e2019-06-25 14:47:04 -0400293 SkASSERT(surface->isCompatible(c));
Robert Phillipse8fabb22018-02-04 14:33:21 -0500294 return surface;
295 }
296
Greg Daniel007d97d2020-11-04 10:50:39 -0500297#ifdef SK_VULKAN
298 sk_sp<GrVkSecondaryCBDrawContext> makeVkSCB(GrDirectContext* dContext) {
299 const SkSurfaceCharacterization c = this->createCharacterization(dContext);
300 SkImageInfo imageInfo = SkImageInfo::Make({fWidth, fHeight},
301 {fColorType, kPremul_SkAlphaType, fColorSpace});
302 GrVkDrawableInfo vkInfo;
Kevin Lubickbe03ef12021-06-16 15:28:00 -0400303 // putting in a bunch of placeholder values here
Greg Daniel007d97d2020-11-04 10:50:39 -0500304 vkInfo.fSecondaryCommandBuffer = (VkCommandBuffer)1;
305 vkInfo.fColorAttachmentIndex = 0;
306 vkInfo.fCompatibleRenderPass = (VkRenderPass)1;
307 vkInfo.fFormat = VK_FORMAT_R8G8B8A8_UNORM;
308 vkInfo.fDrawBounds = nullptr;
309 vkInfo.fImage = (VkImage)1;
310
311 return GrVkSecondaryCBDrawContext::Make(dContext, imageInfo, vkInfo, &fSurfaceProps);
312 }
313#endif
314
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500315private:
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500316 GrBackendApi fBackend;
Brian Salomonf9b00422020-10-08 16:00:14 -0400317 bool fCanBeProtected;
318
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500319 int fWidth;
320 int fHeight;
321 GrSurfaceOrigin fOrigin;
322 SkColorType fColorType;
323 sk_sp<SkColorSpace> fColorSpace;
324 int fSampleCount;
325 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500326 bool fShouldCreateMipMaps;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500327 bool fUsesGLFBO0;
328 bool fIsTextureable;
Robert Phillips3cd54322019-07-10 09:28:59 -0400329 GrProtected fIsProtected;
Greg Daniel638b2e82020-08-27 14:29:00 -0400330 bool fVkRTSupportsInputAttachment;
Greg Daniel007d97d2020-11-04 10:50:39 -0500331 bool fForVulkanSecondaryCommandBuffer;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500332};
333
Robert Phillipsc1267c62018-04-04 11:12:39 -0400334// Test out operator== && operator!=
335DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400336 auto context = ctxInfo.directContext();
Robert Phillipsc1267c62018-04-04 11:12:39 -0400337
Brian Salomonf9b00422020-10-08 16:00:14 -0400338 for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400339 SurfaceParameters params1(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400340 bool didModify1 = i >= 0 && params1.modify(i);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400341
342 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
343 if (!char1.isValid()) {
344 continue; // can happen on some platforms (ChromeOS)
345 }
346
Brian Salomonf9b00422020-10-08 16:00:14 -0400347 for (int j = -1; j < SurfaceParameters::kNumParams; ++j) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400348 SurfaceParameters params2(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400349 bool didModify2 = j >= 0 && params2.modify(j);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400350
351 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
352 if (!char2.isValid()) {
353 continue; // can happen on some platforms (ChromeOS)
354 }
355
Brian Salomonf9b00422020-10-08 16:00:14 -0400356 if (i == j || (!didModify1 && !didModify2)) {
Robert Phillipsc1267c62018-04-04 11:12:39 -0400357 REPORTER_ASSERT(reporter, char1 == char2);
358 } else {
359 REPORTER_ASSERT(reporter, char1 != char2);
360 }
Robert Phillipsc1267c62018-04-04 11:12:39 -0400361 }
362 }
363
364 {
Robert Phillips3cd54322019-07-10 09:28:59 -0400365 SurfaceParameters params(context);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400366
367 SkSurfaceCharacterization valid = params.createCharacterization(context);
368 SkASSERT(valid.isValid());
369
370 SkSurfaceCharacterization inval1, inval2;
371 SkASSERT(!inval1.isValid() && !inval2.isValid());
372
373 REPORTER_ASSERT(reporter, inval1 != inval2);
374 REPORTER_ASSERT(reporter, valid != inval1);
375 REPORTER_ASSERT(reporter, inval1 != valid);
376 }
377}
378
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400379////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500380// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400381void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
Robert Phillips9e441ee2018-02-01 15:14:55 -0500382 // Create a bitmap that we can readback into
383 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
384 kPremul_SkAlphaType);
385 SkBitmap bitmap;
386 bitmap.allocPixels(imageInfo);
387
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400388 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500389
390 // First, create a DDL using the stock SkSurface parameters
391 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400392 SurfaceParameters params(dContext);
Greg Daniel638b2e82020-08-27 14:29:00 -0400393 if (dContext->backend() == GrBackendApi::kVulkan) {
394 params.setVkRTInputAttachmentSupport(true);
395 }
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400396 ddl = params.createDDL(dContext);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500397 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500398
399 // The DDL should draw into an SkSurface created with the same parameters
Brian Salomonf9b00422020-10-08 16:00:14 -0400400 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500401 if (!s) {
402 return;
403 }
404
Adlai Holler7580ad42020-06-24 13:45:25 -0400405 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500406 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Brian Salomonf9b00422020-10-08 16:00:14 -0400407
408 dContext->flush();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500409 }
410
411 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
412 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400413 SurfaceParameters params(dContext);
Brian Salomonf9b00422020-10-08 16:00:14 -0400414 if (!params.modify(i)) {
415 continue;
Robert Phillips3cd54322019-07-10 09:28:59 -0400416 }
417
Brian Salomonf9b00422020-10-08 16:00:14 -0400418 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500419 if (!s) {
420 continue;
421 }
422
Adlai Holler7580ad42020-06-24 13:45:25 -0400423 REPORTER_ASSERT(reporter, !s->draw(ddl),
Robert Phillipse8fabb22018-02-04 14:33:21 -0500424 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Brian Salomonf9b00422020-10-08 16:00:14 -0400425 dContext->flush();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500426 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500427
428 // Next test the compatibility of resource cache parameters
429 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400430 const SurfaceParameters params(dContext);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400431
Brian Salomonf9b00422020-10-08 16:00:14 -0400432 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500433
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400434 size_t maxResourceBytes = dContext->getResourceCacheLimit();
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500435
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400436 dContext->setResourceCacheLimit(maxResourceBytes/2);
Adlai Holler7580ad42020-06-24 13:45:25 -0400437 REPORTER_ASSERT(reporter, !s->draw(ddl));
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500438
Robert Phillips9e441ee2018-02-01 15:14:55 -0500439 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
440 // For now, DDLs are drawn once.
441#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500442 // resource limits >= those at characterization time are accepted
443 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400444 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500445 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500446
447 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400448 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500449 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500450
451 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400452 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500453 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
454#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400455
Brian Salomonf9b00422020-10-08 16:00:14 -0400456 dContext->flush();
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500457 }
458
Robert Phillipse8fabb22018-02-04 14:33:21 -0500459 // Test that the textureability of the DDL characterization can block a DDL draw
460 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400461 SurfaceParameters params(dContext);
Brian Salomonf9b00422020-10-08 16:00:14 -0400462 params.disableTextureability();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500463
Brian Salomonf9b00422020-10-08 16:00:14 -0400464 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500465 if (s) {
Adlai Holler7580ad42020-06-24 13:45:25 -0400466 REPORTER_ASSERT(reporter, !s->draw(ddl)); // bc the DDL was made w/ textureability
Robert Phillipse8fabb22018-02-04 14:33:21 -0500467
Brian Salomonf9b00422020-10-08 16:00:14 -0400468 dContext->flush();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500469 }
470 }
471
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500472 // Make sure non-GPU-backed surfaces fail characterization
473 {
474 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
475
476 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
477 SkSurfaceCharacterization c;
478 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
479 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500480
481 // Exercise the createResized method
482 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400483 SurfaceParameters params(dContext);
Robert Phillips94458ee2018-03-06 13:41:51 -0500484
Brian Salomonf9b00422020-10-08 16:00:14 -0400485 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips94458ee2018-03-06 13:41:51 -0500486 if (!s) {
487 return;
488 }
489
490 SkSurfaceCharacterization char0;
491 SkAssertResult(s->characterize(&char0));
492
493 // Too small
494 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
495 REPORTER_ASSERT(reporter, !char1.isValid());
496
497 // Too large
498 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
499 REPORTER_ASSERT(reporter, !char2.isValid());
500
501 // Just right
502 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
503 REPORTER_ASSERT(reporter, char3.isValid());
504 REPORTER_ASSERT(reporter, 32 == char3.width());
505 REPORTER_ASSERT(reporter, 32 == char3.height());
506 }
Robert Phillipsa975ef32019-10-03 11:09:17 -0400507
508 // Exercise the createColorSpace method
509 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400510 SurfaceParameters params(dContext);
Robert Phillipsa975ef32019-10-03 11:09:17 -0400511
Brian Salomonf9b00422020-10-08 16:00:14 -0400512 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsa975ef32019-10-03 11:09:17 -0400513 if (!s) {
514 return;
515 }
516
517 SkSurfaceCharacterization char0;
518 SkAssertResult(s->characterize(&char0));
519
520 // The default params create an sRGB color space
521 REPORTER_ASSERT(reporter, char0.colorSpace()->isSRGB());
522 REPORTER_ASSERT(reporter, !char0.colorSpace()->gammaIsLinear());
523
524 {
525 sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
526
527 SkSurfaceCharacterization char1 = char0.createColorSpace(std::move(newCS));
528 REPORTER_ASSERT(reporter, char1.isValid());
529 REPORTER_ASSERT(reporter, !char1.colorSpace()->isSRGB());
530 REPORTER_ASSERT(reporter, char1.colorSpace()->gammaIsLinear());
531 }
532
533 {
534 SkSurfaceCharacterization char2 = char0.createColorSpace(nullptr);
535 REPORTER_ASSERT(reporter, char2.isValid());
536 REPORTER_ASSERT(reporter, !char2.colorSpace());
537 }
538
539 {
540 sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
541
542 SkSurfaceCharacterization invalid;
543 REPORTER_ASSERT(reporter, !invalid.isValid());
544 SkSurfaceCharacterization stillInvalid = invalid.createColorSpace(std::move(newCS));
545 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
546 }
Robert Phillipsa975ef32019-10-03 11:09:17 -0400547 }
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500548
549 // Exercise the createBackendFormat method
550 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400551 SurfaceParameters params(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500552
Brian Salomonf9b00422020-10-08 16:00:14 -0400553 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500554 if (!s) {
555 return;
556 }
557
558 SkSurfaceCharacterization char0;
559 SkAssertResult(s->characterize(&char0));
560
561 // The default params create a renderable RGBA8 surface
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400562 auto originalBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
563 GrRenderable::kYes);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500564 REPORTER_ASSERT(reporter, originalBackendFormat.isValid());
565 REPORTER_ASSERT(reporter, char0.backendFormat() == originalBackendFormat);
566
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400567 auto newBackendFormat = dContext->defaultBackendFormat(kRGB_565_SkColorType,
568 GrRenderable::kYes);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500569
570 if (newBackendFormat.isValid()) {
571 SkSurfaceCharacterization char1 = char0.createBackendFormat(kRGB_565_SkColorType,
572 newBackendFormat);
573 REPORTER_ASSERT(reporter, char1.isValid());
574 REPORTER_ASSERT(reporter, char1.backendFormat() == newBackendFormat);
575
576 SkSurfaceCharacterization invalid;
577 REPORTER_ASSERT(reporter, !invalid.isValid());
578 auto stillInvalid = invalid.createBackendFormat(kRGB_565_SkColorType,
579 newBackendFormat);
580 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
581 }
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500582 }
583
584 // Exercise the createFBO0 method
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400585 if (dContext->backend() == GrBackendApi::kOpenGL) {
586 SurfaceParameters params(dContext);
Greg Daniel638b2e82020-08-27 14:29:00 -0400587 // If the original characterization is textureable then we will fail trying to make an
588 // FBO0 characterization
Brian Salomonf9b00422020-10-08 16:00:14 -0400589 params.disableTextureability();
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500590
Brian Salomonf9b00422020-10-08 16:00:14 -0400591 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500592 if (!s) {
593 return;
594 }
595
596 SkSurfaceCharacterization char0;
597 SkAssertResult(s->characterize(&char0));
598
599 // The default params create a non-FBO0 surface
600 REPORTER_ASSERT(reporter, !char0.usesGLFBO0());
601
602 {
603 SkSurfaceCharacterization char1 = char0.createFBO0(true);
604 REPORTER_ASSERT(reporter, char1.isValid());
605 REPORTER_ASSERT(reporter, char1.usesGLFBO0());
606 }
607
608 {
609 SkSurfaceCharacterization invalid;
610 REPORTER_ASSERT(reporter, !invalid.isValid());
611 SkSurfaceCharacterization stillInvalid = invalid.createFBO0(true);
612 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
613 }
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500614 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500615}
616
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500617#ifdef SK_GL
618
619// Test out the surface compatibility checks regarding FBO0-ness. This test constructs
620// two parallel arrays of characterizations and surfaces in the order:
621// FBO0 w/ MSAA, FBO0 w/o MSAA, not-FBO0 w/ MSAA, not-FBO0 w/o MSAA
622// and then tries all sixteen combinations to check the expected compatibility.
623// Note: this is a GL-only test
624DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(CharacterizationFBO0nessTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400625 auto context = ctxInfo.directContext();
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500626 const GrCaps* caps = context->priv().caps();
627 sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy();
628 const size_t resourceCacheLimit = context->getResourceCacheLimit();
629
630 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
631
632 int availableSamples = caps->getRenderTargetSampleCount(4, format);
633 if (availableSamples <= 1) {
634 // This context doesn't support MSAA for RGBA8
635 return;
636 }
637
638 SkImageInfo ii = SkImageInfo::Make({ 128, 128 }, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
639
640 static constexpr int kStencilBits = 8;
641 static constexpr bool kNotMipMapped = false;
642 static constexpr bool kNotTextureable = false;
643 const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
644
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500645 // Rows are characterizations and columns are surfaces
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500646 static const bool kExpectedCompatibility[4][4] = {
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500647 // FBO0 & MSAA, FBO0 & not-MSAA, not-FBO0 & MSAA, not-FBO0 & not-MSAA
648/* FBO0 & MSAA */ { true, false, false, false },
649/* FBO0 & not-MSAA */ { false, true, false, true },
650/* not-FBO0 & MSAA */ { false, false, true, false },
651/* not-FBO0 & not- */ { false, false, false, true }
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500652 };
653
654 SkSurfaceCharacterization characterizations[4];
655 sk_sp<SkSurface> surfaces[4];
656
657 int index = 0;
658 for (bool isFBO0 : { true, false }) {
659 for (int numSamples : { availableSamples, 1 }) {
660 characterizations[index] = proxy->createCharacterization(resourceCacheLimit,
661 ii, format, numSamples,
662 kTopLeft_GrSurfaceOrigin,
663 surfaceProps, kNotMipMapped,
664 isFBO0, kNotTextureable);
665 SkASSERT(characterizations[index].sampleCount() == numSamples);
666 SkASSERT(characterizations[index].usesGLFBO0() == isFBO0);
667
668 GrGLFramebufferInfo fboInfo{ isFBO0 ? 0 : (GrGLuint) 1, GR_GL_RGBA8 };
669 GrBackendRenderTarget backendRT(128, 128, numSamples, kStencilBits, fboInfo);
670 SkAssertResult(backendRT.isValid());
671
672 surfaces[index] = SkSurface::MakeFromBackendRenderTarget(context, backendRT,
673 kTopLeft_GrSurfaceOrigin,
674 kRGBA_8888_SkColorType,
675 nullptr, &surfaceProps);
676 ++index;
677 }
678 }
679
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500680 for (int c = 0; c < 4; ++c) {
681 for (int s = 0; s < 4; ++s) {
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500682 REPORTER_ASSERT(reporter,
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500683 kExpectedCompatibility[c][s] ==
684 surfaces[s]->isCompatible(characterizations[c]));
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500685 }
686 }
687}
688#endif
689
Greg Daniel007d97d2020-11-04 10:50:39 -0500690#ifdef SK_VULKAN
691DEF_GPUTEST_FOR_VULKAN_CONTEXT(CharacterizationVkSCBnessTest, reporter, ctxInfo) {
692 auto dContext = ctxInfo.directContext();
693
694 SurfaceParameters params(dContext);
695 params.modify(SurfaceParameters::kVkSCBCount);
696 SkSurfaceCharacterization characterization = params.createCharacterization(dContext);
697 REPORTER_ASSERT(reporter, characterization.isValid());
698
699 sk_sp<SkDeferredDisplayList> ddl = params.createDDL(dContext);
700 REPORTER_ASSERT(reporter, ddl.get());
701
702 sk_sp<GrVkSecondaryCBDrawContext> scbDrawContext = params.makeVkSCB(dContext);
703 REPORTER_ASSERT(reporter, scbDrawContext->isCompatible(characterization));
704
705 scbDrawContext->releaseResources();
706}
707#endif
708
Robert Phillips3cd54322019-07-10 09:28:59 -0400709DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400710 auto context = ctxInfo.directContext();
Robert Phillips3cd54322019-07-10 09:28:59 -0400711
712 DDLSurfaceCharacterizationTestImpl(context, reporter);
713}
714
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500715// Test that a DDL created w/o textureability can be replayed into both a textureable and
716// non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a
717// textureable DDL cannot be played into a non-textureable destination but can be replayed
718// into a textureable destination.
719DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400720 auto context = ctxInfo.directContext();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500721
722 // Create a bitmap that we can readback into
723 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
724 kPremul_SkAlphaType);
725 SkBitmap bitmap;
726 bitmap.allocPixels(imageInfo);
727
728 for (bool textureability : { true, false }) {
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400729 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500730
Robert Phillipsc046ff02019-07-01 10:34:03 -0400731 // First, create a DDL w/o textureability (and thus no mipmaps). TODO: once we have
732 // reusable DDLs, move this outside of the loop.
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500733 {
Robert Phillips3cd54322019-07-10 09:28:59 -0400734 SurfaceParameters params(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400735 params.disableTextureability();
Greg Daniel638b2e82020-08-27 14:29:00 -0400736 if (context->backend() == GrBackendApi::kVulkan) {
737 params.setVkRTInputAttachmentSupport(true);
738 }
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500739
740 ddl = params.createDDL(context);
741 SkAssertResult(ddl);
742 }
743
744 // Then verify it can draw into either flavor of destination
Robert Phillips3cd54322019-07-10 09:28:59 -0400745 SurfaceParameters params(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400746 if (!textureability) {
747 params.disableTextureability();
748 }
Greg Daniel638b2e82020-08-27 14:29:00 -0400749 if (context->backend() == GrBackendApi::kVulkan) {
750 params.setVkRTInputAttachmentSupport(true);
751 }
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500752
Brian Salomonf9b00422020-10-08 16:00:14 -0400753 sk_sp<SkSurface> s = params.make(context);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500754 if (!s) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500755 continue;
756 }
757
Adlai Holler7580ad42020-06-24 13:45:25 -0400758 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500759 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Brian Salomonf9b00422020-10-08 16:00:14 -0400760
761 context->flush();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500762 }
763
764}
765
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400766static void test_make_render_target(skiatest::Reporter* reporter,
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400767 GrDirectContext* dContext,
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400768 const SurfaceParameters& params) {
769 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400770 const SkSurfaceCharacterization c = params.createCharacterization(dContext);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400771
Robert Phillipsbe77a022018-04-03 17:17:05 -0400772 if (!c.isValid()) {
Brian Salomonf9b00422020-10-08 16:00:14 -0400773 sk_sp<SkSurface> tmp = params.make(dContext);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400774 // If we couldn't characterize the surface we shouldn't be able to create it either
775 REPORTER_ASSERT(reporter, !tmp);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400776 return;
777 }
778 }
779
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400780 const SkSurfaceCharacterization c = params.createCharacterization(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400781 {
Brian Salomonf9b00422020-10-08 16:00:14 -0400782 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400783 REPORTER_ASSERT(reporter, s);
784 if (!s) {
785 REPORTER_ASSERT(reporter, !c.isValid());
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400786 return;
787 }
788
789 REPORTER_ASSERT(reporter, c.isValid());
Brian Salomonf9b00422020-10-08 16:00:14 -0400790 GrBackendTexture backend = s->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
791 if (backend.isValid()) {
792 REPORTER_ASSERT(reporter, c.isCompatible(backend));
793 }
Robert Phillips9907e6e2019-06-25 14:47:04 -0400794 REPORTER_ASSERT(reporter, s->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400795 // Note that we're leaving 'backend' live here
796 }
797
798 // Make an SkSurface from scratch
799 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400800 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(dContext, c, SkBudgeted::kYes);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400801 REPORTER_ASSERT(reporter, s);
Robert Phillips9907e6e2019-06-25 14:47:04 -0400802 REPORTER_ASSERT(reporter, s->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400803 }
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400804}
805
806////////////////////////////////////////////////////////////////////////////////
807// This tests the SkSurface::MakeRenderTarget variants that take an SkSurfaceCharacterization.
808// In particular, the SkSurface, backendTexture and SkSurfaceCharacterization
809// should always be compatible.
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400810void DDLMakeRenderTargetTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
Brian Salomonf9b00422020-10-08 16:00:14 -0400811 for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
Greg Daniel007d97d2020-11-04 10:50:39 -0500812 if (i == SurfaceParameters::kFBO0Count || i == SurfaceParameters::kVkSCBCount) {
813 // MakeRenderTarget doesn't support FBO0 or vulkan secondary command buffers
Robert Phillipsbe77a022018-04-03 17:17:05 -0400814 continue;
815 }
816
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400817 SurfaceParameters params(dContext);
Brian Salomonf9b00422020-10-08 16:00:14 -0400818 if (i >= 0 && !params.modify(i)) {
819 continue;
Brian Salomon4687bdd2019-05-09 16:28:04 -0400820 }
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400821
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400822 test_make_render_target(reporter, dContext, params);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400823 }
824}
825
Robert Phillips3cd54322019-07-10 09:28:59 -0400826DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400827 auto context = ctxInfo.directContext();
Robert Phillips3cd54322019-07-10 09:28:59 -0400828
829 DDLMakeRenderTargetTestImpl(context, reporter);
830}
831
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400832////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500833static constexpr int kSize = 8;
834
835struct TextureReleaseChecker {
836 TextureReleaseChecker() : fReleaseCount(0) {}
837 int fReleaseCount;
838 static void Release(void* self) {
839 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
840 }
841};
842
843enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
844
845// This tests the ability to create and use wrapped textures in a DDL world
846DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
Adlai Holler14dc7912020-08-11 15:48:49 +0000847 auto dContext = ctxInfo.directContext();
Robert Phillips9b16f812019-05-17 10:01:21 -0400848
Brian Salomon72050802020-10-12 20:45:06 -0400849 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(dContext,
850 kSize,
851 kSize,
852 kRGBA_8888_SkColorType,
853 GrMipmapped::kNo,
854 GrRenderable::kNo,
855 GrProtected::kNo);
856 if (!mbet) {
Brian Salomonf7778972018-03-08 10:13:17 -0500857 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500858 }
Brian Salomonf7778972018-03-08 10:13:17 -0500859
Adlai Holler14dc7912020-08-11 15:48:49 +0000860 SurfaceParameters params(dContext);
Brian Salomonf7778972018-03-08 10:13:17 -0500861
Brian Salomonf9b00422020-10-08 16:00:14 -0400862 sk_sp<SkSurface> s = params.make(dContext);
Brian Salomonf7778972018-03-08 10:13:17 -0500863 if (!s) {
Brian Salomonf7778972018-03-08 10:13:17 -0500864 return;
865 }
866
867 SkSurfaceCharacterization c;
868 SkAssertResult(s->characterize(&c));
869
Adlai Holler14dc7912020-08-11 15:48:49 +0000870 SkDeferredDisplayListRecorder recorder(c);
Brian Salomonf7778972018-03-08 10:13:17 -0500871
Adlai Holler14dc7912020-08-11 15:48:49 +0000872 SkCanvas* canvas = recorder.getCanvas();
873 SkASSERT(canvas);
Adlai Holler74b83a42020-08-06 17:24:53 +0000874
Adlai Holler14dc7912020-08-11 15:48:49 +0000875 auto rContext = canvas->recordingContext();
876 if (!rContext) {
Brian Salomonf7778972018-03-08 10:13:17 -0500877 return;
878 }
879
880 // Wrapped Backend Textures are not supported in DDL
Brian Salomonf7778972018-03-08 10:13:17 -0500881 TextureReleaseChecker releaseChecker;
Brian Salomon72050802020-10-12 20:45:06 -0400882 sk_sp<SkImage> image = SkImage::MakeFromTexture(
883 rContext,
884 mbet->texture(),
885 kTopLeft_GrSurfaceOrigin,
886 kRGBA_8888_SkColorType,
887 kPremul_SkAlphaType,
888 nullptr,
889 sk_gpu_test::ManagedBackendTexture::ReleaseProc,
890 mbet->releaseContext(TextureReleaseChecker::Release, &releaseChecker));
Brian Salomonf7778972018-03-08 10:13:17 -0500891 REPORTER_ASSERT(reporter, !image);
Greg Danielf2336e42018-01-23 16:38:14 -0500892}
893
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400894////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400895// Test out the behavior of an invalid DDLRecorder
896DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
Robert Phillipsdc369702020-08-13 13:34:27 -0400897 auto dContext = ctxInfo.directContext();
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400898
899 {
900 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
Robert Phillipsdc369702020-08-13 13:34:27 -0400901 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, ii);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400902
903 SkSurfaceCharacterization characterization;
904 SkAssertResult(s->characterize(&characterization));
905
906 // never calling getCanvas means the backing surface is never allocated
907 SkDeferredDisplayListRecorder recorder(characterization);
908 }
909
910 {
911 SkSurfaceCharacterization invalid;
912
913 SkDeferredDisplayListRecorder recorder(invalid);
914
915 const SkSurfaceCharacterization c = recorder.characterization();
916 REPORTER_ASSERT(reporter, !c.isValid());
917 REPORTER_ASSERT(reporter, !recorder.getCanvas());
918 REPORTER_ASSERT(reporter, !recorder.detach());
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400919 }
Robert Phillipsdc369702020-08-13 13:34:27 -0400920}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400921
Robert Phillipsdc369702020-08-13 13:34:27 -0400922DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLCreateCharacterizationFailures, reporter, ctxInfo) {
923 auto dContext = ctxInfo.directContext();
924 size_t maxResourceBytes = dContext->getResourceCacheLimit();
925 auto proxy = dContext->threadSafeProxy().get();
926
Greg Daniel638b2e82020-08-27 14:29:00 -0400927 auto check_create_fails =
928 [proxy, reporter, maxResourceBytes](const GrBackendFormat& backendFormat,
929 int width, int height,
930 SkColorType ct, bool willUseGLFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500931 bool isTextureable,
Greg Daniel638b2e82020-08-27 14:29:00 -0400932 GrProtected prot,
Greg Daniel007d97d2020-11-04 10:50:39 -0500933 bool vkRTSupportsInputAttachment,
934 bool forVulkanSecondaryCommandBuffer) {
Robert Phillipsdc369702020-08-13 13:34:27 -0400935 const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
936
937 SkImageInfo ii = SkImageInfo::Make(width, height, ct,
938 kPremul_SkAlphaType, nullptr);
939
940 SkSurfaceCharacterization c = proxy->createCharacterization(
941 maxResourceBytes, ii, backendFormat, 1,
942 kBottomLeft_GrSurfaceOrigin, surfaceProps, false,
Greg Daniel007d97d2020-11-04 10:50:39 -0500943 willUseGLFBO0, isTextureable, prot,
944 vkRTSupportsInputAttachment,
945 forVulkanSecondaryCommandBuffer);
Robert Phillipsdc369702020-08-13 13:34:27 -0400946 REPORTER_ASSERT(reporter, !c.isValid());
947 };
948
949 GrBackendFormat goodBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
950 GrRenderable::kYes);
951 SkASSERT(goodBackendFormat.isValid());
952
953 GrBackendFormat badBackendFormat;
954 SkASSERT(!badBackendFormat.isValid());
955
956 SkColorType kGoodCT = kRGBA_8888_SkColorType;
957 SkColorType kBadCT = kUnknown_SkColorType;
958
Greg Daniel007d97d2020-11-04 10:50:39 -0500959 static const bool kIsTextureable = true;
960 static const bool kIsNotTextureable = false;
961
Robert Phillipsdc369702020-08-13 13:34:27 -0400962 static const bool kGoodUseFBO0 = false;
963 static const bool kBadUseFBO0 = true;
964
Greg Daniel638b2e82020-08-27 14:29:00 -0400965 static const bool kGoodVkInputAttachment = false;
966 static const bool kBadVkInputAttachment = true;
967
Greg Daniel007d97d2020-11-04 10:50:39 -0500968 static const bool kGoodForVkSCB = false;
969 static const bool kBadForVkSCB = true;
970
Robert Phillipsdc369702020-08-13 13:34:27 -0400971 int goodWidth = 64;
972 int goodHeight = 64;
973 int badWidths[] = { 0, 1048576 };
974 int badHeights[] = { 0, 1048576 };
975
Greg Daniel638b2e82020-08-27 14:29:00 -0400976
977 // In each of the check_create_fails calls there is one bad parameter that should cause the
978 // creation of the characterization to fail.
979 check_create_fails(goodBackendFormat, goodWidth, badHeights[0], kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500980 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400981 check_create_fails(goodBackendFormat, goodWidth, badHeights[1], kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500982 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400983 check_create_fails(goodBackendFormat, badWidths[0], goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500984 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400985 check_create_fails(goodBackendFormat, badWidths[1], goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500986 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400987 check_create_fails(badBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500988 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400989 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kBadCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500990 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400991 // This fails because we always try to make a characterization that is textureable and we can't
992 // have UseFBO0 be true and textureable.
993 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500994 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Robert Phillipsdc369702020-08-13 13:34:27 -0400995 if (dContext->backend() == GrBackendApi::kVulkan) {
Greg Daniel638b2e82020-08-27 14:29:00 -0400996 // The bad parameter in this case is the GrProtected::kYes since none of our test contexts
997 // are made protected we can't have a protected surface.
998 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500999 kIsTextureable, GrProtected::kYes, kGoodVkInputAttachment,
1000 kGoodForVkSCB);
1001 // The following fails because forVulkanSecondaryCommandBuffer is true and
1002 // isTextureable is true. This is not a legal combination.
Greg Daniel638b2e82020-08-27 14:29:00 -04001003 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -05001004 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kBadForVkSCB);
1005 // The following fails because forVulkanSecondaryCommandBuffer is true and
1006 // vkRTSupportsInputAttachment is true. This is not a legal combination.
1007 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1008 kIsNotTextureable, GrProtected::kNo, kBadVkInputAttachment,
1009 kBadForVkSCB);
1010 // The following fails because forVulkanSecondaryCommandBuffer is true and
1011 // willUseGLFBO0 is true. This is not a legal combination.
1012 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
1013 kIsNotTextureable, GrProtected::kNo, kGoodVkInputAttachment,
1014 kBadForVkSCB);
1015 } else {
1016 // The following set vulkan only flags on non vulkan backends.
1017 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1018 kIsTextureable, GrProtected::kNo, kBadVkInputAttachment, kGoodForVkSCB);
1019 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1020 kIsNotTextureable, GrProtected::kNo, kGoodVkInputAttachment,
1021 kBadForVkSCB);
Robert Phillipsdc369702020-08-13 13:34:27 -04001022 }
Robert Phillips6ceaafa2018-03-15 16:53:06 -04001023}
1024
Robert Phillips6b6fcc72018-03-30 13:57:00 -04001025////////////////////////////////////////////////////////////////////////////////
Robert Phillipsee5fd132019-05-07 13:29:22 -04001026// Test that flushing a DDL via SkSurface::flush works
1027
1028struct FulfillInfo {
1029 sk_sp<SkPromiseImageTexture> fTex;
1030 bool fFulfilled = false;
1031 bool fReleased = false;
Robert Phillipsee5fd132019-05-07 13:29:22 -04001032};
1033
1034static sk_sp<SkPromiseImageTexture> tracking_fulfill_proc(void* context) {
1035 FulfillInfo* info = (FulfillInfo*) context;
1036 info->fFulfilled = true;
1037 return info->fTex;
1038}
1039
1040static void tracking_release_proc(void* context) {
1041 FulfillInfo* info = (FulfillInfo*) context;
1042 info->fReleased = true;
1043}
1044
Robert Phillipsee5fd132019-05-07 13:29:22 -04001045DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSkSurfaceFlush, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001046 auto context = ctxInfo.directContext();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001047
1048 SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1049 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1050
1051 SkSurfaceCharacterization characterization;
1052 SkAssertResult(s->characterize(&characterization));
1053
Brian Salomon72050802020-10-12 20:45:06 -04001054 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeFromInfo(context, ii);
1055 if (!mbet) {
1056 ERRORF(reporter, "Could not make texture.");
Robert Phillipsee5fd132019-05-07 13:29:22 -04001057 return;
1058 }
1059
1060 FulfillInfo fulfillInfo;
Brian Salomon72050802020-10-12 20:45:06 -04001061 fulfillInfo.fTex = SkPromiseImageTexture::Make(mbet->texture());
Robert Phillipsee5fd132019-05-07 13:29:22 -04001062
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001063 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillipsee5fd132019-05-07 13:29:22 -04001064
1065 {
1066 SkDeferredDisplayListRecorder recorder(characterization);
1067
Robert Phillips0a15cc62019-07-30 12:49:10 -04001068 GrBackendFormat format = context->defaultBackendFormat(kRGBA_8888_SkColorType,
1069 GrRenderable::kNo);
1070 SkASSERT(format.isValid());
Robert Phillipsee5fd132019-05-07 13:29:22 -04001071
Adlai Holler38b9a4b2021-02-25 17:54:49 +00001072 SkCanvas* canvas = recorder.getCanvas();
Adlai Holler07e11d42021-02-25 10:26:05 -05001073
Adlai Holler55aaefe2021-03-03 16:12:56 -07001074 sk_sp<SkImage> promiseImage = SkImage::MakePromiseTexture(
1075 canvas->recordingContext()->threadSafeProxy(),
1076 format,
1077 SkISize::Make(32, 32),
1078 GrMipmapped::kNo,
1079 kTopLeft_GrSurfaceOrigin,
1080 kRGBA_8888_SkColorType,
1081 kPremul_SkAlphaType,
1082 nullptr,
1083 tracking_fulfill_proc,
1084 tracking_release_proc,
1085 &fulfillInfo);
1086
Robert Phillipsee5fd132019-05-07 13:29:22 -04001087 canvas->clear(SK_ColorRED);
1088 canvas->drawImage(promiseImage, 0, 0);
1089 ddl = recorder.detach();
1090 }
1091
Greg Daniel0a2464f2020-05-14 15:45:44 -04001092 context->flushAndSubmit();
Robert Phillips15c91422019-05-07 16:54:48 -04001093
Adlai Holler7580ad42020-06-24 13:45:25 -04001094 s->draw(ddl);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001095
1096 GrFlushInfo flushInfo;
Robert Phillips8e49a692019-05-07 15:57:25 -04001097 s->flush(SkSurface::BackendSurfaceAccess::kPresent, flushInfo);
Greg Daniel0a2464f2020-05-14 15:45:44 -04001098 context->submit();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001099
1100 REPORTER_ASSERT(reporter, fulfillInfo.fFulfilled);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001101
Jim Van Verth1c318eb2021-05-07 16:25:49 -04001102 // In order to receive the done callback with the low-level APIs we need to re-flush
1103 s->flush();
1104 context->submit(true);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001105
Brian Salomonf1432742020-11-09 15:40:27 -05001106 REPORTER_ASSERT(reporter, fulfillInfo.fReleased);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001107
1108 REPORTER_ASSERT(reporter, fulfillInfo.fTex->unique());
1109 fulfillInfo.fTex.reset();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001110}
1111
1112////////////////////////////////////////////////////////////////////////////////
Robert Phillipsf54883c2018-12-18 08:29:09 -05001113// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
1114DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001115 auto context = ctxInfo.directContext();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001116
1117 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1118 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1119
1120 SkBitmap bitmap;
1121 bitmap.allocPixels(ii);
1122
1123 SkSurfaceCharacterization characterization;
1124 SkAssertResult(s->characterize(&characterization));
1125
1126 SkDeferredDisplayListRecorder recorder(characterization);
1127
1128 SkCanvas* canvas1 = recorder.getCanvas();
1129
1130 canvas1->clear(SK_ColorRED);
1131
1132 canvas1->save();
1133 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
1134
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001135 sk_sp<SkDeferredDisplayList> ddl1 = recorder.detach();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001136
1137 SkCanvas* canvas2 = recorder.getCanvas();
1138
1139 SkPaint p;
1140 p.setColor(SK_ColorGREEN);
1141 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
1142
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001143 sk_sp<SkDeferredDisplayList> ddl2 = recorder.detach();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001144
1145 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
1146 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
1147
1148 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
1149 // lazy proxy are all different between the two DDLs
1150 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
1151
Adlai Holler7580ad42020-06-24 13:45:25 -04001152 s->draw(ddl1);
1153 s->draw(ddl2);
Robert Phillipsf54883c2018-12-18 08:29:09 -05001154
1155 // Make sure the clipRect from DDL1 didn't percolate into DDL2
1156 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
1157 for (int y = 0; y < 32; ++y) {
1158 for (int x = 0; x < 32; ++x) {
1159 REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
1160 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
1161 return; // we only really need to report the error once
1162 }
1163 }
1164 }
1165}
1166
John Rosascoa9b348f2019-11-08 13:18:15 -08001167#ifdef SK_GL
Adlai Holler55aaefe2021-03-03 16:12:56 -07001168
Kevin Lubickbe03ef12021-06-16 15:28:00 -04001169static sk_sp<SkPromiseImageTexture> noop_fulfill_proc(void*) {
Adlai Holler55aaefe2021-03-03 16:12:56 -07001170 SkASSERT(0);
1171 return nullptr;
1172}
1173
Robert Phillipsf54883c2018-12-18 08:29:09 -05001174////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -04001175// Check that the texture-specific flags (i.e., for external & rectangle textures) work
1176// for promise images. As such, this is a GL-only test.
1177DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001178 auto context = ctxInfo.directContext();
Robert Phillipsabf7b762018-03-21 12:13:37 -04001179
1180 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1181 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1182
1183 SkSurfaceCharacterization characterization;
1184 SkAssertResult(s->characterize(&characterization));
1185
1186 SkDeferredDisplayListRecorder recorder(characterization);
1187
1188 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Brian Salomon7e67dca2020-07-21 09:27:25 -04001189 for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
Greg Daniel09c94002018-06-08 22:11:51 +00001190 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001191
Adlai Holler55aaefe2021-03-03 16:12:56 -07001192 sk_sp<SkImage> image = SkImage::MakePromiseTexture(
1193 recorder.getCanvas()->recordingContext()->threadSafeProxy(),
Brian Salomonf1432742020-11-09 15:40:27 -05001194 format,
Adlai Holler55aaefe2021-03-03 16:12:56 -07001195 SkISize::Make(32, 32),
Brian Salomonf1432742020-11-09 15:40:27 -05001196 mipMapped,
Brian Salomonf55e8d52019-01-30 17:28:20 -05001197 kTopLeft_GrSurfaceOrigin,
1198 kRGBA_8888_SkColorType,
Brian Salomonf1432742020-11-09 15:40:27 -05001199 kPremul_SkAlphaType,
Adlai Holler55aaefe2021-03-03 16:12:56 -07001200 /*color space*/nullptr,
Kevin Lubickbe03ef12021-06-16 15:28:00 -04001201 noop_fulfill_proc,
Brian Salomonf1432742020-11-09 15:40:27 -05001202 /*release proc*/ nullptr,
Adlai Holler55aaefe2021-03-03 16:12:56 -07001203 /*context*/nullptr);
Brian Salomon7e67dca2020-07-21 09:27:25 -04001204 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipmapped::kYes) {
Greg Daniel09c94002018-06-08 22:11:51 +00001205 REPORTER_ASSERT(reporter, !image);
1206 continue;
1207 }
1208 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001209
Brian Salomone6662542021-02-23 10:45:39 -05001210 GrTextureProxy* backingProxy = sk_gpu_test::GetTextureImageProxy(image.get(), context);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001211
Brian Salomon8c82a872020-07-21 12:09:58 -04001212 REPORTER_ASSERT(reporter, backingProxy->mipmapped() == mipMapped);
Greg Daniel09c94002018-06-08 22:11:51 +00001213 if (GR_GL_TEXTURE_2D == target) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001214 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001215 } else {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001216 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001217 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001218 }
1219 }
Robert Phillipsbe77a022018-04-03 17:17:05 -04001220}
John Rosascoa9b348f2019-11-08 13:18:15 -08001221#endif // SK_GL
Robert Phillipsbe77a022018-04-03 17:17:05 -04001222
1223////////////////////////////////////////////////////////////////////////////////
Robert Phillips646f6372018-09-25 09:31:10 -04001224// Test colorType and pixelConfig compatibility.
Robert Phillipsbe77a022018-04-03 17:17:05 -04001225DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001226 auto context = ctxInfo.directContext();
Robert Phillipsbe77a022018-04-03 17:17:05 -04001227
1228 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
1229 SkColorType colorType = static_cast<SkColorType>(ct);
1230
Robert Phillips3cd54322019-07-10 09:28:59 -04001231 SurfaceParameters params(context);
Greg Daniel60ea40c2019-02-12 13:38:44 -05001232 params.setColorType(colorType);
1233 params.setColorSpace(nullptr);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001234
Robert Phillipsd8f79a22019-06-24 13:25:42 -04001235 test_make_render_target(reporter, context, params);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001236 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001237
1238}