blob: 5b8f80239d64cdcd6789203ec8b1a0e6cb5e316b [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"
Brian Salomoneebe7352020-12-09 16:37:04 -050037#include "src/gpu/GrSurfaceDrawContext.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040038#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050039#include "src/gpu/SkGpuDevice.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050040#include "src/gpu/gl/GrGLDefines.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040041#include "src/image/SkImage_GpuBase.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050042#include "src/image/SkSurface_Gpu.h"
43#include "tests/Test.h"
Robert Phillipsee5fd132019-05-07 13:29:22 -040044#include "tests/TestUtils.h"
Brian Salomonf9b00422020-10-08 16:00:14 -040045#include "tools/gpu/BackendSurfaceFactory.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050046#include "tools/gpu/GrContextFactory.h"
Brian Salomon72050802020-10-12 20:45:06 -040047#include "tools/gpu/ManagedBackendTexture.h"
Brian Salomone6662542021-02-23 10:45:39 -050048#include "tools/gpu/ProxyUtils.h"
Ben Wagner9707a7e2019-05-06 17:17:19 -040049
50#include <initializer_list>
51#include <memory>
52#include <utility>
Robert Phillipsfc711a22018-02-13 17:03:00 -050053
Robert Phillips3cd54322019-07-10 09:28:59 -040054#ifdef SK_VULKAN
55#include "src/gpu/vk/GrVkCaps.h"
Greg Daniel007d97d2020-11-04 10:50:39 -050056#include "src/gpu/vk/GrVkSecondaryCBDrawContext.h"
Robert Phillips3cd54322019-07-10 09:28:59 -040057#endif
58
Robert Phillips7ffbcf92017-12-04 12:52:46 -050059class SurfaceParameters {
60public:
Greg Daniel007d97d2020-11-04 10:50:39 -050061 static const int kNumParams = 13;
Robert Phillips3cd54322019-07-10 09:28:59 -040062 static const int kFBO0Count = 9;
Greg Daniel007d97d2020-11-04 10:50:39 -050063 static const int kVkSCBCount = 12;
Robert Phillips7ffbcf92017-12-04 12:52:46 -050064
Robert Phillipsc8ae4942020-07-20 10:56:01 -040065 SurfaceParameters(GrRecordingContext* rContext)
66 : fBackend(rContext->backend())
Brian Salomonf9b00422020-10-08 16:00:14 -040067 , fCanBeProtected(false)
Robert Phillipsb45f47d2019-02-03 17:17:54 -050068 , fWidth(64)
Robert Phillips7ffbcf92017-12-04 12:52:46 -050069 , fHeight(64)
70 , fOrigin(kTopLeft_GrSurfaceOrigin)
71 , fColorType(kRGBA_8888_SkColorType)
72 , fColorSpace(SkColorSpace::MakeSRGB())
Brian Salomonbdecacf2018-02-02 20:32:49 -050073 , fSampleCount(1)
Robert Phillipse8fabb22018-02-04 14:33:21 -050074 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
Robert Phillipsb45f47d2019-02-03 17:17:54 -050075 , fShouldCreateMipMaps(true)
76 , fUsesGLFBO0(false)
Robert Phillips3cd54322019-07-10 09:28:59 -040077 , fIsTextureable(true)
Greg Daniel638b2e82020-08-27 14:29:00 -040078 , fIsProtected(GrProtected::kNo)
Greg Daniel007d97d2020-11-04 10:50:39 -050079 , fVkRTSupportsInputAttachment(false)
80 , fForVulkanSecondaryCommandBuffer(false) {
Robert Phillips3cd54322019-07-10 09:28:59 -040081#ifdef SK_VULKAN
Brian Salomonf9b00422020-10-08 16:00:14 -040082 if (rContext->backend() == GrBackendApi::kVulkan) {
83 auto vkCaps = static_cast<const GrVkCaps*>(rContext->priv().caps());
84 fCanBeProtected = vkCaps->supportsProtectedMemory();
85 if (fCanBeProtected) {
86 fIsProtected = GrProtected::kYes;
87 }
Robert Phillips3cd54322019-07-10 09:28:59 -040088 }
89#endif
Brian Salomonf9b00422020-10-08 16:00:14 -040090 if (!rContext->priv().caps()->mipmapSupport()) {
91 fShouldCreateMipMaps = false;
92 }
Robert Phillipse8fabb22018-02-04 14:33:21 -050093 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -050094
95 int sampleCount() const { return fSampleCount; }
96
Robert Phillipsbe77a022018-04-03 17:17:05 -040097 void setColorType(SkColorType ct) { fColorType = ct; }
Robert Phillipsd8f79a22019-06-24 13:25:42 -040098 SkColorType colorType() const { return fColorType; }
Robert Phillipsbe77a022018-04-03 17:17:05 -040099 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
Brian Salomonf9b00422020-10-08 16:00:14 -0400100 void disableTextureability() {
101 fIsTextureable = false;
102 fShouldCreateMipMaps = false;
103 }
Brian Salomon4687bdd2019-05-09 16:28:04 -0400104 void setShouldCreateMipMaps(bool shouldCreateMipMaps) {
105 fShouldCreateMipMaps = shouldCreateMipMaps;
106 }
Greg Daniel638b2e82020-08-27 14:29:00 -0400107 void setVkRTInputAttachmentSupport(bool inputSupport) {
108 fVkRTSupportsInputAttachment = inputSupport;
109 }
Greg Daniel007d97d2020-11-04 10:50:39 -0500110 void setForVulkanSecondaryCommandBuffer(bool forVkSCB) {
111 fForVulkanSecondaryCommandBuffer = forVkSCB;
112 }
Robert Phillipsbe77a022018-04-03 17:17:05 -0400113
Brian Salomonf9b00422020-10-08 16:00:14 -0400114 // Modify the SurfaceParameters in just one way. Returns false if the requested modification had
115 // no effect.
116 bool modify(int i) {
117 bool changed = false;
118 auto set = [&changed](auto& var, auto value) {
119 if (var != value) {
120 changed = true;
121 }
122 var = value;
123 };
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500124 switch (i) {
125 case 0:
Brian Salomonf9b00422020-10-08 16:00:14 -0400126 set(fWidth, 63);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500127 break;
128 case 1:
Brian Salomonf9b00422020-10-08 16:00:14 -0400129 set(fHeight, 63);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500130 break;
131 case 2:
Brian Salomonf9b00422020-10-08 16:00:14 -0400132 set(fOrigin, kBottomLeft_GrSurfaceOrigin);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500133 break;
134 case 3:
Brian Salomonf9b00422020-10-08 16:00:14 -0400135 set(fColorType, kRGBA_F16_SkColorType);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500136 break;
137 case 4:
Brian Osman37f99882018-08-09 10:26:57 -0400138 // This just needs to be a colorSpace different from that returned by MakeSRGB().
139 // In this case we just change the gamut.
Brian Salomonf9b00422020-10-08 16:00:14 -0400140 set(fColorSpace, SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
141 SkNamedGamut::kAdobeRGB));
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500142 break;
Brian Salomonf9b00422020-10-08 16:00:14 -0400143 case 5:
144 set(fSampleCount, 4);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500145 break;
146 case 6:
Brian Salomonf9b00422020-10-08 16:00:14 -0400147 set(fSurfaceProps, SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry));
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500148 break;
149 case 7:
Brian Salomonf9b00422020-10-08 16:00:14 -0400150 set(fSurfaceProps, SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
151 kUnknown_SkPixelGeometry));
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500152 break;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500153 case 8:
Brian Salomonf9b00422020-10-08 16:00:14 -0400154 set(fShouldCreateMipMaps, false);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500155 break;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500156 case 9:
157 if (GrBackendApi::kOpenGL == fBackend) {
Brian Salomonf9b00422020-10-08 16:00:14 -0400158 set(fUsesGLFBO0, true);
159 set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability
160 set(fIsTextureable, false);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500161 }
162 break;
163 case 10:
Brian Salomonf9b00422020-10-08 16:00:14 -0400164 set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability
165 set(fIsTextureable, false);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500166 break;
Robert Phillips3cd54322019-07-10 09:28:59 -0400167 case 11:
Brian Salomonf9b00422020-10-08 16:00:14 -0400168 if (fCanBeProtected) {
169 set(fIsProtected, GrProtected(!static_cast<bool>(fIsProtected)));
170 }
Robert Phillips3cd54322019-07-10 09:28:59 -0400171 break;
Greg Daniel007d97d2020-11-04 10:50:39 -0500172 case 12:
173 if (GrBackendApi::kVulkan == fBackend) {
174 set(fForVulkanSecondaryCommandBuffer, true);
175 set(fUsesGLFBO0, false);
176 set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability
177 set(fIsTextureable, false);
178 set(fVkRTSupportsInputAttachment, false);
179 }
180 break;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500181 }
Brian Salomonf9b00422020-10-08 16:00:14 -0400182 return changed;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500183 }
184
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400185 SkSurfaceCharacterization createCharacterization(GrDirectContext* dContext) const {
186 size_t maxResourceBytes = dContext->getResourceCacheLimit();
Robert Phillipsfc711a22018-02-13 17:03:00 -0500187
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400188 if (!dContext->colorTypeSupportedAsSurface(fColorType)) {
Robert Phillipsd470e1b2019-09-04 15:05:35 -0400189 return SkSurfaceCharacterization();
190 }
191
Robert Phillipsfc711a22018-02-13 17:03:00 -0500192 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
193 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
194 kPremul_SkAlphaType, fColorSpace);
195
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400196 GrBackendFormat backendFormat = dContext->defaultBackendFormat(fColorType,
197 GrRenderable::kYes);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400198 if (!backendFormat.isValid()) {
199 return SkSurfaceCharacterization();
200 }
Robert Phillipsfc711a22018-02-13 17:03:00 -0500201
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400202 SkSurfaceCharacterization c = dContext->threadSafeProxy()->createCharacterization(
Robert Phillipsfc711a22018-02-13 17:03:00 -0500203 maxResourceBytes, ii, backendFormat, fSampleCount,
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500204 fOrigin, fSurfaceProps, fShouldCreateMipMaps,
Greg Daniel638b2e82020-08-27 14:29:00 -0400205 fUsesGLFBO0, fIsTextureable, fIsProtected,
Greg Daniel007d97d2020-11-04 10:50:39 -0500206 fVkRTSupportsInputAttachment,
207 fForVulkanSecondaryCommandBuffer);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400208 return c;
209 }
210
211 // Create a DDL whose characterization captures the current settings
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400212 sk_sp<SkDeferredDisplayList> createDDL(GrDirectContext* dContext) const {
213 SkSurfaceCharacterization c = this->createCharacterization(dContext);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500214 SkAssertResult(c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500215
216 SkDeferredDisplayListRecorder r(c);
217 SkCanvas* canvas = r.getCanvas();
218 if (!canvas) {
219 return nullptr;
220 }
221
222 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
223 return r.detach();
224 }
225
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500226 // Create the surface with the current set of parameters
Brian Salomonf9b00422020-10-08 16:00:14 -0400227 sk_sp<SkSurface> make(GrDirectContext* dContext) const {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400228 const SkSurfaceCharacterization c = this->createCharacterization(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400229
John Rosasco24cbdab2019-09-25 14:14:35 -0700230#ifdef SK_GL
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500231 if (fUsesGLFBO0) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400232 if (GrBackendApi::kOpenGL != dContext->backend()) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500233 return nullptr;
234 }
235
236 GrGLFramebufferInfo fboInfo;
237 fboInfo.fFBOID = 0;
238 fboInfo.fFormat = GR_GL_RGBA8;
239 static constexpr int kStencilBits = 8;
240 GrBackendRenderTarget backendRT(fWidth, fHeight, 1, kStencilBits, fboInfo);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500241
242 if (!backendRT.isValid()) {
243 return nullptr;
244 }
245
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400246 sk_sp<SkSurface> result = SkSurface::MakeFromBackendRenderTarget(dContext, backendRT,
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400247 fOrigin, fColorType,
248 fColorSpace,
249 &fSurfaceProps);
Robert Phillips9907e6e2019-06-25 14:47:04 -0400250 SkASSERT(result->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400251 return result;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500252 }
John Rosasco24cbdab2019-09-25 14:14:35 -0700253#endif
Robert Phillipsc046ff02019-07-01 10:34:03 -0400254
Greg Daniel007d97d2020-11-04 10:50:39 -0500255 // We can't make SkSurfaces for vulkan secondary command buffers.
256 if (fForVulkanSecondaryCommandBuffer) {
257 return nullptr;
258 }
259
Robert Phillipsbe77a022018-04-03 17:17:05 -0400260 sk_sp<SkSurface> surface;
Brian Salomonf9b00422020-10-08 16:00:14 -0400261 if (fIsTextureable) {
262 surface = sk_gpu_test::MakeBackendTextureSurface(dContext,
263 {fWidth, fHeight},
264 fOrigin,
265 fSampleCount,
266 fColorType,
267 fColorSpace,
268 GrMipmapped(fShouldCreateMipMaps),
269 fIsProtected,
270 &fSurfaceProps);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400271 } else {
Brian Salomonf9b00422020-10-08 16:00:14 -0400272 // Create a surface w/ the current parameters but make it non-textureable
273 SkASSERT(!fShouldCreateMipMaps);
274 surface = sk_gpu_test::MakeBackendRenderTargetSurface(dContext,
275 {fWidth, fHeight},
276 fOrigin,
277 fSampleCount,
278 fColorType,
279 fColorSpace,
280 fIsProtected,
281 &fSurfaceProps);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400282 }
Robert Phillipse8fabb22018-02-04 14:33:21 -0500283
284 if (!surface) {
Robert Phillipsc046ff02019-07-01 10:34:03 -0400285 SkASSERT(!c.isValid());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500286 return nullptr;
287 }
288
Brian Salomonf9b00422020-10-08 16:00:14 -0400289 GrBackendTexture texture =
290 surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
291 if (texture.isValid()) {
292 SkASSERT(c.isCompatible(texture));
293 }
Robert Phillipsc046ff02019-07-01 10:34:03 -0400294 SkASSERT(c.isValid());
Robert Phillips9907e6e2019-06-25 14:47:04 -0400295 SkASSERT(surface->isCompatible(c));
Robert Phillipse8fabb22018-02-04 14:33:21 -0500296 return surface;
297 }
298
Greg Daniel007d97d2020-11-04 10:50:39 -0500299#ifdef SK_VULKAN
300 sk_sp<GrVkSecondaryCBDrawContext> makeVkSCB(GrDirectContext* dContext) {
301 const SkSurfaceCharacterization c = this->createCharacterization(dContext);
302 SkImageInfo imageInfo = SkImageInfo::Make({fWidth, fHeight},
303 {fColorType, kPremul_SkAlphaType, fColorSpace});
304 GrVkDrawableInfo vkInfo;
305 // putting in a bunch of dummy values here
306 vkInfo.fSecondaryCommandBuffer = (VkCommandBuffer)1;
307 vkInfo.fColorAttachmentIndex = 0;
308 vkInfo.fCompatibleRenderPass = (VkRenderPass)1;
309 vkInfo.fFormat = VK_FORMAT_R8G8B8A8_UNORM;
310 vkInfo.fDrawBounds = nullptr;
311 vkInfo.fImage = (VkImage)1;
312
313 return GrVkSecondaryCBDrawContext::Make(dContext, imageInfo, vkInfo, &fSurfaceProps);
314 }
315#endif
316
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500317private:
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500318 GrBackendApi fBackend;
Brian Salomonf9b00422020-10-08 16:00:14 -0400319 bool fCanBeProtected;
320
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500321 int fWidth;
322 int fHeight;
323 GrSurfaceOrigin fOrigin;
324 SkColorType fColorType;
325 sk_sp<SkColorSpace> fColorSpace;
326 int fSampleCount;
327 SkSurfaceProps fSurfaceProps;
Robert Phillipse8fabb22018-02-04 14:33:21 -0500328 bool fShouldCreateMipMaps;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500329 bool fUsesGLFBO0;
330 bool fIsTextureable;
Robert Phillips3cd54322019-07-10 09:28:59 -0400331 GrProtected fIsProtected;
Greg Daniel638b2e82020-08-27 14:29:00 -0400332 bool fVkRTSupportsInputAttachment;
Greg Daniel007d97d2020-11-04 10:50:39 -0500333 bool fForVulkanSecondaryCommandBuffer;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500334};
335
Robert Phillipsc1267c62018-04-04 11:12:39 -0400336// Test out operator== && operator!=
337DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400338 auto context = ctxInfo.directContext();
Robert Phillipsc1267c62018-04-04 11:12:39 -0400339
Brian Salomonf9b00422020-10-08 16:00:14 -0400340 for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400341 SurfaceParameters params1(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400342 bool didModify1 = i >= 0 && params1.modify(i);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400343
344 SkSurfaceCharacterization char1 = params1.createCharacterization(context);
345 if (!char1.isValid()) {
346 continue; // can happen on some platforms (ChromeOS)
347 }
348
Brian Salomonf9b00422020-10-08 16:00:14 -0400349 for (int j = -1; j < SurfaceParameters::kNumParams; ++j) {
Robert Phillips3cd54322019-07-10 09:28:59 -0400350 SurfaceParameters params2(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400351 bool didModify2 = j >= 0 && params2.modify(j);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400352
353 SkSurfaceCharacterization char2 = params2.createCharacterization(context);
354 if (!char2.isValid()) {
355 continue; // can happen on some platforms (ChromeOS)
356 }
357
Brian Salomonf9b00422020-10-08 16:00:14 -0400358 if (i == j || (!didModify1 && !didModify2)) {
Robert Phillipsc1267c62018-04-04 11:12:39 -0400359 REPORTER_ASSERT(reporter, char1 == char2);
360 } else {
361 REPORTER_ASSERT(reporter, char1 != char2);
362 }
Robert Phillipsc1267c62018-04-04 11:12:39 -0400363 }
364 }
365
366 {
Robert Phillips3cd54322019-07-10 09:28:59 -0400367 SurfaceParameters params(context);
Robert Phillipsc1267c62018-04-04 11:12:39 -0400368
369 SkSurfaceCharacterization valid = params.createCharacterization(context);
370 SkASSERT(valid.isValid());
371
372 SkSurfaceCharacterization inval1, inval2;
373 SkASSERT(!inval1.isValid() && !inval2.isValid());
374
375 REPORTER_ASSERT(reporter, inval1 != inval2);
376 REPORTER_ASSERT(reporter, valid != inval1);
377 REPORTER_ASSERT(reporter, inval1 != valid);
378 }
379}
380
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400381////////////////////////////////////////////////////////////////////////////////
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500382// This tests SkSurfaceCharacterization/SkSurface compatibility
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400383void DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
Robert Phillips9e441ee2018-02-01 15:14:55 -0500384 // Create a bitmap that we can readback into
385 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
386 kPremul_SkAlphaType);
387 SkBitmap bitmap;
388 bitmap.allocPixels(imageInfo);
389
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400390 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500391
392 // First, create a DDL using the stock SkSurface parameters
393 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400394 SurfaceParameters params(dContext);
Greg Daniel638b2e82020-08-27 14:29:00 -0400395 if (dContext->backend() == GrBackendApi::kVulkan) {
396 params.setVkRTInputAttachmentSupport(true);
397 }
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400398 ddl = params.createDDL(dContext);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500399 SkAssertResult(ddl);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500400
401 // The DDL should draw into an SkSurface created with the same parameters
Brian Salomonf9b00422020-10-08 16:00:14 -0400402 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500403 if (!s) {
404 return;
405 }
406
Adlai Holler7580ad42020-06-24 13:45:25 -0400407 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500408 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Brian Salomonf9b00422020-10-08 16:00:14 -0400409
410 dContext->flush();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500411 }
412
413 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
414 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400415 SurfaceParameters params(dContext);
Brian Salomonf9b00422020-10-08 16:00:14 -0400416 if (!params.modify(i)) {
417 continue;
Robert Phillips3cd54322019-07-10 09:28:59 -0400418 }
419
Brian Salomonf9b00422020-10-08 16:00:14 -0400420 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500421 if (!s) {
422 continue;
423 }
424
Adlai Holler7580ad42020-06-24 13:45:25 -0400425 REPORTER_ASSERT(reporter, !s->draw(ddl),
Robert Phillipse8fabb22018-02-04 14:33:21 -0500426 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
Brian Salomonf9b00422020-10-08 16:00:14 -0400427 dContext->flush();
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500428 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500429
430 // Next test the compatibility of resource cache parameters
431 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400432 const SurfaceParameters params(dContext);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400433
Brian Salomonf9b00422020-10-08 16:00:14 -0400434 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500435
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400436 size_t maxResourceBytes = dContext->getResourceCacheLimit();
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500437
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400438 dContext->setResourceCacheLimit(maxResourceBytes/2);
Adlai Holler7580ad42020-06-24 13:45:25 -0400439 REPORTER_ASSERT(reporter, !s->draw(ddl));
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500440
Robert Phillips9e441ee2018-02-01 15:14:55 -0500441 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
442 // For now, DDLs are drawn once.
443#if 0
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500444 // resource limits >= those at characterization time are accepted
445 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400446 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500447 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500448
449 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400450 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500451 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500452
453 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
Adlai Holler7580ad42020-06-24 13:45:25 -0400454 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillips9e441ee2018-02-01 15:14:55 -0500455 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
456#endif
Robert Phillipsbe77a022018-04-03 17:17:05 -0400457
Brian Salomonf9b00422020-10-08 16:00:14 -0400458 dContext->flush();
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500459 }
460
Robert Phillipse8fabb22018-02-04 14:33:21 -0500461 // Test that the textureability of the DDL characterization can block a DDL draw
462 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400463 SurfaceParameters params(dContext);
Brian Salomonf9b00422020-10-08 16:00:14 -0400464 params.disableTextureability();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500465
Brian Salomonf9b00422020-10-08 16:00:14 -0400466 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipse8fabb22018-02-04 14:33:21 -0500467 if (s) {
Adlai Holler7580ad42020-06-24 13:45:25 -0400468 REPORTER_ASSERT(reporter, !s->draw(ddl)); // bc the DDL was made w/ textureability
Robert Phillipse8fabb22018-02-04 14:33:21 -0500469
Brian Salomonf9b00422020-10-08 16:00:14 -0400470 dContext->flush();
Robert Phillipse8fabb22018-02-04 14:33:21 -0500471 }
472 }
473
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500474 // Make sure non-GPU-backed surfaces fail characterization
475 {
476 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
477
478 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
479 SkSurfaceCharacterization c;
480 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
481 }
Robert Phillips94458ee2018-03-06 13:41:51 -0500482
483 // Exercise the createResized method
484 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400485 SurfaceParameters params(dContext);
Robert Phillips94458ee2018-03-06 13:41:51 -0500486
Brian Salomonf9b00422020-10-08 16:00:14 -0400487 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillips94458ee2018-03-06 13:41:51 -0500488 if (!s) {
489 return;
490 }
491
492 SkSurfaceCharacterization char0;
493 SkAssertResult(s->characterize(&char0));
494
495 // Too small
496 SkSurfaceCharacterization char1 = char0.createResized(-1, -1);
497 REPORTER_ASSERT(reporter, !char1.isValid());
498
499 // Too large
500 SkSurfaceCharacterization char2 = char0.createResized(1000000, 32);
501 REPORTER_ASSERT(reporter, !char2.isValid());
502
503 // Just right
504 SkSurfaceCharacterization char3 = char0.createResized(32, 32);
505 REPORTER_ASSERT(reporter, char3.isValid());
506 REPORTER_ASSERT(reporter, 32 == char3.width());
507 REPORTER_ASSERT(reporter, 32 == char3.height());
508 }
Robert Phillipsa975ef32019-10-03 11:09:17 -0400509
510 // Exercise the createColorSpace method
511 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400512 SurfaceParameters params(dContext);
Robert Phillipsa975ef32019-10-03 11:09:17 -0400513
Brian Salomonf9b00422020-10-08 16:00:14 -0400514 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsa975ef32019-10-03 11:09:17 -0400515 if (!s) {
516 return;
517 }
518
519 SkSurfaceCharacterization char0;
520 SkAssertResult(s->characterize(&char0));
521
522 // The default params create an sRGB color space
523 REPORTER_ASSERT(reporter, char0.colorSpace()->isSRGB());
524 REPORTER_ASSERT(reporter, !char0.colorSpace()->gammaIsLinear());
525
526 {
527 sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
528
529 SkSurfaceCharacterization char1 = char0.createColorSpace(std::move(newCS));
530 REPORTER_ASSERT(reporter, char1.isValid());
531 REPORTER_ASSERT(reporter, !char1.colorSpace()->isSRGB());
532 REPORTER_ASSERT(reporter, char1.colorSpace()->gammaIsLinear());
533 }
534
535 {
536 SkSurfaceCharacterization char2 = char0.createColorSpace(nullptr);
537 REPORTER_ASSERT(reporter, char2.isValid());
538 REPORTER_ASSERT(reporter, !char2.colorSpace());
539 }
540
541 {
542 sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear();
543
544 SkSurfaceCharacterization invalid;
545 REPORTER_ASSERT(reporter, !invalid.isValid());
546 SkSurfaceCharacterization stillInvalid = invalid.createColorSpace(std::move(newCS));
547 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
548 }
Robert Phillipsa975ef32019-10-03 11:09:17 -0400549 }
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500550
551 // Exercise the createBackendFormat method
552 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400553 SurfaceParameters params(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500554
Brian Salomonf9b00422020-10-08 16:00:14 -0400555 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500556 if (!s) {
557 return;
558 }
559
560 SkSurfaceCharacterization char0;
561 SkAssertResult(s->characterize(&char0));
562
563 // The default params create a renderable RGBA8 surface
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400564 auto originalBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
565 GrRenderable::kYes);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500566 REPORTER_ASSERT(reporter, originalBackendFormat.isValid());
567 REPORTER_ASSERT(reporter, char0.backendFormat() == originalBackendFormat);
568
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400569 auto newBackendFormat = dContext->defaultBackendFormat(kRGB_565_SkColorType,
570 GrRenderable::kYes);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500571
572 if (newBackendFormat.isValid()) {
573 SkSurfaceCharacterization char1 = char0.createBackendFormat(kRGB_565_SkColorType,
574 newBackendFormat);
575 REPORTER_ASSERT(reporter, char1.isValid());
576 REPORTER_ASSERT(reporter, char1.backendFormat() == newBackendFormat);
577
578 SkSurfaceCharacterization invalid;
579 REPORTER_ASSERT(reporter, !invalid.isValid());
580 auto stillInvalid = invalid.createBackendFormat(kRGB_565_SkColorType,
581 newBackendFormat);
582 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
583 }
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500584 }
585
586 // Exercise the createFBO0 method
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400587 if (dContext->backend() == GrBackendApi::kOpenGL) {
588 SurfaceParameters params(dContext);
Greg Daniel638b2e82020-08-27 14:29:00 -0400589 // If the original characterization is textureable then we will fail trying to make an
590 // FBO0 characterization
Brian Salomonf9b00422020-10-08 16:00:14 -0400591 params.disableTextureability();
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500592
Brian Salomonf9b00422020-10-08 16:00:14 -0400593 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500594 if (!s) {
595 return;
596 }
597
598 SkSurfaceCharacterization char0;
599 SkAssertResult(s->characterize(&char0));
600
601 // The default params create a non-FBO0 surface
602 REPORTER_ASSERT(reporter, !char0.usesGLFBO0());
603
604 {
605 SkSurfaceCharacterization char1 = char0.createFBO0(true);
606 REPORTER_ASSERT(reporter, char1.isValid());
607 REPORTER_ASSERT(reporter, char1.usesGLFBO0());
608 }
609
610 {
611 SkSurfaceCharacterization invalid;
612 REPORTER_ASSERT(reporter, !invalid.isValid());
613 SkSurfaceCharacterization stillInvalid = invalid.createFBO0(true);
614 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
615 }
Robert Phillipsb3c061a2020-02-13 13:24:47 -0500616 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500617}
618
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500619#ifdef SK_GL
620
621// Test out the surface compatibility checks regarding FBO0-ness. This test constructs
622// two parallel arrays of characterizations and surfaces in the order:
623// FBO0 w/ MSAA, FBO0 w/o MSAA, not-FBO0 w/ MSAA, not-FBO0 w/o MSAA
624// and then tries all sixteen combinations to check the expected compatibility.
625// Note: this is a GL-only test
626DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(CharacterizationFBO0nessTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400627 auto context = ctxInfo.directContext();
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500628 const GrCaps* caps = context->priv().caps();
629 sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy();
630 const size_t resourceCacheLimit = context->getResourceCacheLimit();
631
632 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D);
633
634 int availableSamples = caps->getRenderTargetSampleCount(4, format);
635 if (availableSamples <= 1) {
636 // This context doesn't support MSAA for RGBA8
637 return;
638 }
639
640 SkImageInfo ii = SkImageInfo::Make({ 128, 128 }, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
641
642 static constexpr int kStencilBits = 8;
643 static constexpr bool kNotMipMapped = false;
644 static constexpr bool kNotTextureable = false;
645 const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
646
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500647 // Rows are characterizations and columns are surfaces
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500648 static const bool kExpectedCompatibility[4][4] = {
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500649 // FBO0 & MSAA, FBO0 & not-MSAA, not-FBO0 & MSAA, not-FBO0 & not-MSAA
650/* FBO0 & MSAA */ { true, false, false, false },
651/* FBO0 & not-MSAA */ { false, true, false, true },
652/* not-FBO0 & MSAA */ { false, false, true, false },
653/* not-FBO0 & not- */ { false, false, false, true }
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500654 };
655
656 SkSurfaceCharacterization characterizations[4];
657 sk_sp<SkSurface> surfaces[4];
658
659 int index = 0;
660 for (bool isFBO0 : { true, false }) {
661 for (int numSamples : { availableSamples, 1 }) {
662 characterizations[index] = proxy->createCharacterization(resourceCacheLimit,
663 ii, format, numSamples,
664 kTopLeft_GrSurfaceOrigin,
665 surfaceProps, kNotMipMapped,
666 isFBO0, kNotTextureable);
667 SkASSERT(characterizations[index].sampleCount() == numSamples);
668 SkASSERT(characterizations[index].usesGLFBO0() == isFBO0);
669
670 GrGLFramebufferInfo fboInfo{ isFBO0 ? 0 : (GrGLuint) 1, GR_GL_RGBA8 };
671 GrBackendRenderTarget backendRT(128, 128, numSamples, kStencilBits, fboInfo);
672 SkAssertResult(backendRT.isValid());
673
674 surfaces[index] = SkSurface::MakeFromBackendRenderTarget(context, backendRT,
675 kTopLeft_GrSurfaceOrigin,
676 kRGBA_8888_SkColorType,
677 nullptr, &surfaceProps);
678 ++index;
679 }
680 }
681
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500682 for (int c = 0; c < 4; ++c) {
683 for (int s = 0; s < 4; ++s) {
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500684 REPORTER_ASSERT(reporter,
Robert Phillips1b1bd4e2020-03-05 13:21:12 -0500685 kExpectedCompatibility[c][s] ==
686 surfaces[s]->isCompatible(characterizations[c]));
Robert Phillips2dbcbe82020-03-05 11:16:39 -0500687 }
688 }
689}
690#endif
691
Greg Daniel007d97d2020-11-04 10:50:39 -0500692#ifdef SK_VULKAN
693DEF_GPUTEST_FOR_VULKAN_CONTEXT(CharacterizationVkSCBnessTest, reporter, ctxInfo) {
694 auto dContext = ctxInfo.directContext();
695
696 SurfaceParameters params(dContext);
697 params.modify(SurfaceParameters::kVkSCBCount);
698 SkSurfaceCharacterization characterization = params.createCharacterization(dContext);
699 REPORTER_ASSERT(reporter, characterization.isValid());
700
701 sk_sp<SkDeferredDisplayList> ddl = params.createDDL(dContext);
702 REPORTER_ASSERT(reporter, ddl.get());
703
704 sk_sp<GrVkSecondaryCBDrawContext> scbDrawContext = params.makeVkSCB(dContext);
705 REPORTER_ASSERT(reporter, scbDrawContext->isCompatible(characterization));
706
707 scbDrawContext->releaseResources();
708}
709#endif
710
Robert Phillips3cd54322019-07-10 09:28:59 -0400711DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400712 auto context = ctxInfo.directContext();
Robert Phillips3cd54322019-07-10 09:28:59 -0400713
714 DDLSurfaceCharacterizationTestImpl(context, reporter);
715}
716
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500717// Test that a DDL created w/o textureability can be replayed into both a textureable and
718// non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a
719// textureable DDL cannot be played into a non-textureable destination but can be replayed
720// into a textureable destination.
721DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400722 auto context = ctxInfo.directContext();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500723
724 // Create a bitmap that we can readback into
725 SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType,
726 kPremul_SkAlphaType);
727 SkBitmap bitmap;
728 bitmap.allocPixels(imageInfo);
729
730 for (bool textureability : { true, false }) {
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400731 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500732
Robert Phillipsc046ff02019-07-01 10:34:03 -0400733 // First, create a DDL w/o textureability (and thus no mipmaps). TODO: once we have
734 // reusable DDLs, move this outside of the loop.
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500735 {
Robert Phillips3cd54322019-07-10 09:28:59 -0400736 SurfaceParameters params(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400737 params.disableTextureability();
Greg Daniel638b2e82020-08-27 14:29:00 -0400738 if (context->backend() == GrBackendApi::kVulkan) {
739 params.setVkRTInputAttachmentSupport(true);
740 }
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500741
742 ddl = params.createDDL(context);
743 SkAssertResult(ddl);
744 }
745
746 // Then verify it can draw into either flavor of destination
Robert Phillips3cd54322019-07-10 09:28:59 -0400747 SurfaceParameters params(context);
Brian Salomonf9b00422020-10-08 16:00:14 -0400748 if (!textureability) {
749 params.disableTextureability();
750 }
Greg Daniel638b2e82020-08-27 14:29:00 -0400751 if (context->backend() == GrBackendApi::kVulkan) {
752 params.setVkRTInputAttachmentSupport(true);
753 }
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500754
Brian Salomonf9b00422020-10-08 16:00:14 -0400755 sk_sp<SkSurface> s = params.make(context);
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500756 if (!s) {
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500757 continue;
758 }
759
Adlai Holler7580ad42020-06-24 13:45:25 -0400760 REPORTER_ASSERT(reporter, s->draw(ddl));
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500761 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
Brian Salomonf9b00422020-10-08 16:00:14 -0400762
763 context->flush();
Robert Phillipsb45f47d2019-02-03 17:17:54 -0500764 }
765
766}
767
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400768static void test_make_render_target(skiatest::Reporter* reporter,
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400769 GrDirectContext* dContext,
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400770 const SurfaceParameters& params) {
771 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400772 const SkSurfaceCharacterization c = params.createCharacterization(dContext);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400773
Robert Phillipsbe77a022018-04-03 17:17:05 -0400774 if (!c.isValid()) {
Brian Salomonf9b00422020-10-08 16:00:14 -0400775 sk_sp<SkSurface> tmp = params.make(dContext);
Robert Phillipsbe77a022018-04-03 17:17:05 -0400776 // If we couldn't characterize the surface we shouldn't be able to create it either
777 REPORTER_ASSERT(reporter, !tmp);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400778 return;
779 }
780 }
781
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400782 const SkSurfaceCharacterization c = params.createCharacterization(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400783 {
Brian Salomonf9b00422020-10-08 16:00:14 -0400784 sk_sp<SkSurface> s = params.make(dContext);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400785 REPORTER_ASSERT(reporter, s);
786 if (!s) {
787 REPORTER_ASSERT(reporter, !c.isValid());
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400788 return;
789 }
790
791 REPORTER_ASSERT(reporter, c.isValid());
Brian Salomonf9b00422020-10-08 16:00:14 -0400792 GrBackendTexture backend = s->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
793 if (backend.isValid()) {
794 REPORTER_ASSERT(reporter, c.isCompatible(backend));
795 }
Robert Phillips9907e6e2019-06-25 14:47:04 -0400796 REPORTER_ASSERT(reporter, s->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400797 // Note that we're leaving 'backend' live here
798 }
799
800 // Make an SkSurface from scratch
801 {
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400802 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(dContext, c, SkBudgeted::kYes);
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400803 REPORTER_ASSERT(reporter, s);
Robert Phillips9907e6e2019-06-25 14:47:04 -0400804 REPORTER_ASSERT(reporter, s->isCompatible(c));
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400805 }
Robert Phillipsd8f79a22019-06-24 13:25:42 -0400806}
807
808////////////////////////////////////////////////////////////////////////////////
809// This tests the SkSurface::MakeRenderTarget variants that take an SkSurfaceCharacterization.
810// In particular, the SkSurface, backendTexture and SkSurfaceCharacterization
811// should always be compatible.
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400812void DDLMakeRenderTargetTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) {
Brian Salomonf9b00422020-10-08 16:00:14 -0400813 for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
Greg Daniel007d97d2020-11-04 10:50:39 -0500814 if (i == SurfaceParameters::kFBO0Count || i == SurfaceParameters::kVkSCBCount) {
815 // MakeRenderTarget doesn't support FBO0 or vulkan secondary command buffers
Robert Phillipsbe77a022018-04-03 17:17:05 -0400816 continue;
817 }
818
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400819 SurfaceParameters params(dContext);
Brian Salomonf9b00422020-10-08 16:00:14 -0400820 if (i >= 0 && !params.modify(i)) {
821 continue;
Brian Salomon4687bdd2019-05-09 16:28:04 -0400822 }
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400823
Robert Phillipsc8ae4942020-07-20 10:56:01 -0400824 test_make_render_target(reporter, dContext, params);
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400825 }
826}
827
Robert Phillips3cd54322019-07-10 09:28:59 -0400828DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -0400829 auto context = ctxInfo.directContext();
Robert Phillips3cd54322019-07-10 09:28:59 -0400830
831 DDLMakeRenderTargetTestImpl(context, reporter);
832}
833
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400834////////////////////////////////////////////////////////////////////////////////
Greg Danielf2336e42018-01-23 16:38:14 -0500835static constexpr int kSize = 8;
836
837struct TextureReleaseChecker {
838 TextureReleaseChecker() : fReleaseCount(0) {}
839 int fReleaseCount;
840 static void Release(void* self) {
841 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
842 }
843};
844
845enum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL };
846
847// This tests the ability to create and use wrapped textures in a DDL world
848DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
Adlai Holler14dc7912020-08-11 15:48:49 +0000849 auto dContext = ctxInfo.directContext();
Robert Phillips9b16f812019-05-17 10:01:21 -0400850
Brian Salomon72050802020-10-12 20:45:06 -0400851 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(dContext,
852 kSize,
853 kSize,
854 kRGBA_8888_SkColorType,
855 GrMipmapped::kNo,
856 GrRenderable::kNo,
857 GrProtected::kNo);
858 if (!mbet) {
Brian Salomonf7778972018-03-08 10:13:17 -0500859 return;
Greg Danielf2336e42018-01-23 16:38:14 -0500860 }
Brian Salomonf7778972018-03-08 10:13:17 -0500861
Adlai Holler14dc7912020-08-11 15:48:49 +0000862 SurfaceParameters params(dContext);
Brian Salomonf7778972018-03-08 10:13:17 -0500863
Brian Salomonf9b00422020-10-08 16:00:14 -0400864 sk_sp<SkSurface> s = params.make(dContext);
Brian Salomonf7778972018-03-08 10:13:17 -0500865 if (!s) {
Brian Salomonf7778972018-03-08 10:13:17 -0500866 return;
867 }
868
869 SkSurfaceCharacterization c;
870 SkAssertResult(s->characterize(&c));
871
Adlai Holler14dc7912020-08-11 15:48:49 +0000872 SkDeferredDisplayListRecorder recorder(c);
Brian Salomonf7778972018-03-08 10:13:17 -0500873
Adlai Holler14dc7912020-08-11 15:48:49 +0000874 SkCanvas* canvas = recorder.getCanvas();
875 SkASSERT(canvas);
Adlai Holler74b83a42020-08-06 17:24:53 +0000876
Adlai Holler14dc7912020-08-11 15:48:49 +0000877 auto rContext = canvas->recordingContext();
878 if (!rContext) {
Brian Salomonf7778972018-03-08 10:13:17 -0500879 return;
880 }
881
882 // Wrapped Backend Textures are not supported in DDL
Brian Salomonf7778972018-03-08 10:13:17 -0500883 TextureReleaseChecker releaseChecker;
Brian Salomon72050802020-10-12 20:45:06 -0400884 sk_sp<SkImage> image = SkImage::MakeFromTexture(
885 rContext,
886 mbet->texture(),
887 kTopLeft_GrSurfaceOrigin,
888 kRGBA_8888_SkColorType,
889 kPremul_SkAlphaType,
890 nullptr,
891 sk_gpu_test::ManagedBackendTexture::ReleaseProc,
892 mbet->releaseContext(TextureReleaseChecker::Release, &releaseChecker));
Brian Salomonf7778972018-03-08 10:13:17 -0500893 REPORTER_ASSERT(reporter, !image);
Greg Danielf2336e42018-01-23 16:38:14 -0500894}
895
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400896////////////////////////////////////////////////////////////////////////////////
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400897// Test out the behavior of an invalid DDLRecorder
898DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) {
Robert Phillipsdc369702020-08-13 13:34:27 -0400899 auto dContext = ctxInfo.directContext();
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400900
901 {
902 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
Robert Phillipsdc369702020-08-13 13:34:27 -0400903 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, ii);
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400904
905 SkSurfaceCharacterization characterization;
906 SkAssertResult(s->characterize(&characterization));
907
908 // never calling getCanvas means the backing surface is never allocated
909 SkDeferredDisplayListRecorder recorder(characterization);
910 }
911
912 {
913 SkSurfaceCharacterization invalid;
914
915 SkDeferredDisplayListRecorder recorder(invalid);
916
917 const SkSurfaceCharacterization c = recorder.characterization();
918 REPORTER_ASSERT(reporter, !c.isValid());
919 REPORTER_ASSERT(reporter, !recorder.getCanvas());
920 REPORTER_ASSERT(reporter, !recorder.detach());
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400921 }
Robert Phillipsdc369702020-08-13 13:34:27 -0400922}
Robert Phillips6ceaafa2018-03-15 16:53:06 -0400923
Robert Phillipsdc369702020-08-13 13:34:27 -0400924DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLCreateCharacterizationFailures, reporter, ctxInfo) {
925 auto dContext = ctxInfo.directContext();
926 size_t maxResourceBytes = dContext->getResourceCacheLimit();
927 auto proxy = dContext->threadSafeProxy().get();
928
Greg Daniel638b2e82020-08-27 14:29:00 -0400929 auto check_create_fails =
930 [proxy, reporter, maxResourceBytes](const GrBackendFormat& backendFormat,
931 int width, int height,
932 SkColorType ct, bool willUseGLFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500933 bool isTextureable,
Greg Daniel638b2e82020-08-27 14:29:00 -0400934 GrProtected prot,
Greg Daniel007d97d2020-11-04 10:50:39 -0500935 bool vkRTSupportsInputAttachment,
936 bool forVulkanSecondaryCommandBuffer) {
Robert Phillipsdc369702020-08-13 13:34:27 -0400937 const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
938
939 SkImageInfo ii = SkImageInfo::Make(width, height, ct,
940 kPremul_SkAlphaType, nullptr);
941
942 SkSurfaceCharacterization c = proxy->createCharacterization(
943 maxResourceBytes, ii, backendFormat, 1,
944 kBottomLeft_GrSurfaceOrigin, surfaceProps, false,
Greg Daniel007d97d2020-11-04 10:50:39 -0500945 willUseGLFBO0, isTextureable, prot,
946 vkRTSupportsInputAttachment,
947 forVulkanSecondaryCommandBuffer);
Robert Phillipsdc369702020-08-13 13:34:27 -0400948 REPORTER_ASSERT(reporter, !c.isValid());
949 };
950
951 GrBackendFormat goodBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
952 GrRenderable::kYes);
953 SkASSERT(goodBackendFormat.isValid());
954
955 GrBackendFormat badBackendFormat;
956 SkASSERT(!badBackendFormat.isValid());
957
958 SkColorType kGoodCT = kRGBA_8888_SkColorType;
959 SkColorType kBadCT = kUnknown_SkColorType;
960
Greg Daniel007d97d2020-11-04 10:50:39 -0500961 static const bool kIsTextureable = true;
962 static const bool kIsNotTextureable = false;
963
Robert Phillipsdc369702020-08-13 13:34:27 -0400964 static const bool kGoodUseFBO0 = false;
965 static const bool kBadUseFBO0 = true;
966
Greg Daniel638b2e82020-08-27 14:29:00 -0400967 static const bool kGoodVkInputAttachment = false;
968 static const bool kBadVkInputAttachment = true;
969
Greg Daniel007d97d2020-11-04 10:50:39 -0500970 static const bool kGoodForVkSCB = false;
971 static const bool kBadForVkSCB = true;
972
Robert Phillipsdc369702020-08-13 13:34:27 -0400973 int goodWidth = 64;
974 int goodHeight = 64;
975 int badWidths[] = { 0, 1048576 };
976 int badHeights[] = { 0, 1048576 };
977
Greg Daniel638b2e82020-08-27 14:29:00 -0400978
979 // In each of the check_create_fails calls there is one bad parameter that should cause the
980 // creation of the characterization to fail.
981 check_create_fails(goodBackendFormat, goodWidth, badHeights[0], 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, goodWidth, badHeights[1], 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[0], 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(goodBackendFormat, badWidths[1], 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(badBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500990 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400991 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kBadCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500992 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Greg Daniel638b2e82020-08-27 14:29:00 -0400993 // This fails because we always try to make a characterization that is textureable and we can't
994 // have UseFBO0 be true and textureable.
995 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -0500996 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB);
Robert Phillipsdc369702020-08-13 13:34:27 -0400997 if (dContext->backend() == GrBackendApi::kVulkan) {
Greg Daniel638b2e82020-08-27 14:29:00 -0400998 // The bad parameter in this case is the GrProtected::kYes since none of our test contexts
999 // are made protected we can't have a protected surface.
1000 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -05001001 kIsTextureable, GrProtected::kYes, kGoodVkInputAttachment,
1002 kGoodForVkSCB);
1003 // The following fails because forVulkanSecondaryCommandBuffer is true and
1004 // isTextureable is true. This is not a legal combination.
Greg Daniel638b2e82020-08-27 14:29:00 -04001005 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
Greg Daniel007d97d2020-11-04 10:50:39 -05001006 kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kBadForVkSCB);
1007 // The following fails because forVulkanSecondaryCommandBuffer is true and
1008 // vkRTSupportsInputAttachment is true. This is not a legal combination.
1009 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1010 kIsNotTextureable, GrProtected::kNo, kBadVkInputAttachment,
1011 kBadForVkSCB);
1012 // The following fails because forVulkanSecondaryCommandBuffer is true and
1013 // willUseGLFBO0 is true. This is not a legal combination.
1014 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
1015 kIsNotTextureable, GrProtected::kNo, kGoodVkInputAttachment,
1016 kBadForVkSCB);
1017 } else {
1018 // The following set vulkan only flags on non vulkan backends.
1019 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1020 kIsTextureable, GrProtected::kNo, kBadVkInputAttachment, kGoodForVkSCB);
1021 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1022 kIsNotTextureable, GrProtected::kNo, kGoodVkInputAttachment,
1023 kBadForVkSCB);
Robert Phillipsdc369702020-08-13 13:34:27 -04001024 }
Robert Phillips6ceaafa2018-03-15 16:53:06 -04001025}
1026
Robert Phillips6b6fcc72018-03-30 13:57:00 -04001027////////////////////////////////////////////////////////////////////////////////
Robert Phillipsee5fd132019-05-07 13:29:22 -04001028// Test that flushing a DDL via SkSurface::flush works
1029
1030struct FulfillInfo {
1031 sk_sp<SkPromiseImageTexture> fTex;
1032 bool fFulfilled = false;
1033 bool fReleased = false;
Robert Phillipsee5fd132019-05-07 13:29:22 -04001034};
1035
1036static sk_sp<SkPromiseImageTexture> tracking_fulfill_proc(void* context) {
1037 FulfillInfo* info = (FulfillInfo*) context;
1038 info->fFulfilled = true;
1039 return info->fTex;
1040}
1041
1042static void tracking_release_proc(void* context) {
1043 FulfillInfo* info = (FulfillInfo*) context;
1044 info->fReleased = true;
1045}
1046
Robert Phillipsee5fd132019-05-07 13:29:22 -04001047DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSkSurfaceFlush, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001048 auto context = ctxInfo.directContext();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001049
1050 SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1051 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1052
1053 SkSurfaceCharacterization characterization;
1054 SkAssertResult(s->characterize(&characterization));
1055
Brian Salomon72050802020-10-12 20:45:06 -04001056 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeFromInfo(context, ii);
1057 if (!mbet) {
1058 ERRORF(reporter, "Could not make texture.");
Robert Phillipsee5fd132019-05-07 13:29:22 -04001059 return;
1060 }
1061
1062 FulfillInfo fulfillInfo;
Brian Salomon72050802020-10-12 20:45:06 -04001063 fulfillInfo.fTex = SkPromiseImageTexture::Make(mbet->texture());
Robert Phillipsee5fd132019-05-07 13:29:22 -04001064
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001065 sk_sp<SkDeferredDisplayList> ddl;
Robert Phillipsee5fd132019-05-07 13:29:22 -04001066
1067 {
1068 SkDeferredDisplayListRecorder recorder(characterization);
1069
Robert Phillips0a15cc62019-07-30 12:49:10 -04001070 GrBackendFormat format = context->defaultBackendFormat(kRGBA_8888_SkColorType,
1071 GrRenderable::kNo);
1072 SkASSERT(format.isValid());
Robert Phillipsee5fd132019-05-07 13:29:22 -04001073
Robert Phillipsee5fd132019-05-07 13:29:22 -04001074 SkCanvas* canvas = recorder.getCanvas();
1075
Adlai Holler07e11d42021-02-25 10:26:05 -05001076 sk_sp<SkImage> promiseImage = SkImage::MakePromiseTexture(
1077 canvas->recordingContext()->threadSafeProxy(),
1078 format,
1079 SkISize::Make(32, 32),
1080 GrMipmapped::kNo,
1081 kTopLeft_GrSurfaceOrigin,
1082 kRGBA_8888_SkColorType,
1083 kPremul_SkAlphaType,
1084 nullptr,
1085 tracking_fulfill_proc,
1086 tracking_release_proc,
1087 &fulfillInfo);
1088
Robert Phillipsee5fd132019-05-07 13:29:22 -04001089 canvas->clear(SK_ColorRED);
1090 canvas->drawImage(promiseImage, 0, 0);
1091 ddl = recorder.detach();
1092 }
1093
Greg Daniel0a2464f2020-05-14 15:45:44 -04001094 context->flushAndSubmit();
Robert Phillips15c91422019-05-07 16:54:48 -04001095
Adlai Holler7580ad42020-06-24 13:45:25 -04001096 s->draw(ddl);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001097
1098 GrFlushInfo flushInfo;
Robert Phillips8e49a692019-05-07 15:57:25 -04001099 s->flush(SkSurface::BackendSurfaceAccess::kPresent, flushInfo);
Greg Daniel0a2464f2020-05-14 15:45:44 -04001100 context->submit();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001101
1102 REPORTER_ASSERT(reporter, fulfillInfo.fFulfilled);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001103
Robert Phillips8e49a692019-05-07 15:57:25 -04001104 if (GrBackendApi::kVulkan == context->backend() ||
1105 GrBackendApi::kMetal == context->backend()) {
Robert Phillips15c91422019-05-07 16:54:48 -04001106 // In order to receive the done callback with Vulkan we need to perform the equivalent
Robert Phillipsee5fd132019-05-07 13:29:22 -04001107 // of a glFinish
Greg Danielce9f0162020-06-30 13:42:46 -04001108 s->flush();
Greg Daniel0a2464f2020-05-14 15:45:44 -04001109 context->submit(true);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001110 }
1111
Brian Salomonf1432742020-11-09 15:40:27 -05001112 REPORTER_ASSERT(reporter, fulfillInfo.fReleased);
Robert Phillipsee5fd132019-05-07 13:29:22 -04001113
1114 REPORTER_ASSERT(reporter, fulfillInfo.fTex->unique());
1115 fulfillInfo.fTex.reset();
Robert Phillipsee5fd132019-05-07 13:29:22 -04001116}
1117
1118////////////////////////////////////////////////////////////////////////////////
Robert Phillipsf54883c2018-12-18 08:29:09 -05001119// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
1120DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001121 auto context = ctxInfo.directContext();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001122
1123 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1124 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1125
1126 SkBitmap bitmap;
1127 bitmap.allocPixels(ii);
1128
1129 SkSurfaceCharacterization characterization;
1130 SkAssertResult(s->characterize(&characterization));
1131
1132 SkDeferredDisplayListRecorder recorder(characterization);
1133
1134 SkCanvas* canvas1 = recorder.getCanvas();
1135
1136 canvas1->clear(SK_ColorRED);
1137
1138 canvas1->save();
1139 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
1140
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001141 sk_sp<SkDeferredDisplayList> ddl1 = recorder.detach();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001142
1143 SkCanvas* canvas2 = recorder.getCanvas();
1144
1145 SkPaint p;
1146 p.setColor(SK_ColorGREEN);
1147 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
1148
Adlai Hollerf19bbb52020-06-29 10:00:08 -04001149 sk_sp<SkDeferredDisplayList> ddl2 = recorder.detach();
Robert Phillipsf54883c2018-12-18 08:29:09 -05001150
1151 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
1152 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
1153
1154 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
1155 // lazy proxy are all different between the two DDLs
1156 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
1157
Adlai Holler7580ad42020-06-24 13:45:25 -04001158 s->draw(ddl1);
1159 s->draw(ddl2);
Robert Phillipsf54883c2018-12-18 08:29:09 -05001160
1161 // Make sure the clipRect from DDL1 didn't percolate into DDL2
1162 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
1163 for (int y = 0; y < 32; ++y) {
1164 for (int x = 0; x < 32; ++x) {
1165 REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN);
1166 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
1167 return; // we only really need to report the error once
1168 }
1169 }
1170 }
1171}
1172
John Rosascoa9b348f2019-11-08 13:18:15 -08001173#ifdef SK_GL
Adlai Holler07e11d42021-02-25 10:26:05 -05001174
1175static sk_sp<SkPromiseImageTexture> dummy_fulfill_proc(void*) {
1176 SkASSERT(0);
1177 return nullptr;
1178}
1179
Robert Phillipsf54883c2018-12-18 08:29:09 -05001180////////////////////////////////////////////////////////////////////////////////
Robert Phillipsabf7b762018-03-21 12:13:37 -04001181// Check that the texture-specific flags (i.e., for external & rectangle textures) work
1182// for promise images. As such, this is a GL-only test.
1183DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001184 auto context = ctxInfo.directContext();
Robert Phillipsabf7b762018-03-21 12:13:37 -04001185
1186 SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32);
1187 sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii);
1188
1189 SkSurfaceCharacterization characterization;
1190 SkAssertResult(s->characterize(&characterization));
1191
1192 SkDeferredDisplayListRecorder recorder(characterization);
1193
1194 for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) {
Brian Salomon7e67dca2020-07-21 09:27:25 -04001195 for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
Greg Daniel09c94002018-06-08 22:11:51 +00001196 GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001197
Adlai Holler07e11d42021-02-25 10:26:05 -05001198 sk_sp<SkImage> image = SkImage::MakePromiseTexture(
1199 recorder.getCanvas()->recordingContext()->threadSafeProxy(),
Brian Salomonf1432742020-11-09 15:40:27 -05001200 format,
Adlai Holler07e11d42021-02-25 10:26:05 -05001201 SkISize::Make(32, 32),
Brian Salomonf1432742020-11-09 15:40:27 -05001202 mipMapped,
Brian Salomonf55e8d52019-01-30 17:28:20 -05001203 kTopLeft_GrSurfaceOrigin,
1204 kRGBA_8888_SkColorType,
Brian Salomonf1432742020-11-09 15:40:27 -05001205 kPremul_SkAlphaType,
Adlai Holler07e11d42021-02-25 10:26:05 -05001206 /*color space*/nullptr,
Brian Salomonf1432742020-11-09 15:40:27 -05001207 dummy_fulfill_proc,
1208 /*release proc*/ nullptr,
Adlai Holler07e11d42021-02-25 10:26:05 -05001209 /*context*/nullptr);
Brian Salomon7e67dca2020-07-21 09:27:25 -04001210 if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipmapped::kYes) {
Greg Daniel09c94002018-06-08 22:11:51 +00001211 REPORTER_ASSERT(reporter, !image);
1212 continue;
1213 }
1214 REPORTER_ASSERT(reporter, image);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001215
Brian Salomone6662542021-02-23 10:45:39 -05001216 GrTextureProxy* backingProxy = sk_gpu_test::GetTextureImageProxy(image.get(), context);
Robert Phillipsabf7b762018-03-21 12:13:37 -04001217
Brian Salomon8c82a872020-07-21 12:09:58 -04001218 REPORTER_ASSERT(reporter, backingProxy->mipmapped() == mipMapped);
Greg Daniel09c94002018-06-08 22:11:51 +00001219 if (GR_GL_TEXTURE_2D == target) {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001220 REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001221 } else {
Brian Salomonfd98c2c2018-07-31 17:25:29 -04001222 REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling());
Greg Daniel09c94002018-06-08 22:11:51 +00001223 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001224 }
1225 }
Robert Phillipsbe77a022018-04-03 17:17:05 -04001226}
John Rosascoa9b348f2019-11-08 13:18:15 -08001227#endif // SK_GL
Robert Phillipsbe77a022018-04-03 17:17:05 -04001228
1229////////////////////////////////////////////////////////////////////////////////
Robert Phillips646f6372018-09-25 09:31:10 -04001230// Test colorType and pixelConfig compatibility.
Robert Phillipsbe77a022018-04-03 17:17:05 -04001231DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) {
Robert Phillips6d344c32020-07-06 10:56:46 -04001232 auto context = ctxInfo.directContext();
Robert Phillipsbe77a022018-04-03 17:17:05 -04001233
1234 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
1235 SkColorType colorType = static_cast<SkColorType>(ct);
1236
Robert Phillips3cd54322019-07-10 09:28:59 -04001237 SurfaceParameters params(context);
Greg Daniel60ea40c2019-02-12 13:38:44 -05001238 params.setColorType(colorType);
1239 params.setColorSpace(nullptr);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001240
Robert Phillipsd8f79a22019-06-24 13:25:42 -04001241 test_make_render_target(reporter, context, params);
Robert Phillipsbe77a022018-04-03 17:17:05 -04001242 }
Robert Phillipsabf7b762018-03-21 12:13:37 -04001243
1244}