Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
DeferredDisplayListTest.cpp
Go to the documentation of this file.
1/*
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
16#include "include/core/SkRect.h"
18#include "include/core/SkSize.h"
27#include "include/gpu/GrTypes.h"
41#include "tests/Test.h"
45
46#include <cstddef>
47#include <initializer_list>
48#include <memory>
49#include <utility>
50
51class SkImage;
52struct GrContextOptions;
53
54#ifdef SK_GL
58#endif
59
60#ifdef SK_VULKAN
66#include <vulkan/vulkan_core.h>
67#endif
68
69static bool is_compatible(const GrSurfaceCharacterization& gsc, const GrBackendTexture& backendTex) {
70 if (!gsc.isValid() || !backendTex.isValid()) {
71 return false;
72 }
73
74 if (gsc.backendFormat() != backendTex.getBackendFormat()) {
75 return false;
76 }
77
78 if (gsc.usesGLFBO0()) {
79 // It is a backend texture so can't be wrapping FBO0
80 return false;
81 }
82
83 if (gsc.vulkanSecondaryCBCompatible()) {
84 return false;
85 }
86
87 if (gsc.vkRTSupportsInputAttachment()) {
88 if (backendTex.backend() != GrBackendApi::kVulkan) {
89 return false;
90 }
91#ifdef SK_VULKAN
92 GrVkImageInfo vkInfo;
93 if (!GrBackendTextures::GetVkImageInfo(backendTex, &vkInfo)) {
94 return false;
95 }
97 return false;
98 }
99#endif // SK_VULKAN
100 }
101
102 if (gsc.isMipMapped() && !backendTex.hasMipmaps()) {
103 // backend texture is allowed to have mipmaps even if the characterization doesn't require
104 // them.
105 return false;
106 }
107
108 if (gsc.width() != backendTex.width() || gsc.height() != backendTex.height()) {
109 return false;
110 }
111
112 if (gsc.isProtected() != skgpu::Protected(backendTex.isProtected())) {
113 return false;
114 }
115
116 return true;
117}
118
120public:
121 static const int kNumParams = 13;
122 static const int kFBO0Count = 9;
123 static const int kVkSCBCount = 12;
124
126 : fBackend(rContext->backend())
127 , fCanBeProtected(false)
128 , fWidth(64)
129 , fHeight(64)
130 , fOrigin(kTopLeft_GrSurfaceOrigin)
131 , fColorType(kRGBA_8888_SkColorType)
132 , fColorSpace(SkColorSpace::MakeSRGB())
133 , fSampleCount(1)
134 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry)
135 , fShouldCreateMipMaps(skgpu::Mipmapped::kYes)
136 , fUsesGLFBO0(false)
137 , fIsTextureable(true)
138 , fIsProtected(skgpu::Protected::kNo)
139 , fVkRTSupportsInputAttachment(false)
140 , fForVulkanSecondaryCommandBuffer(false) {
141#ifdef SK_VULKAN
142 if (rContext->backend() == GrBackendApi::kVulkan) {
143 auto vkCaps = static_cast<const GrVkCaps*>(rContext->priv().caps());
144 fCanBeProtected = vkCaps->supportsProtectedContent();
145 if (fCanBeProtected) {
146 fIsProtected = skgpu::Protected::kYes;
147 }
148 }
149#endif
150 if (!rContext->priv().caps()->mipmapSupport()) {
151 fShouldCreateMipMaps = skgpu::Mipmapped::kNo;
152 }
153 }
154
155 int sampleCount() const { return fSampleCount; }
156
157 void setColorType(SkColorType ct) { fColorType = ct; }
158 SkColorType colorType() const { return fColorType; }
159 void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); }
161 fIsTextureable = false;
162 fShouldCreateMipMaps = skgpu::Mipmapped::kNo;
163 }
164 void setShouldCreateMipMaps(skgpu::Mipmapped shouldCreateMipMaps) {
165 fShouldCreateMipMaps = shouldCreateMipMaps;
166 }
167 void setVkRTInputAttachmentSupport(bool inputSupport) {
168 fVkRTSupportsInputAttachment = inputSupport;
169 }
171 fForVulkanSecondaryCommandBuffer = forVkSCB;
172 }
173
174 // Modify the SurfaceParameters in just one way. Returns false if the requested modification had
175 // no effect.
176 bool modify(int i) {
177 bool changed = false;
178 auto set = [&changed](auto& var, auto value) {
179 if (var != value) {
180 changed = true;
181 }
182 var = value;
183 };
184 switch (i) {
185 case 0:
186 set(fWidth, 63);
187 break;
188 case 1:
189 set(fHeight, 63);
190 break;
191 case 2:
192 set(fOrigin, kBottomLeft_GrSurfaceOrigin);
193 break;
194 case 3:
195 set(fColorType, kRGBA_F16_SkColorType);
196 break;
197 case 4:
198 // This just needs to be a colorSpace different from that returned by MakeSRGB().
199 // In this case we just change the gamut.
202 break;
203 case 5:
204 set(fSampleCount, 4);
205 break;
206 case 6:
207 set(fSurfaceProps, SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry));
208 break;
209 case 7:
212 break;
213 case 8:
214 set(fShouldCreateMipMaps, skgpu::Mipmapped::kNo);
215 break;
216 case 9:
217 if (GrBackendApi::kOpenGL == fBackend) {
218 set(fUsesGLFBO0, true);
219 set(fShouldCreateMipMaps,
220 skgpu::Mipmapped::kNo); // needs to changed in tandem w/ textureability
221 set(fIsTextureable, false);
222 }
223 break;
224 case 10:
225 set(fShouldCreateMipMaps,
226 skgpu::Mipmapped::kNo); // needs to changed in tandem w/ textureability
227 set(fIsTextureable, false);
228 break;
229 case 11:
230 if (fCanBeProtected) {
231 set(fIsProtected, skgpu::Protected(!static_cast<bool>(fIsProtected)));
232 }
233 break;
234 case 12:
235 if (GrBackendApi::kVulkan == fBackend) {
236 set(fForVulkanSecondaryCommandBuffer, true);
237 set(fUsesGLFBO0, false);
238 set(fShouldCreateMipMaps,
239 skgpu::Mipmapped::kNo); // needs to changed in tandem w/ textureability
240 set(fIsTextureable, false);
241 set(fVkRTSupportsInputAttachment, false);
242 }
243 break;
244 }
245 return changed;
246 }
247
249 size_t maxResourceBytes = dContext->getResourceCacheLimit();
250
251 if (!dContext->colorTypeSupportedAsSurface(fColorType)) {
253 }
254
255 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
256 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
257 kPremul_SkAlphaType, fColorSpace);
258
259 GrBackendFormat backendFormat = dContext->defaultBackendFormat(fColorType,
260 GrRenderable::kYes);
261 if (!backendFormat.isValid()) {
263 }
264
266 maxResourceBytes, ii, backendFormat, fSampleCount,
267 fOrigin, fSurfaceProps, fShouldCreateMipMaps,
268 fUsesGLFBO0, fIsTextureable, fIsProtected,
269 fVkRTSupportsInputAttachment,
270 fForVulkanSecondaryCommandBuffer);
271 return c;
272 }
273
274 // Create a DDL whose characterization captures the current settings
278
280 SkCanvas* canvas = r.getCanvas();
281 if (!canvas) {
282 return nullptr;
283 }
284
285 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
286 return r.detach();
287 }
288
289 // Create the surface with the current set of parameters
291 const GrSurfaceCharacterization c = this->createCharacterization(dContext);
292
293#ifdef SK_GL
294 if (fUsesGLFBO0) {
295 if (GrBackendApi::kOpenGL != dContext->backend()) {
296 return nullptr;
297 }
298
299 GrGLFramebufferInfo fboInfo;
300 fboInfo.fFBOID = 0;
301 fboInfo.fFormat = GR_GL_RGBA8;
302 fboInfo.fProtected = skgpu::Protected::kNo;
303 static constexpr int kStencilBits = 8;
304 GrBackendRenderTarget backendRT =
305 GrBackendRenderTargets::MakeGL(fWidth, fHeight, 1, kStencilBits, fboInfo);
306
307 if (!backendRT.isValid()) {
308 return nullptr;
309 }
310
312 dContext, backendRT, fOrigin, fColorType, fColorSpace, &fSurfaceProps);
313 SkASSERT(result->isCompatible(c));
314 return result;
315 }
316#endif
317
318 // We can't make SkSurfaces for vulkan secondary command buffers.
319 if (fForVulkanSecondaryCommandBuffer) {
320 return nullptr;
321 }
322
324 if (fIsTextureable) {
326 {fWidth, fHeight},
327 fOrigin,
328 fSampleCount,
329 fColorType,
330 fColorSpace,
331 fShouldCreateMipMaps,
332 fIsProtected,
333 &fSurfaceProps);
334 } else {
335 // Create a surface w/ the current parameters but make it non-textureable
336 SkASSERT(fShouldCreateMipMaps == skgpu::Mipmapped::kNo);
338 {fWidth, fHeight},
339 fOrigin,
340 fSampleCount,
341 fColorType,
342 fColorSpace,
343 fIsProtected,
344 &fSurfaceProps);
345 }
346
347 if (!surface) {
348 SkASSERT(!c.isValid());
349 return nullptr;
350 }
351
353 surface.get(), SkSurfaces::BackendHandleAccess::kFlushRead);
354 if (texture.isValid()) {
356 }
357
358 SkASSERT(c.isValid());
359 SkASSERT(surface->isCompatible(c));
360 return surface;
361 }
362
363#ifdef SK_VULKAN
365 const GrSurfaceCharacterization c = this->createCharacterization(dContext);
366 SkImageInfo imageInfo = SkImageInfo::Make({fWidth, fHeight},
367 {fColorType, kPremul_SkAlphaType, fColorSpace});
368 GrVkDrawableInfo vkInfo;
369 // putting in a bunch of placeholder values here
370 vkInfo.fSecondaryCommandBuffer = (VkCommandBuffer)1;
371 vkInfo.fColorAttachmentIndex = 0;
372 vkInfo.fCompatibleRenderPass = (VkRenderPass)1;
373 vkInfo.fFormat = VK_FORMAT_R8G8B8A8_UNORM;
374 vkInfo.fDrawBounds = nullptr;
375
376 return GrVkSecondaryCBDrawContext::Make(dContext, imageInfo, vkInfo, &fSurfaceProps);
377 }
378#endif
379
380private:
381 GrBackendApi fBackend;
382 bool fCanBeProtected;
383
384 int fWidth;
385 int fHeight;
386 GrSurfaceOrigin fOrigin;
387 SkColorType fColorType;
388 sk_sp<SkColorSpace> fColorSpace;
389 int fSampleCount;
390 SkSurfaceProps fSurfaceProps;
391 skgpu::Mipmapped fShouldCreateMipMaps;
392 bool fUsesGLFBO0;
393 bool fIsTextureable;
394 skgpu::Protected fIsProtected;
395 bool fVkRTSupportsInputAttachment;
396 bool fForVulkanSecondaryCommandBuffer;
397};
398
399// Test out operator== && operator!=
401 reporter,
402 ctxInfo,
404 auto context = ctxInfo.directContext();
405
406 for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
407 SurfaceParameters params1(context);
408 bool didModify1 = i >= 0 && params1.modify(i);
409
410 GrSurfaceCharacterization char1 = params1.createCharacterization(context);
411 if (!char1.isValid()) {
412 continue; // can happen on some platforms (ChromeOS)
413 }
414
415 for (int j = -1; j < SurfaceParameters::kNumParams; ++j) {
416 SurfaceParameters params2(context);
417 bool didModify2 = j >= 0 && params2.modify(j);
418
419 GrSurfaceCharacterization char2 = params2.createCharacterization(context);
420 if (!char2.isValid()) {
421 continue; // can happen on some platforms (ChromeOS)
422 }
423
424 if (i == j || (!didModify1 && !didModify2)) {
425 REPORTER_ASSERT(reporter, char1 == char2);
426 } else {
427 REPORTER_ASSERT(reporter, char1 != char2);
428 }
429 }
430 }
431
432 {
433 SurfaceParameters params(context);
434
435 GrSurfaceCharacterization valid = params.createCharacterization(context);
436 SkASSERT(valid.isValid());
437
438 GrSurfaceCharacterization inval1, inval2;
439 SkASSERT(!inval1.isValid() && !inval2.isValid());
440
441 REPORTER_ASSERT(reporter, inval1 != inval2);
442 REPORTER_ASSERT(reporter, valid != inval1);
443 REPORTER_ASSERT(reporter, inval1 != valid);
444 }
445}
446
447////////////////////////////////////////////////////////////////////////////////
448// This tests GrSurfaceCharacterization/SkSurface compatibility
450 // Create a bitmap that we can readback into
454 bitmap.allocPixels(imageInfo);
455
457
458 // First, create a DDL using the stock SkSurface parameters
459 {
460 SurfaceParameters params(dContext);
461 if (dContext->backend() == GrBackendApi::kVulkan) {
462 params.setVkRTInputAttachmentSupport(true);
463 }
464 ddl = params.createDDL(dContext);
465 SkAssertResult(ddl);
466
467 // The DDL should draw into an SkSurface created with the same parameters
468 sk_sp<SkSurface> s = params.make(dContext);
469 if (!s) {
470 return;
471 }
472
474 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
475
476 dContext->flush();
477 }
478
479 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
480 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
481 SurfaceParameters params(dContext);
482 if (!params.modify(i)) {
483 continue;
484 }
485
486 sk_sp<SkSurface> s = params.make(dContext);
487 if (!s) {
488 continue;
489 }
490
492 "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i);
493 dContext->flush();
494 }
495
496 // Next test the compatibility of resource cache parameters
497 {
498 const SurfaceParameters params(dContext);
499
500 sk_sp<SkSurface> s = params.make(dContext);
501
502 size_t maxResourceBytes = dContext->getResourceCacheLimit();
503
504 dContext->setResourceCacheLimit(maxResourceBytes/2);
506
507 // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests.
508 // For now, DDLs are drawn once.
509#if 0
510 // resource limits >= those at characterization time are accepted
511 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
513 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
514
515 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
517 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
518
519 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
521 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
522#endif
523
524 dContext->flush();
525 }
526
527 // Test that the textureability of the DDL characterization can block a DDL draw
528 {
529 SurfaceParameters params(dContext);
530 params.disableTextureability();
531
532 sk_sp<SkSurface> s = params.make(dContext);
533 if (s) {
534 // bc the DDL was made w/ textureability
536
537 dContext->flush();
538 }
539 }
540
541 // Make sure non-GPU-backed surfaces fail characterization
542 {
544
545 sk_sp<SkSurface> rasterSurface = SkSurfaces::Raster(ii);
547 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
548 }
549
550 // Exercise the createResized method
551 {
552 SurfaceParameters params(dContext);
553
554 sk_sp<SkSurface> s = params.make(dContext);
555 if (!s) {
556 return;
557 }
558
560 SkAssertResult(s->characterize(&char0));
561
562 // Too small
563 GrSurfaceCharacterization char1 = char0.createResized(-1, -1);
565
566 // Too large
567 GrSurfaceCharacterization char2 = char0.createResized(1000000, 32);
569
570 // Just right
571 GrSurfaceCharacterization char3 = char0.createResized(32, 32);
573 REPORTER_ASSERT(reporter, 32 == char3.width());
574 REPORTER_ASSERT(reporter, 32 == char3.height());
575 }
576
577 // Exercise the createColorSpace method
578 {
579 SurfaceParameters params(dContext);
580
581 sk_sp<SkSurface> s = params.make(dContext);
582 if (!s) {
583 return;
584 }
585
587 SkAssertResult(s->characterize(&char0));
588
589 // The default params create an sRGB color space
592
593 {
595
596 GrSurfaceCharacterization char1 = char0.createColorSpace(std::move(newCS));
600 }
601
602 {
603 GrSurfaceCharacterization char2 = char0.createColorSpace(nullptr);
606 }
607
608 {
610
612 REPORTER_ASSERT(reporter, !invalid.isValid());
613 GrSurfaceCharacterization stillInvalid = invalid.createColorSpace(std::move(newCS));
614 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
615 }
616 }
617
618 // Exercise the createBackendFormat method
619 {
620 SurfaceParameters params(dContext);
621
622 sk_sp<SkSurface> s = params.make(dContext);
623 if (!s) {
624 return;
625 }
626
628 SkAssertResult(s->characterize(&char0));
629
630 // The default params create a renderable RGBA8 surface
631 auto originalBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
632 GrRenderable::kYes);
633 REPORTER_ASSERT(reporter, originalBackendFormat.isValid());
634 REPORTER_ASSERT(reporter, char0.backendFormat() == originalBackendFormat);
635
636 auto newBackendFormat = dContext->defaultBackendFormat(kRGB_565_SkColorType,
637 GrRenderable::kYes);
638
639 if (newBackendFormat.isValid()) {
641 newBackendFormat);
643 REPORTER_ASSERT(reporter, char1.backendFormat() == newBackendFormat);
644
646 REPORTER_ASSERT(reporter, !invalid.isValid());
647 auto stillInvalid = invalid.createBackendFormat(kRGB_565_SkColorType,
648 newBackendFormat);
649 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
650 }
651 }
652
653 // Exercise the createFBO0 method
654 if (dContext->backend() == GrBackendApi::kOpenGL) {
655 SurfaceParameters params(dContext);
656 // If the original characterization is textureable then we will fail trying to make an
657 // FBO0 characterization
658 params.disableTextureability();
659
660 sk_sp<SkSurface> s = params.make(dContext);
661 if (!s) {
662 return;
663 }
664
666 SkAssertResult(s->characterize(&char0));
667
668 // The default params create a non-FBO0 surface
669 REPORTER_ASSERT(reporter, !char0.usesGLFBO0());
670
671 {
672 GrSurfaceCharacterization char1 = char0.createFBO0(true);
674 REPORTER_ASSERT(reporter, char1.usesGLFBO0());
675 }
676
677 {
679 REPORTER_ASSERT(reporter, !invalid.isValid());
680 GrSurfaceCharacterization stillInvalid = invalid.createFBO0(true);
681 REPORTER_ASSERT(reporter, !stillInvalid.isValid());
682 }
683 }
684}
685
686#ifdef SK_GL
687
688// Test out the surface compatibility checks regarding FBO0-ness. This test constructs
689// two parallel arrays of characterizations and surfaces in the order:
690// FBO0 w/ MSAA, FBO0 w/o MSAA, not-FBO0 w/ MSAA, not-FBO0 w/o MSAA
691// and then tries all sixteen combinations to check the expected compatibility.
692// Note: this is a GL-only test
693DEF_GANESH_TEST_FOR_GL_CONTEXT(CharacterizationFBO0nessTest,
694 reporter,
695 ctxInfo,
697 auto context = ctxInfo.directContext();
698 const GrCaps* caps = context->priv().caps();
699 sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy();
700 const size_t resourceCacheLimit = context->getResourceCacheLimit();
701
703
704 int availableSamples = caps->getRenderTargetSampleCount(4, format);
705 if (availableSamples <= 1) {
706 // This context doesn't support MSAA for RGBA8
707 return;
708 }
709
711
712 static constexpr int kStencilBits = 8;
713 static constexpr bool kNotTextureable = false;
714 const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
715
716 // Rows are characterizations and columns are surfaces
717 static const bool kExpectedCompatibility[4][4] = {
718 // FBO0 & MSAA, FBO0 & not-MSAA, not-FBO0 & MSAA, not-FBO0 & not-MSAA
719/* FBO0 & MSAA */ { true, false, false, false },
720/* FBO0 & not-MSAA */ { false, true, false, true },
721/* not-FBO0 & MSAA */ { false, false, true, false },
722/* not-FBO0 & not- */ { false, false, false, true }
723 };
724
725 GrSurfaceCharacterization characterizations[4];
726 sk_sp<SkSurface> surfaces[4];
727
728 int index = 0;
729 for (bool isFBO0 : { true, false }) {
730 for (int numSamples : { availableSamples, 1 }) {
731 characterizations[index] = proxy->createCharacterization(resourceCacheLimit,
732 ii,
733 format,
734 numSamples,
736 surfaceProps,
737 skgpu::Mipmapped::kNo,
738 isFBO0,
739 kNotTextureable);
740 SkASSERT(characterizations[index].sampleCount() == numSamples);
741 SkASSERT(characterizations[index].usesGLFBO0() == isFBO0);
742
743 GrGLFramebufferInfo fboInfo{ isFBO0 ? 0 : (GrGLuint) 1, GR_GL_RGBA8 };
744 GrBackendRenderTarget backendRT =
745 GrBackendRenderTargets::MakeGL(128, 128, numSamples, kStencilBits, fboInfo);
746 SkAssertResult(backendRT.isValid());
747
748 surfaces[index] = SkSurfaces::WrapBackendRenderTarget(context,
749 backendRT,
752 nullptr,
753 &surfaceProps);
754 ++index;
755 }
756 }
757
758 for (int c = 0; c < 4; ++c) {
759 for (int s = 0; s < 4; ++s) {
761 kExpectedCompatibility[c][s] ==
762 surfaces[s]->isCompatible(characterizations[c]));
763 }
764 }
765}
766#endif
767
768#ifdef SK_VULKAN
769DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(CharacterizationVkSCBnessTest,
770 reporter,
771 ctxInfo,
773 auto dContext = ctxInfo.directContext();
774
775 SurfaceParameters params(dContext);
777 GrSurfaceCharacterization characterization = params.createCharacterization(dContext);
778 REPORTER_ASSERT(reporter, characterization.isValid());
779
780 sk_sp<GrDeferredDisplayList> ddl = params.createDDL(dContext);
782
783 sk_sp<GrVkSecondaryCBDrawContext> scbDrawContext = params.makeVkSCB(dContext);
784 REPORTER_ASSERT(reporter, scbDrawContext->isCompatible(characterization));
785
786 scbDrawContext->releaseResources();
787}
788#endif
789
790DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest,
791 reporter,
792 ctxInfo,
794 auto context = ctxInfo.directContext();
795
797}
798
799#if defined(SK_VULKAN)
800DEF_GANESH_TEST(VkProtectedContext_DDLSurfaceCharacterizationTest,
801 reporter,
802 ctxInfo,
804 std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
805 /* isProtected= */ true);
806 if (!helper) {
807 return;
808 }
809
810 REPORTER_ASSERT(reporter, helper->isValid());
811
812 DDLSurfaceCharacterizationTestImpl(helper->directContext(), reporter);
813}
814#endif
815
816// Test that a DDL created w/o textureability can be replayed into both a textureable and
817// non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a
818// textureable DDL cannot be played into a non-textureable destination but can be replayed
819// into a textureable destination.
821 reporter,
822 ctxInfo,
824 auto context = ctxInfo.directContext();
825
826 // Create a bitmap that we can readback into
830 bitmap.allocPixels(imageInfo);
831
832 for (bool textureability : { true, false }) {
834
835 // First, create a DDL w/o textureability (and thus no mipmaps). TODO: once we have
836 // reusable DDLs, move this outside of the loop.
837 {
838 SurfaceParameters params(context);
839 params.disableTextureability();
840 if (context->backend() == GrBackendApi::kVulkan) {
841 params.setVkRTInputAttachmentSupport(true);
842 }
843
844 ddl = params.createDDL(context);
845 SkAssertResult(ddl);
846 }
847
848 // Then verify it can draw into either flavor of destination
849 SurfaceParameters params(context);
850 if (!textureability) {
851 params.disableTextureability();
852 }
853 if (context->backend() == GrBackendApi::kVulkan) {
854 params.setVkRTInputAttachmentSupport(true);
855 }
856
857 sk_sp<SkSurface> s = params.make(context);
858 if (!s) {
859 continue;
860 }
861
863 s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
864
865 context->flush();
866 }
867}
868
870 GrDirectContext* dContext,
871 const SurfaceParameters& params) {
872 {
873 const GrSurfaceCharacterization c = params.createCharacterization(dContext);
874
875 if (!c.isValid()) {
876 sk_sp<SkSurface> tmp = params.make(dContext);
877 // If we couldn't characterize the surface we shouldn't be able to create it either
879 return;
880 }
881 }
882
883 const GrSurfaceCharacterization c = params.createCharacterization(dContext);
884 {
885 sk_sp<SkSurface> s = params.make(dContext);
887 if (!s) {
889 return;
890 }
891
894 SkSurfaces::GetBackendTexture(s.get(), SkSurfaces::BackendHandleAccess::kFlushRead);
895 if (backend.isValid()) {
897 }
898 REPORTER_ASSERT(reporter, s->isCompatible(c));
899 // Note that we're leaving 'backend' live here
900 }
901
902 // Make an SkSurface from scratch
903 {
906 REPORTER_ASSERT(reporter, s->isCompatible(c));
907 }
908}
909
910////////////////////////////////////////////////////////////////////////////////
911// This tests the SkSurfaces::RenderTarget variants that take a GrSurfaceCharacterization.
912// In particular, the SkSurface, backendTexture and GrSurfaceCharacterization
913// should always be compatible.
915 for (int i = -1; i < SurfaceParameters::kNumParams; ++i) {
917 // MakeRenderTarget doesn't support FBO0 or vulkan secondary command buffers
918 continue;
919 }
920
921 SurfaceParameters params(dContext);
922 if (i >= 0 && !params.modify(i)) {
923 continue;
924 }
925
927 }
928}
929
931 reporter,
932 ctxInfo,
934 auto context = ctxInfo.directContext();
935
937}
938
939#if defined(SK_VULKAN)
940
941DEF_GANESH_TEST(VkProtectedContext_DDLMakeRenderTargetTest,
942 reporter,
943 ctxInfo,
945 std::unique_ptr<VkTestHelper> helper = VkTestHelper::Make(skiatest::TestType::kGanesh,
946 /* isProtected= */ true);
947 if (!helper) {
948 return;
949 }
950 REPORTER_ASSERT(reporter, helper->isValid());
951
952 DDLMakeRenderTargetTestImpl(helper->directContext(), reporter);
953}
954#endif
955
956////////////////////////////////////////////////////////////////////////////////
957static constexpr int kSize = 8;
958
962 static void Release(void* self) {
963 static_cast<TextureReleaseChecker*>(self)->fReleaseCount++;
964 }
965};
966
968
969// This tests the ability to create and use wrapped textures in a DDL world
971 reporter,
972 ctxInfo,
974 auto dContext = ctxInfo.directContext();
975
976 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(dContext,
977 kSize,
978 kSize,
980 skgpu::Mipmapped::kNo,
981 GrRenderable::kNo,
982 skgpu::Protected::kNo);
983 if (!mbet) {
984 return;
985 }
986
987 SurfaceParameters params(dContext);
988
989 sk_sp<SkSurface> s = params.make(dContext);
990 if (!s) {
991 return;
992 }
993
995 SkAssertResult(s->characterize(&c));
996
998
999 SkCanvas* canvas = recorder.getCanvas();
1000 SkASSERT(canvas);
1001
1002 auto rContext = canvas->recordingContext();
1003 if (!rContext) {
1004 return;
1005 }
1006
1007 // Wrapped Backend Textures are not supported in DDL
1008 TextureReleaseChecker releaseChecker;
1010 rContext,
1011 mbet->texture(),
1015 nullptr,
1016 sk_gpu_test::ManagedBackendTexture::ReleaseProc,
1017 mbet->releaseContext(TextureReleaseChecker::Release, &releaseChecker));
1019}
1020
1021////////////////////////////////////////////////////////////////////////////////
1022// Test out the behavior of an invalid DDLRecorder
1024 reporter,
1025 ctxInfo,
1027 auto dContext = ctxInfo.directContext();
1028
1029 {
1032
1033 GrSurfaceCharacterization characterization;
1034 SkAssertResult(s->characterize(&characterization));
1035
1036 // never calling getCanvas means the backing surface is never allocated
1037 GrDeferredDisplayListRecorder recorder(characterization);
1038 }
1039
1040 {
1042
1044
1045 const GrSurfaceCharacterization c = recorder.characterization();
1047 REPORTER_ASSERT(reporter, !recorder.getCanvas());
1048 REPORTER_ASSERT(reporter, !recorder.detach());
1049 }
1050}
1051
1052DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(DDLCreateCharacterizationFailures,
1053 reporter,
1054 ctxInfo,
1056 using namespace skgpu;
1057
1058 auto dContext = ctxInfo.directContext();
1059 size_t maxResourceBytes = dContext->getResourceCacheLimit();
1060 auto proxy = dContext->threadSafeProxy().get();
1061
1062 Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
1063
1064 auto check_create_fails = [proxy, reporter, maxResourceBytes](
1065 const GrBackendFormat& backendFormat,
1066 int width,
1067 int height,
1068 SkColorType ct,
1069 bool willUseGLFBO0,
1070 bool isTextureable,
1071 Protected prot,
1072 bool vkRTSupportsInputAttachment,
1073 bool forVulkanSecondaryCommandBuffer) {
1074 const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry);
1075
1077 kPremul_SkAlphaType, nullptr);
1078
1080 proxy->createCharacterization(maxResourceBytes,
1081 ii,
1082 backendFormat,
1083 1,
1085 surfaceProps,
1086 Mipmapped::kNo,
1087 willUseGLFBO0,
1088 isTextureable,
1089 prot,
1090 vkRTSupportsInputAttachment,
1091 forVulkanSecondaryCommandBuffer);
1093 };
1094
1095 GrBackendFormat goodBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType,
1096 GrRenderable::kYes);
1097 SkASSERT(goodBackendFormat.isValid());
1098
1099 GrBackendFormat badBackendFormat;
1100 SkASSERT(!badBackendFormat.isValid());
1101
1104
1105 static const bool kIsTextureable = true;
1106 static const bool kIsNotTextureable = false;
1107
1108 static const bool kGoodUseFBO0 = false;
1109 static const bool kBadUseFBO0 = true;
1110
1111 static const bool kGoodVkInputAttachment = false;
1112 static const bool kBadVkInputAttachment = true;
1113
1114 static const bool kGoodForVkSCB = false;
1115 static const bool kBadForVkSCB = true;
1116
1117 int goodWidth = 64;
1118 int goodHeight = 64;
1119 int badWidths[] = { 0, 1048576 };
1120 int badHeights[] = { 0, 1048576 };
1121
1122
1123 // In each of the check_create_fails calls there is one bad parameter that should cause the
1124 // creation of the characterization to fail.
1125 check_create_fails(goodBackendFormat, goodWidth, badHeights[0], kGoodCT, kGoodUseFBO0,
1126 kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1127 check_create_fails(goodBackendFormat, goodWidth, badHeights[1], kGoodCT, kGoodUseFBO0,
1128 kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1129 check_create_fails(goodBackendFormat, badWidths[0], goodHeight, kGoodCT, kGoodUseFBO0,
1130 kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1131 check_create_fails(goodBackendFormat, badWidths[1], goodHeight, kGoodCT, kGoodUseFBO0,
1132 kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1133 check_create_fails(badBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1134 kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1135 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kBadCT, kGoodUseFBO0,
1136 kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1137 // This fails because we always try to make a characterization that is textureable and we can't
1138 // have UseFBO0 be true and textureable.
1139 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
1140 kIsTextureable, isProtected, kGoodVkInputAttachment, kGoodForVkSCB);
1141 if (dContext->backend() == GrBackendApi::kVulkan) {
1142 // The following fails because forVulkanSecondaryCommandBuffer is true and
1143 // isTextureable is true. This is not a legal combination.
1144 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1145 kIsTextureable, isProtected, kGoodVkInputAttachment, kBadForVkSCB);
1146 // The following fails because forVulkanSecondaryCommandBuffer is true and
1147 // vkRTSupportsInputAttachment is true. This is not a legal combination.
1148 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1149 kIsNotTextureable, isProtected, kBadVkInputAttachment,
1150 kBadForVkSCB);
1151 // The following fails because forVulkanSecondaryCommandBuffer is true and
1152 // willUseGLFBO0 is true. This is not a legal combination.
1153 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0,
1154 kIsNotTextureable, isProtected, kGoodVkInputAttachment,
1155 kBadForVkSCB);
1156 } else {
1157 // The following set vulkan only flags on non vulkan backends.
1158 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1159 kIsTextureable, isProtected, kBadVkInputAttachment, kGoodForVkSCB);
1160 check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0,
1161 kIsNotTextureable, isProtected, kGoodVkInputAttachment,
1162 kBadForVkSCB);
1163 }
1164}
1165
1166////////////////////////////////////////////////////////////////////////////////
1167// Test that flushing a DDL via SkSurface::flush works
1168
1174
1176 FulfillInfo* info = (FulfillInfo*) context;
1177 info->fFulfilled = true;
1178 return info->fTex;
1179}
1180
1181static void tracking_release_proc(void* context) {
1182 FulfillInfo* info = (FulfillInfo*) context;
1183 info->fReleased = true;
1184}
1185
1187 reporter,
1188 ctxInfo,
1190 using namespace skgpu;
1191
1192 auto context = ctxInfo.directContext();
1193
1194 Protected isProtected = Protected(context->priv().caps()->supportsProtectedContent());
1195
1197 sk_sp<SkSurface> s = SkSurfaces::RenderTarget(context, Budgeted::kNo, ii);
1198
1199 GrSurfaceCharacterization characterization;
1200 SkAssertResult(s->characterize(&characterization));
1201
1202 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeFromInfo(context, ii,
1203 Mipmapped::kNo,
1204 Renderable::kNo,
1205 isProtected);
1206 if (!mbet) {
1207 ERRORF(reporter, "Could not make texture.");
1208 return;
1209 }
1210
1211 FulfillInfo fulfillInfo;
1212 fulfillInfo.fTex = GrPromiseImageTexture::Make(mbet->texture());
1213
1215
1216 {
1217 GrDeferredDisplayListRecorder recorder(characterization);
1218
1219 GrBackendFormat format = context->defaultBackendFormat(kRGBA_8888_SkColorType,
1220 GrRenderable::kNo);
1221 SkASSERT(format.isValid());
1222
1223 SkCanvas* canvas = recorder.getCanvas();
1224
1225 sk_sp<SkImage> promiseImage =
1227 format,
1228 SkISize::Make(32, 32),
1229 skgpu::Mipmapped::kNo,
1233 nullptr,
1236 &fulfillInfo);
1237
1238 canvas->clear(SK_ColorRED);
1239 canvas->drawImage(promiseImage, 0, 0);
1240 ddl = recorder.detach();
1241 }
1242
1243 context->flushAndSubmit();
1244
1246
1247 GrFlushInfo flushInfo;
1248 context->flush(s.get(), SkSurfaces::BackendSurfaceAccess::kPresent, flushInfo);
1249 context->submit(GrSyncCpu::kNo);
1250
1251 REPORTER_ASSERT(reporter, fulfillInfo.fFulfilled);
1252
1253 // In order to receive the done callback with the low-level APIs we need to re-flush
1254 context->flush(s.get());
1255 context->submit(GrSyncCpu::kYes);
1256
1257 REPORTER_ASSERT(reporter, fulfillInfo.fReleased);
1258
1259 REPORTER_ASSERT(reporter, fulfillInfo.fTex->unique());
1260 fulfillInfo.fTex.reset();
1261}
1262
1263////////////////////////////////////////////////////////////////////////////////
1264// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly
1266 auto context = ctxInfo.directContext();
1267
1270
1272 bitmap.allocPixels(ii);
1273
1274 GrSurfaceCharacterization characterization;
1275 SkAssertResult(s->characterize(&characterization));
1276
1277 GrDeferredDisplayListRecorder recorder(characterization);
1278
1279 SkCanvas* canvas1 = recorder.getCanvas();
1280
1281 canvas1->clear(SK_ColorRED);
1282
1283 canvas1->save();
1284 canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16));
1285
1286 sk_sp<GrDeferredDisplayList> ddl1 = recorder.detach();
1287
1288 SkCanvas* canvas2 = recorder.getCanvas();
1289
1290 SkPaint p;
1291 p.setColor(SK_ColorGREEN);
1292 canvas2->drawRect(SkRect::MakeWH(32, 32), p);
1293
1294 sk_sp<GrDeferredDisplayList> ddl2 = recorder.detach();
1295
1296 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData());
1297 REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData());
1298
1299 // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing-
1300 // lazy proxy are all different between the two DDLs
1301 REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData());
1302
1305
1306 // Make sure the clipRect from DDL1 didn't percolate into DDL2
1307 s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
1308 for (int y = 0; y < 32; ++y) {
1309 for (int x = 0; x < 32; ++x) {
1311 if (bitmap.getColor(x, y) != SK_ColorGREEN) {
1312 return; // we only really need to report the error once
1313 }
1314 }
1315 }
1316}
1317
1318#ifdef SK_GL
1319
1320static sk_sp<GrPromiseImageTexture> noop_fulfill_proc(void*) {
1321 SkASSERT(0);
1322 return nullptr;
1323}
1324
1325////////////////////////////////////////////////////////////////////////////////
1326// Check that the texture-specific flags (i.e., for external & rectangle textures) work
1327// for promise images. As such, this is a GL-only test.
1328DEF_GANESH_TEST_FOR_GL_CONTEXT(DDLTextureFlagsTest, reporter, ctxInfo, CtsEnforcement::kNever) {
1329 auto context = ctxInfo.directContext();
1330
1333
1334 GrSurfaceCharacterization characterization;
1335 SkAssertResult(s->characterize(&characterization));
1336
1337 GrDeferredDisplayListRecorder recorder(characterization);
1338
1340 for (auto mipmapped : {skgpu::Mipmapped::kNo, skgpu::Mipmapped::kYes}) {
1342
1344 recorder.getCanvas()->recordingContext()->threadSafeProxy(),
1345 format,
1346 SkISize::Make(32, 32),
1347 mipmapped,
1351 /*color space*/ nullptr,
1352 noop_fulfill_proc,
1353 /*release proc*/ nullptr,
1354 /*context*/ nullptr);
1355 if (GR_GL_TEXTURE_2D != target && mipmapped == skgpu::Mipmapped::kYes) {
1357 continue;
1358 }
1359 if (!context->priv().caps()->isFormatTexturable(format, format.textureType())) {
1361 continue;
1362 }
1364
1365 GrTextureProxy* backingProxy = sk_gpu_test::GetTextureImageProxy(image.get(), context);
1366
1367 REPORTER_ASSERT(reporter, backingProxy->mipmapped() == mipmapped);
1368 if (GR_GL_TEXTURE_2D == target) {
1370 } else {
1372 }
1373 }
1374 }
1375}
1376#endif // SK_GL
1377
1378////////////////////////////////////////////////////////////////////////////////
1379// Test colorType and pixelConfig compatibility.
1381 auto context = ctxInfo.directContext();
1382
1383 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) {
1384 SkColorType colorType = static_cast<SkColorType>(ct);
1385
1386 SurfaceParameters params(context);
1387 params.setColorType(colorType);
1388 params.setColorSpace(nullptr);
1389
1391 }
1392}
static bool invalid(const SkISize &size)
const char * backend
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
static constexpr int kSize
static sk_sp< GrPromiseImageTexture > tracking_fulfill_proc(void *context)
static bool is_compatible(const GrSurfaceCharacterization &gsc, const GrBackendTexture &backendTex)
static void test_make_render_target(skiatest::Reporter *reporter, GrDirectContext *dContext, const SurfaceParameters &params)
void DDLMakeRenderTargetTestImpl(GrDirectContext *dContext, skiatest::Reporter *reporter)
void DDLSurfaceCharacterizationTestImpl(GrDirectContext *dContext, skiatest::Reporter *reporter)
static void tracking_release_proc(void *context)
reporter
#define GR_GL_RGBA8
#define GR_GL_TEXTURE_2D
#define GR_GL_TEXTURE_RECTANGLE
#define GR_GL_TEXTURE_EXTERNAL
unsigned int GrGLuint
Definition GrGLTypes.h:113
unsigned int GrGLenum
Definition GrGLTypes.h:102
GrSurfaceOrigin
Definition GrTypes.h:147
@ kBottomLeft_GrSurfaceOrigin
Definition GrTypes.h:149
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
GrBackendApi
Definition GrTypes.h:95
skgpu::Protected Protected
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkAssertResult(cond)
Definition SkAssert.h:123
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition SkColorType.h:38
@ kLastEnum_SkColorType
last valid value
Definition SkColorType.h:56
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
@ kNo
Don't pre-clip the geometry before applying the (perspective) matrix.
@ kUnknown_SkPixelGeometry
@ kRGB_H_SkPixelGeometry
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
#define DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(name, reporter, context_info, ctsEnforcement)
Definition Test.h:458
#define DEF_GANESH_TEST(name, reporter, options, ctsEnforcement)
Definition Test.h:393
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define DEF_GANESH_TEST_FOR_GL_CONTEXT(name, reporter, context_info, ctsEnforcement)
Definition Test.h:442
#define ERRORF(r,...)
Definition Test.h:293
#define DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info, ctsEnforcement)
Definition Test.h:434
bool isValid() const
GrBackendFormat getBackendFormat() const
bool hasMipmaps() const
GrBackendApi backend() const
const GrCaps * caps() const
bool mipmapSupport() const
Definition GrCaps.h:72
virtual int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat &) const =0
GrSurfaceCharacterization createCharacterization(size_t cacheMaxResourceBytes, const SkImageInfo &ii, const GrBackendFormat &backendFormat, int sampleCount, GrSurfaceOrigin origin, const SkSurfaceProps &surfaceProps, skgpu::Mipmapped isMipmapped, bool willUseGLFBO0=false, bool isTextureable=true, skgpu::Protected isProtected=GrProtected::kNo, bool vkRTSupportsInputAttachment=false, bool forVulkanSecondaryCommandBuffer=false)
SK_API GrBackendApi backend() const
sk_sp< GrContextThreadSafeProxy > threadSafeProxy()
SK_API GrBackendFormat defaultBackendFormat(SkColorType, GrRenderable) const
const GrSurfaceCharacterization & characterization() const
sk_sp< GrDeferredDisplayList > detach()
SK_API bool colorTypeSupportedAsSurface(SkColorType colorType) const
size_t getResourceCacheLimit() const
GrSemaphoresSubmitted flush(const GrFlushInfo &info)
sk_sp< GrContextThreadSafeProxy > threadSafeProxy()
void setResourceCacheLimit(size_t maxResourceBytes)
static sk_sp< GrPromiseImageTexture > Make(const GrBackendTexture &backendTexture)
GrRecordingContextPriv priv()
GrSurfaceCharacterization createColorSpace(sk_sp< SkColorSpace >) const
GrSurfaceCharacterization createFBO0(bool usesGLFBO0) const
GrSurfaceCharacterization createResized(int width, int height) const
GrSurfaceCharacterization createBackendFormat(SkColorType colorType, const GrBackendFormat &backendFormat) const
bool hasRestrictedSampling() const
skgpu::Mipmapped mipmapped() const
static sk_sp< GrVkSecondaryCBDrawContext > Make(GrRecordingContext *, const SkImageInfo &, const GrVkDrawableInfo &, const SkSurfaceProps *props)
void drawRect(const SkRect &rect, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
virtual GrRecordingContext * recordingContext() const
void clear(SkColor color)
Definition SkCanvas.h:1199
int save()
Definition SkCanvas.cpp:451
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
bool gammaIsLinear() const
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
bool isSRGB() const
static sk_sp< SkColorSpace > MakeSRGBLinear()
bool unique() const
Definition SkRefCnt.h:175
@ kUseDeviceIndependentFonts_Flag
sk_sp< GrDeferredDisplayList > createDDL(GrDirectContext *dContext) const
void setVkRTInputAttachmentSupport(bool inputSupport)
void setColorType(SkColorType ct)
sk_sp< SkSurface > make(GrDirectContext *dContext) const
void setColorSpace(sk_sp< SkColorSpace > cs)
void setForVulkanSecondaryCommandBuffer(bool forVkSCB)
GrSurfaceCharacterization createCharacterization(GrDirectContext *dContext) const
SkColorType colorType() const
SurfaceParameters(GrRecordingContext *rContext)
void setShouldCreateMipMaps(skgpu::Mipmapped shouldCreateMipMaps)
T * get() const
Definition SkRefCnt.h:303
void reset(T *ptr=nullptr)
Definition SkRefCnt.h:310
const EmbeddedViewParams * params
VkSurfaceKHR surface
Definition main.cc:49
sk_sp< SkImage > image
Definition examples.cpp:29
struct MyStruct s
uint8_t value
GAsyncResult * result
uint32_t uint32_t * format
uint32_t * target
FlTexture * texture
double y
double x
SK_API GrBackendFormat MakeGL(GrGLenum format, GrGLenum target)
SK_API GrBackendRenderTarget MakeGL(int width, int height, int sampleCnt, int stencilBits, const GrGLFramebufferInfo &glInfo)
SK_API bool GetVkImageInfo(const GrBackendTexture &, GrVkImageInfo *)
SK_API sk_sp< SkImage > PromiseTextureFrom(skgpu::graphite::Recorder *, SkISize dimensions, const skgpu::graphite::TextureInfo &, const SkColorInfo &, skgpu::Origin origin, skgpu::graphite::Volatile, GraphitePromiseTextureFulfillProc, GraphitePromiseImageReleaseProc, GraphitePromiseTextureReleaseProc, GraphitePromiseImageContext)
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
static constexpr skcms_Matrix3x3 kAdobeRGB
static constexpr skcms_TransferFunction kSRGB
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_API sk_sp< SkSurface > WrapBackendRenderTarget(GrRecordingContext *context, const GrBackendRenderTarget &backendRenderTarget, GrSurfaceOrigin origin, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, RenderTargetReleaseProc releaseProc=nullptr, ReleaseContext releaseContext=nullptr)
@ kPresent
back-end surface will be used for presenting to screen
SK_API GrBackendTexture GetBackendTexture(SkSurface *, BackendHandleAccess)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
sk_sp< SkSurface > MakeBackendRenderTargetSurface(GrDirectContext *dContext, const SkImageInfo &ii, GrSurfaceOrigin origin, int sampleCnt, GrProtected isProtected, const SkSurfaceProps *props)
GrTextureProxy * GetTextureImageProxy(SkImage *image, GrRecordingContext *rContext)
sk_sp< SkSurface > MakeBackendTextureSurface(GrDirectContext *dContext, const SkImageInfo &ii, GrSurfaceOrigin origin, int sampleCnt, skgpu::Mipmapped mipmapped, GrProtected isProtected, const SkSurfaceProps *props)
SK_API bool DrawDDL(SkSurface *, sk_sp< const GrDeferredDisplayList > ddl)
Mipmapped
Definition GpuTypes.h:53
Protected
Definition GpuTypes.h:61
int32_t height
int32_t width
sk_sp< GrPromiseImageTexture > fTex
skgpu::Protected fProtected
Definition GrGLTypes.h:199
VkCommandBuffer fSecondaryCommandBuffer
Definition GrVkTypes.h:85
VkImageUsageFlags fImageUsageFlags
Definition GrVkTypes.h:31
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static void Release(void *self)
@ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
@ VK_FORMAT_R8G8B8A8_UNORM