1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkColor.h" 11cb93a386Sopenharmony_ci#include "include/core/SkColorSpace.h" 12cb93a386Sopenharmony_ci#include "include/core/SkDeferredDisplayList.h" 13cb93a386Sopenharmony_ci#include "include/core/SkDeferredDisplayListRecorder.h" 14cb93a386Sopenharmony_ci#include "include/core/SkImage.h" 15cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h" 16cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 17cb93a386Sopenharmony_ci#include "include/core/SkPromiseImageTexture.h" 18cb93a386Sopenharmony_ci#include "include/core/SkRect.h" 19cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h" 20cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 21cb93a386Sopenharmony_ci#include "include/core/SkSurfaceCharacterization.h" 22cb93a386Sopenharmony_ci#include "include/core/SkSurfaceProps.h" 23cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 24cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 25cb93a386Sopenharmony_ci#include "include/gpu/GrContextThreadSafeProxy.h" 26cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 27cb93a386Sopenharmony_ci#include "include/gpu/GrRecordingContext.h" 28cb93a386Sopenharmony_ci#include "include/gpu/GrTypes.h" 29cb93a386Sopenharmony_ci#include "include/gpu/gl/GrGLTypes.h" 30cb93a386Sopenharmony_ci#include "include/private/GrTypesPriv.h" 31cb93a386Sopenharmony_ci#include "src/core/SkDeferredDisplayListPriv.h" 32cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 33cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 34cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h" 35cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h" 36cb93a386Sopenharmony_ci#include "src/gpu/GrRenderTargetProxy.h" 37cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h" 38cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLDefines.h" 39cb93a386Sopenharmony_ci#include "src/image/SkImage_GpuBase.h" 40cb93a386Sopenharmony_ci#include "src/image/SkSurface_Gpu.h" 41cb93a386Sopenharmony_ci#include "tests/Test.h" 42cb93a386Sopenharmony_ci#include "tests/TestUtils.h" 43cb93a386Sopenharmony_ci#include "tools/gpu/BackendSurfaceFactory.h" 44cb93a386Sopenharmony_ci#include "tools/gpu/GrContextFactory.h" 45cb93a386Sopenharmony_ci#include "tools/gpu/ManagedBackendTexture.h" 46cb93a386Sopenharmony_ci#include "tools/gpu/ProxyUtils.h" 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci#include <initializer_list> 49cb93a386Sopenharmony_ci#include <memory> 50cb93a386Sopenharmony_ci#include <utility> 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci#ifdef SK_VULKAN 53cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkCaps.h" 54cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkSecondaryCBDrawContext.h" 55cb93a386Sopenharmony_ci#endif 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ciclass SurfaceParameters { 58cb93a386Sopenharmony_cipublic: 59cb93a386Sopenharmony_ci static const int kNumParams = 13; 60cb93a386Sopenharmony_ci static const int kFBO0Count = 9; 61cb93a386Sopenharmony_ci static const int kVkSCBCount = 12; 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci SurfaceParameters(GrRecordingContext* rContext) 64cb93a386Sopenharmony_ci : fBackend(rContext->backend()) 65cb93a386Sopenharmony_ci , fCanBeProtected(false) 66cb93a386Sopenharmony_ci , fWidth(64) 67cb93a386Sopenharmony_ci , fHeight(64) 68cb93a386Sopenharmony_ci , fOrigin(kTopLeft_GrSurfaceOrigin) 69cb93a386Sopenharmony_ci , fColorType(kRGBA_8888_SkColorType) 70cb93a386Sopenharmony_ci , fColorSpace(SkColorSpace::MakeSRGB()) 71cb93a386Sopenharmony_ci , fSampleCount(1) 72cb93a386Sopenharmony_ci , fSurfaceProps(0x0, kUnknown_SkPixelGeometry) 73cb93a386Sopenharmony_ci , fShouldCreateMipMaps(true) 74cb93a386Sopenharmony_ci , fUsesGLFBO0(false) 75cb93a386Sopenharmony_ci , fIsTextureable(true) 76cb93a386Sopenharmony_ci , fIsProtected(GrProtected::kNo) 77cb93a386Sopenharmony_ci , fVkRTSupportsInputAttachment(false) 78cb93a386Sopenharmony_ci , fForVulkanSecondaryCommandBuffer(false) { 79cb93a386Sopenharmony_ci#ifdef SK_VULKAN 80cb93a386Sopenharmony_ci if (rContext->backend() == GrBackendApi::kVulkan) { 81cb93a386Sopenharmony_ci auto vkCaps = static_cast<const GrVkCaps*>(rContext->priv().caps()); 82cb93a386Sopenharmony_ci fCanBeProtected = vkCaps->supportsProtectedMemory(); 83cb93a386Sopenharmony_ci if (fCanBeProtected) { 84cb93a386Sopenharmony_ci fIsProtected = GrProtected::kYes; 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci#endif 88cb93a386Sopenharmony_ci if (!rContext->priv().caps()->mipmapSupport()) { 89cb93a386Sopenharmony_ci fShouldCreateMipMaps = false; 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci } 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci int sampleCount() const { return fSampleCount; } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci void setColorType(SkColorType ct) { fColorType = ct; } 96cb93a386Sopenharmony_ci SkColorType colorType() const { return fColorType; } 97cb93a386Sopenharmony_ci void setColorSpace(sk_sp<SkColorSpace> cs) { fColorSpace = std::move(cs); } 98cb93a386Sopenharmony_ci void disableTextureability() { 99cb93a386Sopenharmony_ci fIsTextureable = false; 100cb93a386Sopenharmony_ci fShouldCreateMipMaps = false; 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci void setShouldCreateMipMaps(bool shouldCreateMipMaps) { 103cb93a386Sopenharmony_ci fShouldCreateMipMaps = shouldCreateMipMaps; 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci void setVkRTInputAttachmentSupport(bool inputSupport) { 106cb93a386Sopenharmony_ci fVkRTSupportsInputAttachment = inputSupport; 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci void setForVulkanSecondaryCommandBuffer(bool forVkSCB) { 109cb93a386Sopenharmony_ci fForVulkanSecondaryCommandBuffer = forVkSCB; 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci // Modify the SurfaceParameters in just one way. Returns false if the requested modification had 113cb93a386Sopenharmony_ci // no effect. 114cb93a386Sopenharmony_ci bool modify(int i) { 115cb93a386Sopenharmony_ci bool changed = false; 116cb93a386Sopenharmony_ci auto set = [&changed](auto& var, auto value) { 117cb93a386Sopenharmony_ci if (var != value) { 118cb93a386Sopenharmony_ci changed = true; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci var = value; 121cb93a386Sopenharmony_ci }; 122cb93a386Sopenharmony_ci switch (i) { 123cb93a386Sopenharmony_ci case 0: 124cb93a386Sopenharmony_ci set(fWidth, 63); 125cb93a386Sopenharmony_ci break; 126cb93a386Sopenharmony_ci case 1: 127cb93a386Sopenharmony_ci set(fHeight, 63); 128cb93a386Sopenharmony_ci break; 129cb93a386Sopenharmony_ci case 2: 130cb93a386Sopenharmony_ci set(fOrigin, kBottomLeft_GrSurfaceOrigin); 131cb93a386Sopenharmony_ci break; 132cb93a386Sopenharmony_ci case 3: 133cb93a386Sopenharmony_ci set(fColorType, kRGBA_F16_SkColorType); 134cb93a386Sopenharmony_ci break; 135cb93a386Sopenharmony_ci case 4: 136cb93a386Sopenharmony_ci // This just needs to be a colorSpace different from that returned by MakeSRGB(). 137cb93a386Sopenharmony_ci // In this case we just change the gamut. 138cb93a386Sopenharmony_ci set(fColorSpace, SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, 139cb93a386Sopenharmony_ci SkNamedGamut::kAdobeRGB)); 140cb93a386Sopenharmony_ci break; 141cb93a386Sopenharmony_ci case 5: 142cb93a386Sopenharmony_ci set(fSampleCount, 4); 143cb93a386Sopenharmony_ci break; 144cb93a386Sopenharmony_ci case 6: 145cb93a386Sopenharmony_ci set(fSurfaceProps, SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry)); 146cb93a386Sopenharmony_ci break; 147cb93a386Sopenharmony_ci case 7: 148cb93a386Sopenharmony_ci set(fSurfaceProps, SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag, 149cb93a386Sopenharmony_ci kUnknown_SkPixelGeometry)); 150cb93a386Sopenharmony_ci break; 151cb93a386Sopenharmony_ci case 8: 152cb93a386Sopenharmony_ci set(fShouldCreateMipMaps, false); 153cb93a386Sopenharmony_ci break; 154cb93a386Sopenharmony_ci case 9: 155cb93a386Sopenharmony_ci if (GrBackendApi::kOpenGL == fBackend) { 156cb93a386Sopenharmony_ci set(fUsesGLFBO0, true); 157cb93a386Sopenharmony_ci set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability 158cb93a386Sopenharmony_ci set(fIsTextureable, false); 159cb93a386Sopenharmony_ci } 160cb93a386Sopenharmony_ci break; 161cb93a386Sopenharmony_ci case 10: 162cb93a386Sopenharmony_ci set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability 163cb93a386Sopenharmony_ci set(fIsTextureable, false); 164cb93a386Sopenharmony_ci break; 165cb93a386Sopenharmony_ci case 11: 166cb93a386Sopenharmony_ci if (fCanBeProtected) { 167cb93a386Sopenharmony_ci set(fIsProtected, GrProtected(!static_cast<bool>(fIsProtected))); 168cb93a386Sopenharmony_ci } 169cb93a386Sopenharmony_ci break; 170cb93a386Sopenharmony_ci case 12: 171cb93a386Sopenharmony_ci if (GrBackendApi::kVulkan == fBackend) { 172cb93a386Sopenharmony_ci set(fForVulkanSecondaryCommandBuffer, true); 173cb93a386Sopenharmony_ci set(fUsesGLFBO0, false); 174cb93a386Sopenharmony_ci set(fShouldCreateMipMaps, false); // needs to changed in tandem w/ textureability 175cb93a386Sopenharmony_ci set(fIsTextureable, false); 176cb93a386Sopenharmony_ci set(fVkRTSupportsInputAttachment, false); 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci break; 179cb93a386Sopenharmony_ci } 180cb93a386Sopenharmony_ci return changed; 181cb93a386Sopenharmony_ci } 182cb93a386Sopenharmony_ci 183cb93a386Sopenharmony_ci SkSurfaceCharacterization createCharacterization(GrDirectContext* dContext) const { 184cb93a386Sopenharmony_ci size_t maxResourceBytes = dContext->getResourceCacheLimit(); 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_ci if (!dContext->colorTypeSupportedAsSurface(fColorType)) { 187cb93a386Sopenharmony_ci return SkSurfaceCharacterization(); 188cb93a386Sopenharmony_ci } 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ci // Note that Ganesh doesn't make use of the SkImageInfo's alphaType 191cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType, 192cb93a386Sopenharmony_ci kPremul_SkAlphaType, fColorSpace); 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_ci GrBackendFormat backendFormat = dContext->defaultBackendFormat(fColorType, 195cb93a386Sopenharmony_ci GrRenderable::kYes); 196cb93a386Sopenharmony_ci if (!backendFormat.isValid()) { 197cb93a386Sopenharmony_ci return SkSurfaceCharacterization(); 198cb93a386Sopenharmony_ci } 199cb93a386Sopenharmony_ci 200cb93a386Sopenharmony_ci SkSurfaceCharacterization c = dContext->threadSafeProxy()->createCharacterization( 201cb93a386Sopenharmony_ci maxResourceBytes, ii, backendFormat, fSampleCount, 202cb93a386Sopenharmony_ci fOrigin, fSurfaceProps, fShouldCreateMipMaps, 203cb93a386Sopenharmony_ci fUsesGLFBO0, fIsTextureable, fIsProtected, 204cb93a386Sopenharmony_ci fVkRTSupportsInputAttachment, 205cb93a386Sopenharmony_ci fForVulkanSecondaryCommandBuffer); 206cb93a386Sopenharmony_ci return c; 207cb93a386Sopenharmony_ci } 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci // Create a DDL whose characterization captures the current settings 210cb93a386Sopenharmony_ci sk_sp<SkDeferredDisplayList> createDDL(GrDirectContext* dContext) const { 211cb93a386Sopenharmony_ci SkSurfaceCharacterization c = this->createCharacterization(dContext); 212cb93a386Sopenharmony_ci SkAssertResult(c.isValid()); 213cb93a386Sopenharmony_ci 214cb93a386Sopenharmony_ci SkDeferredDisplayListRecorder r(c); 215cb93a386Sopenharmony_ci SkCanvas* canvas = r.getCanvas(); 216cb93a386Sopenharmony_ci if (!canvas) { 217cb93a386Sopenharmony_ci return nullptr; 218cb93a386Sopenharmony_ci } 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ci canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint()); 221cb93a386Sopenharmony_ci return r.detach(); 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci 224cb93a386Sopenharmony_ci // Create the surface with the current set of parameters 225cb93a386Sopenharmony_ci sk_sp<SkSurface> make(GrDirectContext* dContext) const { 226cb93a386Sopenharmony_ci const SkSurfaceCharacterization c = this->createCharacterization(dContext); 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_ci#ifdef SK_GL 229cb93a386Sopenharmony_ci if (fUsesGLFBO0) { 230cb93a386Sopenharmony_ci if (GrBackendApi::kOpenGL != dContext->backend()) { 231cb93a386Sopenharmony_ci return nullptr; 232cb93a386Sopenharmony_ci } 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_ci GrGLFramebufferInfo fboInfo; 235cb93a386Sopenharmony_ci fboInfo.fFBOID = 0; 236cb93a386Sopenharmony_ci fboInfo.fFormat = GR_GL_RGBA8; 237cb93a386Sopenharmony_ci static constexpr int kStencilBits = 8; 238cb93a386Sopenharmony_ci GrBackendRenderTarget backendRT(fWidth, fHeight, 1, kStencilBits, fboInfo); 239cb93a386Sopenharmony_ci 240cb93a386Sopenharmony_ci if (!backendRT.isValid()) { 241cb93a386Sopenharmony_ci return nullptr; 242cb93a386Sopenharmony_ci } 243cb93a386Sopenharmony_ci 244cb93a386Sopenharmony_ci sk_sp<SkSurface> result = SkSurface::MakeFromBackendRenderTarget(dContext, backendRT, 245cb93a386Sopenharmony_ci fOrigin, fColorType, 246cb93a386Sopenharmony_ci fColorSpace, 247cb93a386Sopenharmony_ci &fSurfaceProps); 248cb93a386Sopenharmony_ci SkASSERT(result->isCompatible(c)); 249cb93a386Sopenharmony_ci return result; 250cb93a386Sopenharmony_ci } 251cb93a386Sopenharmony_ci#endif 252cb93a386Sopenharmony_ci 253cb93a386Sopenharmony_ci // We can't make SkSurfaces for vulkan secondary command buffers. 254cb93a386Sopenharmony_ci if (fForVulkanSecondaryCommandBuffer) { 255cb93a386Sopenharmony_ci return nullptr; 256cb93a386Sopenharmony_ci } 257cb93a386Sopenharmony_ci 258cb93a386Sopenharmony_ci sk_sp<SkSurface> surface; 259cb93a386Sopenharmony_ci if (fIsTextureable) { 260cb93a386Sopenharmony_ci surface = sk_gpu_test::MakeBackendTextureSurface(dContext, 261cb93a386Sopenharmony_ci {fWidth, fHeight}, 262cb93a386Sopenharmony_ci fOrigin, 263cb93a386Sopenharmony_ci fSampleCount, 264cb93a386Sopenharmony_ci fColorType, 265cb93a386Sopenharmony_ci fColorSpace, 266cb93a386Sopenharmony_ci GrMipmapped(fShouldCreateMipMaps), 267cb93a386Sopenharmony_ci fIsProtected, 268cb93a386Sopenharmony_ci &fSurfaceProps); 269cb93a386Sopenharmony_ci } else { 270cb93a386Sopenharmony_ci // Create a surface w/ the current parameters but make it non-textureable 271cb93a386Sopenharmony_ci SkASSERT(!fShouldCreateMipMaps); 272cb93a386Sopenharmony_ci surface = sk_gpu_test::MakeBackendRenderTargetSurface(dContext, 273cb93a386Sopenharmony_ci {fWidth, fHeight}, 274cb93a386Sopenharmony_ci fOrigin, 275cb93a386Sopenharmony_ci fSampleCount, 276cb93a386Sopenharmony_ci fColorType, 277cb93a386Sopenharmony_ci fColorSpace, 278cb93a386Sopenharmony_ci fIsProtected, 279cb93a386Sopenharmony_ci &fSurfaceProps); 280cb93a386Sopenharmony_ci } 281cb93a386Sopenharmony_ci 282cb93a386Sopenharmony_ci if (!surface) { 283cb93a386Sopenharmony_ci SkASSERT(!c.isValid()); 284cb93a386Sopenharmony_ci return nullptr; 285cb93a386Sopenharmony_ci } 286cb93a386Sopenharmony_ci 287cb93a386Sopenharmony_ci GrBackendTexture texture = 288cb93a386Sopenharmony_ci surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess); 289cb93a386Sopenharmony_ci if (texture.isValid()) { 290cb93a386Sopenharmony_ci SkASSERT(c.isCompatible(texture)); 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci SkASSERT(c.isValid()); 293cb93a386Sopenharmony_ci SkASSERT(surface->isCompatible(c)); 294cb93a386Sopenharmony_ci return surface; 295cb93a386Sopenharmony_ci } 296cb93a386Sopenharmony_ci 297cb93a386Sopenharmony_ci#ifdef SK_VULKAN 298cb93a386Sopenharmony_ci sk_sp<GrVkSecondaryCBDrawContext> makeVkSCB(GrDirectContext* dContext) { 299cb93a386Sopenharmony_ci const SkSurfaceCharacterization c = this->createCharacterization(dContext); 300cb93a386Sopenharmony_ci SkImageInfo imageInfo = SkImageInfo::Make({fWidth, fHeight}, 301cb93a386Sopenharmony_ci {fColorType, kPremul_SkAlphaType, fColorSpace}); 302cb93a386Sopenharmony_ci GrVkDrawableInfo vkInfo; 303cb93a386Sopenharmony_ci // putting in a bunch of placeholder values here 304cb93a386Sopenharmony_ci vkInfo.fSecondaryCommandBuffer = (VkCommandBuffer)1; 305cb93a386Sopenharmony_ci vkInfo.fColorAttachmentIndex = 0; 306cb93a386Sopenharmony_ci vkInfo.fCompatibleRenderPass = (VkRenderPass)1; 307cb93a386Sopenharmony_ci vkInfo.fFormat = VK_FORMAT_R8G8B8A8_UNORM; 308cb93a386Sopenharmony_ci vkInfo.fDrawBounds = nullptr; 309cb93a386Sopenharmony_ci vkInfo.fImage = (VkImage)1; 310cb93a386Sopenharmony_ci 311cb93a386Sopenharmony_ci return GrVkSecondaryCBDrawContext::Make(dContext, imageInfo, vkInfo, &fSurfaceProps); 312cb93a386Sopenharmony_ci } 313cb93a386Sopenharmony_ci#endif 314cb93a386Sopenharmony_ci 315cb93a386Sopenharmony_ciprivate: 316cb93a386Sopenharmony_ci GrBackendApi fBackend; 317cb93a386Sopenharmony_ci bool fCanBeProtected; 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ci int fWidth; 320cb93a386Sopenharmony_ci int fHeight; 321cb93a386Sopenharmony_ci GrSurfaceOrigin fOrigin; 322cb93a386Sopenharmony_ci SkColorType fColorType; 323cb93a386Sopenharmony_ci sk_sp<SkColorSpace> fColorSpace; 324cb93a386Sopenharmony_ci int fSampleCount; 325cb93a386Sopenharmony_ci SkSurfaceProps fSurfaceProps; 326cb93a386Sopenharmony_ci bool fShouldCreateMipMaps; 327cb93a386Sopenharmony_ci bool fUsesGLFBO0; 328cb93a386Sopenharmony_ci bool fIsTextureable; 329cb93a386Sopenharmony_ci GrProtected fIsProtected; 330cb93a386Sopenharmony_ci bool fVkRTSupportsInputAttachment; 331cb93a386Sopenharmony_ci bool fForVulkanSecondaryCommandBuffer; 332cb93a386Sopenharmony_ci}; 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_ci// Test out operator== && operator!= 335cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLOperatorEqTest, reporter, ctxInfo) { 336cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_ci for (int i = -1; i < SurfaceParameters::kNumParams; ++i) { 339cb93a386Sopenharmony_ci SurfaceParameters params1(context); 340cb93a386Sopenharmony_ci bool didModify1 = i >= 0 && params1.modify(i); 341cb93a386Sopenharmony_ci 342cb93a386Sopenharmony_ci SkSurfaceCharacterization char1 = params1.createCharacterization(context); 343cb93a386Sopenharmony_ci if (!char1.isValid()) { 344cb93a386Sopenharmony_ci continue; // can happen on some platforms (ChromeOS) 345cb93a386Sopenharmony_ci } 346cb93a386Sopenharmony_ci 347cb93a386Sopenharmony_ci for (int j = -1; j < SurfaceParameters::kNumParams; ++j) { 348cb93a386Sopenharmony_ci SurfaceParameters params2(context); 349cb93a386Sopenharmony_ci bool didModify2 = j >= 0 && params2.modify(j); 350cb93a386Sopenharmony_ci 351cb93a386Sopenharmony_ci SkSurfaceCharacterization char2 = params2.createCharacterization(context); 352cb93a386Sopenharmony_ci if (!char2.isValid()) { 353cb93a386Sopenharmony_ci continue; // can happen on some platforms (ChromeOS) 354cb93a386Sopenharmony_ci } 355cb93a386Sopenharmony_ci 356cb93a386Sopenharmony_ci if (i == j || (!didModify1 && !didModify2)) { 357cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1 == char2); 358cb93a386Sopenharmony_ci } else { 359cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1 != char2); 360cb93a386Sopenharmony_ci } 361cb93a386Sopenharmony_ci } 362cb93a386Sopenharmony_ci } 363cb93a386Sopenharmony_ci 364cb93a386Sopenharmony_ci { 365cb93a386Sopenharmony_ci SurfaceParameters params(context); 366cb93a386Sopenharmony_ci 367cb93a386Sopenharmony_ci SkSurfaceCharacterization valid = params.createCharacterization(context); 368cb93a386Sopenharmony_ci SkASSERT(valid.isValid()); 369cb93a386Sopenharmony_ci 370cb93a386Sopenharmony_ci SkSurfaceCharacterization inval1, inval2; 371cb93a386Sopenharmony_ci SkASSERT(!inval1.isValid() && !inval2.isValid()); 372cb93a386Sopenharmony_ci 373cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, inval1 != inval2); 374cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, valid != inval1); 375cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, inval1 != valid); 376cb93a386Sopenharmony_ci } 377cb93a386Sopenharmony_ci} 378cb93a386Sopenharmony_ci 379cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 380cb93a386Sopenharmony_ci// This tests SkSurfaceCharacterization/SkSurface compatibility 381cb93a386Sopenharmony_civoid DDLSurfaceCharacterizationTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) { 382cb93a386Sopenharmony_ci // Create a bitmap that we can readback into 383cb93a386Sopenharmony_ci SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, 384cb93a386Sopenharmony_ci kPremul_SkAlphaType); 385cb93a386Sopenharmony_ci SkBitmap bitmap; 386cb93a386Sopenharmony_ci bitmap.allocPixels(imageInfo); 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci sk_sp<SkDeferredDisplayList> ddl; 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_ci // First, create a DDL using the stock SkSurface parameters 391cb93a386Sopenharmony_ci { 392cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 393cb93a386Sopenharmony_ci if (dContext->backend() == GrBackendApi::kVulkan) { 394cb93a386Sopenharmony_ci params.setVkRTInputAttachmentSupport(true); 395cb93a386Sopenharmony_ci } 396cb93a386Sopenharmony_ci ddl = params.createDDL(dContext); 397cb93a386Sopenharmony_ci SkAssertResult(ddl); 398cb93a386Sopenharmony_ci 399cb93a386Sopenharmony_ci // The DDL should draw into an SkSurface created with the same parameters 400cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 401cb93a386Sopenharmony_ci if (!s) { 402cb93a386Sopenharmony_ci return; 403cb93a386Sopenharmony_ci } 404cb93a386Sopenharmony_ci 405cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s->draw(ddl)); 406cb93a386Sopenharmony_ci s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); 407cb93a386Sopenharmony_ci 408cb93a386Sopenharmony_ci dContext->flush(); 409cb93a386Sopenharmony_ci } 410cb93a386Sopenharmony_ci 411cb93a386Sopenharmony_ci // Then, alter each parameter in turn and check that the DDL & surface are incompatible 412cb93a386Sopenharmony_ci for (int i = 0; i < SurfaceParameters::kNumParams; ++i) { 413cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 414cb93a386Sopenharmony_ci if (!params.modify(i)) { 415cb93a386Sopenharmony_ci continue; 416cb93a386Sopenharmony_ci } 417cb93a386Sopenharmony_ci 418cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 419cb93a386Sopenharmony_ci if (!s) { 420cb93a386Sopenharmony_ci continue; 421cb93a386Sopenharmony_ci } 422cb93a386Sopenharmony_ci 423cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !s->draw(ddl), 424cb93a386Sopenharmony_ci "DDLSurfaceCharacterizationTest failed on parameter: %d\n", i); 425cb93a386Sopenharmony_ci dContext->flush(); 426cb93a386Sopenharmony_ci } 427cb93a386Sopenharmony_ci 428cb93a386Sopenharmony_ci // Next test the compatibility of resource cache parameters 429cb93a386Sopenharmony_ci { 430cb93a386Sopenharmony_ci const SurfaceParameters params(dContext); 431cb93a386Sopenharmony_ci 432cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 433cb93a386Sopenharmony_ci 434cb93a386Sopenharmony_ci size_t maxResourceBytes = dContext->getResourceCacheLimit(); 435cb93a386Sopenharmony_ci 436cb93a386Sopenharmony_ci dContext->setResourceCacheLimit(maxResourceBytes/2); 437cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !s->draw(ddl)); 438cb93a386Sopenharmony_ci 439cb93a386Sopenharmony_ci // DDL TODO: once proxies/ops can be de-instantiated we can re-enable these tests. 440cb93a386Sopenharmony_ci // For now, DDLs are drawn once. 441cb93a386Sopenharmony_ci#if 0 442cb93a386Sopenharmony_ci // resource limits >= those at characterization time are accepted 443cb93a386Sopenharmony_ci context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes); 444cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s->draw(ddl)); 445cb93a386Sopenharmony_ci s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); 446cb93a386Sopenharmony_ci 447cb93a386Sopenharmony_ci context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes); 448cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s->draw(ddl)); 449cb93a386Sopenharmony_ci s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); 450cb93a386Sopenharmony_ci 451cb93a386Sopenharmony_ci context->setResourceCacheLimits(maxResourceCount, maxResourceBytes); 452cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s->draw(ddl)); 453cb93a386Sopenharmony_ci s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); 454cb93a386Sopenharmony_ci#endif 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_ci dContext->flush(); 457cb93a386Sopenharmony_ci } 458cb93a386Sopenharmony_ci 459cb93a386Sopenharmony_ci // Test that the textureability of the DDL characterization can block a DDL draw 460cb93a386Sopenharmony_ci { 461cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 462cb93a386Sopenharmony_ci params.disableTextureability(); 463cb93a386Sopenharmony_ci 464cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 465cb93a386Sopenharmony_ci if (s) { 466cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !s->draw(ddl)); // bc the DDL was made w/ textureability 467cb93a386Sopenharmony_ci 468cb93a386Sopenharmony_ci dContext->flush(); 469cb93a386Sopenharmony_ci } 470cb93a386Sopenharmony_ci } 471cb93a386Sopenharmony_ci 472cb93a386Sopenharmony_ci // Make sure non-GPU-backed surfaces fail characterization 473cb93a386Sopenharmony_ci { 474cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType); 475cb93a386Sopenharmony_ci 476cb93a386Sopenharmony_ci sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii); 477cb93a386Sopenharmony_ci SkSurfaceCharacterization c; 478cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c)); 479cb93a386Sopenharmony_ci } 480cb93a386Sopenharmony_ci 481cb93a386Sopenharmony_ci // Exercise the createResized method 482cb93a386Sopenharmony_ci { 483cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 484cb93a386Sopenharmony_ci 485cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 486cb93a386Sopenharmony_ci if (!s) { 487cb93a386Sopenharmony_ci return; 488cb93a386Sopenharmony_ci } 489cb93a386Sopenharmony_ci 490cb93a386Sopenharmony_ci SkSurfaceCharacterization char0; 491cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&char0)); 492cb93a386Sopenharmony_ci 493cb93a386Sopenharmony_ci // Too small 494cb93a386Sopenharmony_ci SkSurfaceCharacterization char1 = char0.createResized(-1, -1); 495cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !char1.isValid()); 496cb93a386Sopenharmony_ci 497cb93a386Sopenharmony_ci // Too large 498cb93a386Sopenharmony_ci SkSurfaceCharacterization char2 = char0.createResized(1000000, 32); 499cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !char2.isValid()); 500cb93a386Sopenharmony_ci 501cb93a386Sopenharmony_ci // Just right 502cb93a386Sopenharmony_ci SkSurfaceCharacterization char3 = char0.createResized(32, 32); 503cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char3.isValid()); 504cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 32 == char3.width()); 505cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 32 == char3.height()); 506cb93a386Sopenharmony_ci } 507cb93a386Sopenharmony_ci 508cb93a386Sopenharmony_ci // Exercise the createColorSpace method 509cb93a386Sopenharmony_ci { 510cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 511cb93a386Sopenharmony_ci 512cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 513cb93a386Sopenharmony_ci if (!s) { 514cb93a386Sopenharmony_ci return; 515cb93a386Sopenharmony_ci } 516cb93a386Sopenharmony_ci 517cb93a386Sopenharmony_ci SkSurfaceCharacterization char0; 518cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&char0)); 519cb93a386Sopenharmony_ci 520cb93a386Sopenharmony_ci // The default params create an sRGB color space 521cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char0.colorSpace()->isSRGB()); 522cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !char0.colorSpace()->gammaIsLinear()); 523cb93a386Sopenharmony_ci 524cb93a386Sopenharmony_ci { 525cb93a386Sopenharmony_ci sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear(); 526cb93a386Sopenharmony_ci 527cb93a386Sopenharmony_ci SkSurfaceCharacterization char1 = char0.createColorSpace(std::move(newCS)); 528cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1.isValid()); 529cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !char1.colorSpace()->isSRGB()); 530cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1.colorSpace()->gammaIsLinear()); 531cb93a386Sopenharmony_ci } 532cb93a386Sopenharmony_ci 533cb93a386Sopenharmony_ci { 534cb93a386Sopenharmony_ci SkSurfaceCharacterization char2 = char0.createColorSpace(nullptr); 535cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char2.isValid()); 536cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !char2.colorSpace()); 537cb93a386Sopenharmony_ci } 538cb93a386Sopenharmony_ci 539cb93a386Sopenharmony_ci { 540cb93a386Sopenharmony_ci sk_sp<SkColorSpace> newCS = SkColorSpace::MakeSRGBLinear(); 541cb93a386Sopenharmony_ci 542cb93a386Sopenharmony_ci SkSurfaceCharacterization invalid; 543cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !invalid.isValid()); 544cb93a386Sopenharmony_ci SkSurfaceCharacterization stillInvalid = invalid.createColorSpace(std::move(newCS)); 545cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !stillInvalid.isValid()); 546cb93a386Sopenharmony_ci } 547cb93a386Sopenharmony_ci } 548cb93a386Sopenharmony_ci 549cb93a386Sopenharmony_ci // Exercise the createBackendFormat method 550cb93a386Sopenharmony_ci { 551cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 552cb93a386Sopenharmony_ci 553cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 554cb93a386Sopenharmony_ci if (!s) { 555cb93a386Sopenharmony_ci return; 556cb93a386Sopenharmony_ci } 557cb93a386Sopenharmony_ci 558cb93a386Sopenharmony_ci SkSurfaceCharacterization char0; 559cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&char0)); 560cb93a386Sopenharmony_ci 561cb93a386Sopenharmony_ci // The default params create a renderable RGBA8 surface 562cb93a386Sopenharmony_ci auto originalBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType, 563cb93a386Sopenharmony_ci GrRenderable::kYes); 564cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, originalBackendFormat.isValid()); 565cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char0.backendFormat() == originalBackendFormat); 566cb93a386Sopenharmony_ci 567cb93a386Sopenharmony_ci auto newBackendFormat = dContext->defaultBackendFormat(kRGB_565_SkColorType, 568cb93a386Sopenharmony_ci GrRenderable::kYes); 569cb93a386Sopenharmony_ci 570cb93a386Sopenharmony_ci if (newBackendFormat.isValid()) { 571cb93a386Sopenharmony_ci SkSurfaceCharacterization char1 = char0.createBackendFormat(kRGB_565_SkColorType, 572cb93a386Sopenharmony_ci newBackendFormat); 573cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1.isValid()); 574cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1.backendFormat() == newBackendFormat); 575cb93a386Sopenharmony_ci 576cb93a386Sopenharmony_ci SkSurfaceCharacterization invalid; 577cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !invalid.isValid()); 578cb93a386Sopenharmony_ci auto stillInvalid = invalid.createBackendFormat(kRGB_565_SkColorType, 579cb93a386Sopenharmony_ci newBackendFormat); 580cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !stillInvalid.isValid()); 581cb93a386Sopenharmony_ci } 582cb93a386Sopenharmony_ci } 583cb93a386Sopenharmony_ci 584cb93a386Sopenharmony_ci // Exercise the createFBO0 method 585cb93a386Sopenharmony_ci if (dContext->backend() == GrBackendApi::kOpenGL) { 586cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 587cb93a386Sopenharmony_ci // If the original characterization is textureable then we will fail trying to make an 588cb93a386Sopenharmony_ci // FBO0 characterization 589cb93a386Sopenharmony_ci params.disableTextureability(); 590cb93a386Sopenharmony_ci 591cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 592cb93a386Sopenharmony_ci if (!s) { 593cb93a386Sopenharmony_ci return; 594cb93a386Sopenharmony_ci } 595cb93a386Sopenharmony_ci 596cb93a386Sopenharmony_ci SkSurfaceCharacterization char0; 597cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&char0)); 598cb93a386Sopenharmony_ci 599cb93a386Sopenharmony_ci // The default params create a non-FBO0 surface 600cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !char0.usesGLFBO0()); 601cb93a386Sopenharmony_ci 602cb93a386Sopenharmony_ci { 603cb93a386Sopenharmony_ci SkSurfaceCharacterization char1 = char0.createFBO0(true); 604cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1.isValid()); 605cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, char1.usesGLFBO0()); 606cb93a386Sopenharmony_ci } 607cb93a386Sopenharmony_ci 608cb93a386Sopenharmony_ci { 609cb93a386Sopenharmony_ci SkSurfaceCharacterization invalid; 610cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !invalid.isValid()); 611cb93a386Sopenharmony_ci SkSurfaceCharacterization stillInvalid = invalid.createFBO0(true); 612cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !stillInvalid.isValid()); 613cb93a386Sopenharmony_ci } 614cb93a386Sopenharmony_ci } 615cb93a386Sopenharmony_ci} 616cb93a386Sopenharmony_ci 617cb93a386Sopenharmony_ci#ifdef SK_GL 618cb93a386Sopenharmony_ci 619cb93a386Sopenharmony_ci// Test out the surface compatibility checks regarding FBO0-ness. This test constructs 620cb93a386Sopenharmony_ci// two parallel arrays of characterizations and surfaces in the order: 621cb93a386Sopenharmony_ci// FBO0 w/ MSAA, FBO0 w/o MSAA, not-FBO0 w/ MSAA, not-FBO0 w/o MSAA 622cb93a386Sopenharmony_ci// and then tries all sixteen combinations to check the expected compatibility. 623cb93a386Sopenharmony_ci// Note: this is a GL-only test 624cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(CharacterizationFBO0nessTest, reporter, ctxInfo) { 625cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 626cb93a386Sopenharmony_ci const GrCaps* caps = context->priv().caps(); 627cb93a386Sopenharmony_ci sk_sp<GrContextThreadSafeProxy> proxy = context->threadSafeProxy(); 628cb93a386Sopenharmony_ci const size_t resourceCacheLimit = context->getResourceCacheLimit(); 629cb93a386Sopenharmony_ci 630cb93a386Sopenharmony_ci GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_2D); 631cb93a386Sopenharmony_ci 632cb93a386Sopenharmony_ci int availableSamples = caps->getRenderTargetSampleCount(4, format); 633cb93a386Sopenharmony_ci if (availableSamples <= 1) { 634cb93a386Sopenharmony_ci // This context doesn't support MSAA for RGBA8 635cb93a386Sopenharmony_ci return; 636cb93a386Sopenharmony_ci } 637cb93a386Sopenharmony_ci 638cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::Make({ 128, 128 }, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 639cb93a386Sopenharmony_ci 640cb93a386Sopenharmony_ci static constexpr int kStencilBits = 8; 641cb93a386Sopenharmony_ci static constexpr bool kNotMipMapped = false; 642cb93a386Sopenharmony_ci static constexpr bool kNotTextureable = false; 643cb93a386Sopenharmony_ci const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry); 644cb93a386Sopenharmony_ci 645cb93a386Sopenharmony_ci // Rows are characterizations and columns are surfaces 646cb93a386Sopenharmony_ci static const bool kExpectedCompatibility[4][4] = { 647cb93a386Sopenharmony_ci // FBO0 & MSAA, FBO0 & not-MSAA, not-FBO0 & MSAA, not-FBO0 & not-MSAA 648cb93a386Sopenharmony_ci/* FBO0 & MSAA */ { true, false, false, false }, 649cb93a386Sopenharmony_ci/* FBO0 & not-MSAA */ { false, true, false, true }, 650cb93a386Sopenharmony_ci/* not-FBO0 & MSAA */ { false, false, true, false }, 651cb93a386Sopenharmony_ci/* not-FBO0 & not- */ { false, false, false, true } 652cb93a386Sopenharmony_ci }; 653cb93a386Sopenharmony_ci 654cb93a386Sopenharmony_ci SkSurfaceCharacterization characterizations[4]; 655cb93a386Sopenharmony_ci sk_sp<SkSurface> surfaces[4]; 656cb93a386Sopenharmony_ci 657cb93a386Sopenharmony_ci int index = 0; 658cb93a386Sopenharmony_ci for (bool isFBO0 : { true, false }) { 659cb93a386Sopenharmony_ci for (int numSamples : { availableSamples, 1 }) { 660cb93a386Sopenharmony_ci characterizations[index] = proxy->createCharacterization(resourceCacheLimit, 661cb93a386Sopenharmony_ci ii, format, numSamples, 662cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 663cb93a386Sopenharmony_ci surfaceProps, kNotMipMapped, 664cb93a386Sopenharmony_ci isFBO0, kNotTextureable); 665cb93a386Sopenharmony_ci SkASSERT(characterizations[index].sampleCount() == numSamples); 666cb93a386Sopenharmony_ci SkASSERT(characterizations[index].usesGLFBO0() == isFBO0); 667cb93a386Sopenharmony_ci 668cb93a386Sopenharmony_ci GrGLFramebufferInfo fboInfo{ isFBO0 ? 0 : (GrGLuint) 1, GR_GL_RGBA8 }; 669cb93a386Sopenharmony_ci GrBackendRenderTarget backendRT(128, 128, numSamples, kStencilBits, fboInfo); 670cb93a386Sopenharmony_ci SkAssertResult(backendRT.isValid()); 671cb93a386Sopenharmony_ci 672cb93a386Sopenharmony_ci surfaces[index] = SkSurface::MakeFromBackendRenderTarget(context, backendRT, 673cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 674cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 675cb93a386Sopenharmony_ci nullptr, &surfaceProps); 676cb93a386Sopenharmony_ci ++index; 677cb93a386Sopenharmony_ci } 678cb93a386Sopenharmony_ci } 679cb93a386Sopenharmony_ci 680cb93a386Sopenharmony_ci for (int c = 0; c < 4; ++c) { 681cb93a386Sopenharmony_ci for (int s = 0; s < 4; ++s) { 682cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 683cb93a386Sopenharmony_ci kExpectedCompatibility[c][s] == 684cb93a386Sopenharmony_ci surfaces[s]->isCompatible(characterizations[c])); 685cb93a386Sopenharmony_ci } 686cb93a386Sopenharmony_ci } 687cb93a386Sopenharmony_ci} 688cb93a386Sopenharmony_ci#endif 689cb93a386Sopenharmony_ci 690cb93a386Sopenharmony_ci#ifdef SK_VULKAN 691cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_VULKAN_CONTEXT(CharacterizationVkSCBnessTest, reporter, ctxInfo) { 692cb93a386Sopenharmony_ci auto dContext = ctxInfo.directContext(); 693cb93a386Sopenharmony_ci 694cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 695cb93a386Sopenharmony_ci params.modify(SurfaceParameters::kVkSCBCount); 696cb93a386Sopenharmony_ci SkSurfaceCharacterization characterization = params.createCharacterization(dContext); 697cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, characterization.isValid()); 698cb93a386Sopenharmony_ci 699cb93a386Sopenharmony_ci sk_sp<SkDeferredDisplayList> ddl = params.createDDL(dContext); 700cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, ddl.get()); 701cb93a386Sopenharmony_ci 702cb93a386Sopenharmony_ci sk_sp<GrVkSecondaryCBDrawContext> scbDrawContext = params.makeVkSCB(dContext); 703cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, scbDrawContext->isCompatible(characterization)); 704cb93a386Sopenharmony_ci 705cb93a386Sopenharmony_ci scbDrawContext->releaseResources(); 706cb93a386Sopenharmony_ci} 707cb93a386Sopenharmony_ci#endif 708cb93a386Sopenharmony_ci 709cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSurfaceCharacterizationTest, reporter, ctxInfo) { 710cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 711cb93a386Sopenharmony_ci 712cb93a386Sopenharmony_ci DDLSurfaceCharacterizationTestImpl(context, reporter); 713cb93a386Sopenharmony_ci} 714cb93a386Sopenharmony_ci 715cb93a386Sopenharmony_ci// Test that a DDL created w/o textureability can be replayed into both a textureable and 716cb93a386Sopenharmony_ci// non-textureable destination. Note that DDLSurfaceCharacterizationTest tests that a 717cb93a386Sopenharmony_ci// textureable DDL cannot be played into a non-textureable destination but can be replayed 718cb93a386Sopenharmony_ci// into a textureable destination. 719cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLNonTextureabilityTest, reporter, ctxInfo) { 720cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 721cb93a386Sopenharmony_ci 722cb93a386Sopenharmony_ci // Create a bitmap that we can readback into 723cb93a386Sopenharmony_ci SkImageInfo imageInfo = SkImageInfo::Make(64, 64, kRGBA_8888_SkColorType, 724cb93a386Sopenharmony_ci kPremul_SkAlphaType); 725cb93a386Sopenharmony_ci SkBitmap bitmap; 726cb93a386Sopenharmony_ci bitmap.allocPixels(imageInfo); 727cb93a386Sopenharmony_ci 728cb93a386Sopenharmony_ci for (bool textureability : { true, false }) { 729cb93a386Sopenharmony_ci sk_sp<SkDeferredDisplayList> ddl; 730cb93a386Sopenharmony_ci 731cb93a386Sopenharmony_ci // First, create a DDL w/o textureability (and thus no mipmaps). TODO: once we have 732cb93a386Sopenharmony_ci // reusable DDLs, move this outside of the loop. 733cb93a386Sopenharmony_ci { 734cb93a386Sopenharmony_ci SurfaceParameters params(context); 735cb93a386Sopenharmony_ci params.disableTextureability(); 736cb93a386Sopenharmony_ci if (context->backend() == GrBackendApi::kVulkan) { 737cb93a386Sopenharmony_ci params.setVkRTInputAttachmentSupport(true); 738cb93a386Sopenharmony_ci } 739cb93a386Sopenharmony_ci 740cb93a386Sopenharmony_ci ddl = params.createDDL(context); 741cb93a386Sopenharmony_ci SkAssertResult(ddl); 742cb93a386Sopenharmony_ci } 743cb93a386Sopenharmony_ci 744cb93a386Sopenharmony_ci // Then verify it can draw into either flavor of destination 745cb93a386Sopenharmony_ci SurfaceParameters params(context); 746cb93a386Sopenharmony_ci if (!textureability) { 747cb93a386Sopenharmony_ci params.disableTextureability(); 748cb93a386Sopenharmony_ci } 749cb93a386Sopenharmony_ci if (context->backend() == GrBackendApi::kVulkan) { 750cb93a386Sopenharmony_ci params.setVkRTInputAttachmentSupport(true); 751cb93a386Sopenharmony_ci } 752cb93a386Sopenharmony_ci 753cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(context); 754cb93a386Sopenharmony_ci if (!s) { 755cb93a386Sopenharmony_ci continue; 756cb93a386Sopenharmony_ci } 757cb93a386Sopenharmony_ci 758cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s->draw(ddl)); 759cb93a386Sopenharmony_ci s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); 760cb93a386Sopenharmony_ci 761cb93a386Sopenharmony_ci context->flush(); 762cb93a386Sopenharmony_ci } 763cb93a386Sopenharmony_ci 764cb93a386Sopenharmony_ci} 765cb93a386Sopenharmony_ci 766cb93a386Sopenharmony_cistatic void test_make_render_target(skiatest::Reporter* reporter, 767cb93a386Sopenharmony_ci GrDirectContext* dContext, 768cb93a386Sopenharmony_ci const SurfaceParameters& params) { 769cb93a386Sopenharmony_ci { 770cb93a386Sopenharmony_ci const SkSurfaceCharacterization c = params.createCharacterization(dContext); 771cb93a386Sopenharmony_ci 772cb93a386Sopenharmony_ci if (!c.isValid()) { 773cb93a386Sopenharmony_ci sk_sp<SkSurface> tmp = params.make(dContext); 774cb93a386Sopenharmony_ci // If we couldn't characterize the surface we shouldn't be able to create it either 775cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !tmp); 776cb93a386Sopenharmony_ci return; 777cb93a386Sopenharmony_ci } 778cb93a386Sopenharmony_ci } 779cb93a386Sopenharmony_ci 780cb93a386Sopenharmony_ci const SkSurfaceCharacterization c = params.createCharacterization(dContext); 781cb93a386Sopenharmony_ci { 782cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 783cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s); 784cb93a386Sopenharmony_ci if (!s) { 785cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !c.isValid()); 786cb93a386Sopenharmony_ci return; 787cb93a386Sopenharmony_ci } 788cb93a386Sopenharmony_ci 789cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, c.isValid()); 790cb93a386Sopenharmony_ci GrBackendTexture backend = s->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess); 791cb93a386Sopenharmony_ci if (backend.isValid()) { 792cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, c.isCompatible(backend)); 793cb93a386Sopenharmony_ci } 794cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s->isCompatible(c)); 795cb93a386Sopenharmony_ci // Note that we're leaving 'backend' live here 796cb93a386Sopenharmony_ci } 797cb93a386Sopenharmony_ci 798cb93a386Sopenharmony_ci // Make an SkSurface from scratch 799cb93a386Sopenharmony_ci { 800cb93a386Sopenharmony_ci sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(dContext, c, SkBudgeted::kYes); 801cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s); 802cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, s->isCompatible(c)); 803cb93a386Sopenharmony_ci } 804cb93a386Sopenharmony_ci} 805cb93a386Sopenharmony_ci 806cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 807cb93a386Sopenharmony_ci// This tests the SkSurface::MakeRenderTarget variants that take an SkSurfaceCharacterization. 808cb93a386Sopenharmony_ci// In particular, the SkSurface, backendTexture and SkSurfaceCharacterization 809cb93a386Sopenharmony_ci// should always be compatible. 810cb93a386Sopenharmony_civoid DDLMakeRenderTargetTestImpl(GrDirectContext* dContext, skiatest::Reporter* reporter) { 811cb93a386Sopenharmony_ci for (int i = -1; i < SurfaceParameters::kNumParams; ++i) { 812cb93a386Sopenharmony_ci if (i == SurfaceParameters::kFBO0Count || i == SurfaceParameters::kVkSCBCount) { 813cb93a386Sopenharmony_ci // MakeRenderTarget doesn't support FBO0 or vulkan secondary command buffers 814cb93a386Sopenharmony_ci continue; 815cb93a386Sopenharmony_ci } 816cb93a386Sopenharmony_ci 817cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 818cb93a386Sopenharmony_ci if (i >= 0 && !params.modify(i)) { 819cb93a386Sopenharmony_ci continue; 820cb93a386Sopenharmony_ci } 821cb93a386Sopenharmony_ci 822cb93a386Sopenharmony_ci test_make_render_target(reporter, dContext, params); 823cb93a386Sopenharmony_ci } 824cb93a386Sopenharmony_ci} 825cb93a386Sopenharmony_ci 826cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMakeRenderTargetTest, reporter, ctxInfo) { 827cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 828cb93a386Sopenharmony_ci 829cb93a386Sopenharmony_ci DDLMakeRenderTargetTestImpl(context, reporter); 830cb93a386Sopenharmony_ci} 831cb93a386Sopenharmony_ci 832cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 833cb93a386Sopenharmony_cistatic constexpr int kSize = 8; 834cb93a386Sopenharmony_ci 835cb93a386Sopenharmony_cistruct TextureReleaseChecker { 836cb93a386Sopenharmony_ci TextureReleaseChecker() : fReleaseCount(0) {} 837cb93a386Sopenharmony_ci int fReleaseCount; 838cb93a386Sopenharmony_ci static void Release(void* self) { 839cb93a386Sopenharmony_ci static_cast<TextureReleaseChecker*>(self)->fReleaseCount++; 840cb93a386Sopenharmony_ci } 841cb93a386Sopenharmony_ci}; 842cb93a386Sopenharmony_ci 843cb93a386Sopenharmony_cienum class DDLStage { kMakeImage, kDrawImage, kDetach, kDrawDDL }; 844cb93a386Sopenharmony_ci 845cb93a386Sopenharmony_ci// This tests the ability to create and use wrapped textures in a DDL world 846cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) { 847cb93a386Sopenharmony_ci auto dContext = ctxInfo.directContext(); 848cb93a386Sopenharmony_ci 849cb93a386Sopenharmony_ci auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(dContext, 850cb93a386Sopenharmony_ci kSize, 851cb93a386Sopenharmony_ci kSize, 852cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 853cb93a386Sopenharmony_ci GrMipmapped::kNo, 854cb93a386Sopenharmony_ci GrRenderable::kNo, 855cb93a386Sopenharmony_ci GrProtected::kNo); 856cb93a386Sopenharmony_ci if (!mbet) { 857cb93a386Sopenharmony_ci return; 858cb93a386Sopenharmony_ci } 859cb93a386Sopenharmony_ci 860cb93a386Sopenharmony_ci SurfaceParameters params(dContext); 861cb93a386Sopenharmony_ci 862cb93a386Sopenharmony_ci sk_sp<SkSurface> s = params.make(dContext); 863cb93a386Sopenharmony_ci if (!s) { 864cb93a386Sopenharmony_ci return; 865cb93a386Sopenharmony_ci } 866cb93a386Sopenharmony_ci 867cb93a386Sopenharmony_ci SkSurfaceCharacterization c; 868cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&c)); 869cb93a386Sopenharmony_ci 870cb93a386Sopenharmony_ci SkDeferredDisplayListRecorder recorder(c); 871cb93a386Sopenharmony_ci 872cb93a386Sopenharmony_ci SkCanvas* canvas = recorder.getCanvas(); 873cb93a386Sopenharmony_ci SkASSERT(canvas); 874cb93a386Sopenharmony_ci 875cb93a386Sopenharmony_ci auto rContext = canvas->recordingContext(); 876cb93a386Sopenharmony_ci if (!rContext) { 877cb93a386Sopenharmony_ci return; 878cb93a386Sopenharmony_ci } 879cb93a386Sopenharmony_ci 880cb93a386Sopenharmony_ci // Wrapped Backend Textures are not supported in DDL 881cb93a386Sopenharmony_ci TextureReleaseChecker releaseChecker; 882cb93a386Sopenharmony_ci sk_sp<SkImage> image = SkImage::MakeFromTexture( 883cb93a386Sopenharmony_ci rContext, 884cb93a386Sopenharmony_ci mbet->texture(), 885cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 886cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 887cb93a386Sopenharmony_ci kPremul_SkAlphaType, 888cb93a386Sopenharmony_ci nullptr, 889cb93a386Sopenharmony_ci sk_gpu_test::ManagedBackendTexture::ReleaseProc, 890cb93a386Sopenharmony_ci mbet->releaseContext(TextureReleaseChecker::Release, &releaseChecker)); 891cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !image); 892cb93a386Sopenharmony_ci} 893cb93a386Sopenharmony_ci 894cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 895cb93a386Sopenharmony_ci// Test out the behavior of an invalid DDLRecorder 896cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLInvalidRecorder, reporter, ctxInfo) { 897cb93a386Sopenharmony_ci auto dContext = ctxInfo.directContext(); 898cb93a386Sopenharmony_ci 899cb93a386Sopenharmony_ci { 900cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32); 901cb93a386Sopenharmony_ci sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, ii); 902cb93a386Sopenharmony_ci 903cb93a386Sopenharmony_ci SkSurfaceCharacterization characterization; 904cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&characterization)); 905cb93a386Sopenharmony_ci 906cb93a386Sopenharmony_ci // never calling getCanvas means the backing surface is never allocated 907cb93a386Sopenharmony_ci SkDeferredDisplayListRecorder recorder(characterization); 908cb93a386Sopenharmony_ci } 909cb93a386Sopenharmony_ci 910cb93a386Sopenharmony_ci { 911cb93a386Sopenharmony_ci SkSurfaceCharacterization invalid; 912cb93a386Sopenharmony_ci 913cb93a386Sopenharmony_ci SkDeferredDisplayListRecorder recorder(invalid); 914cb93a386Sopenharmony_ci 915cb93a386Sopenharmony_ci const SkSurfaceCharacterization c = recorder.characterization(); 916cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !c.isValid()); 917cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !recorder.getCanvas()); 918cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !recorder.detach()); 919cb93a386Sopenharmony_ci } 920cb93a386Sopenharmony_ci} 921cb93a386Sopenharmony_ci 922cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLCreateCharacterizationFailures, reporter, ctxInfo) { 923cb93a386Sopenharmony_ci auto dContext = ctxInfo.directContext(); 924cb93a386Sopenharmony_ci size_t maxResourceBytes = dContext->getResourceCacheLimit(); 925cb93a386Sopenharmony_ci auto proxy = dContext->threadSafeProxy().get(); 926cb93a386Sopenharmony_ci 927cb93a386Sopenharmony_ci auto check_create_fails = 928cb93a386Sopenharmony_ci [proxy, reporter, maxResourceBytes](const GrBackendFormat& backendFormat, 929cb93a386Sopenharmony_ci int width, int height, 930cb93a386Sopenharmony_ci SkColorType ct, bool willUseGLFBO0, 931cb93a386Sopenharmony_ci bool isTextureable, 932cb93a386Sopenharmony_ci GrProtected prot, 933cb93a386Sopenharmony_ci bool vkRTSupportsInputAttachment, 934cb93a386Sopenharmony_ci bool forVulkanSecondaryCommandBuffer) { 935cb93a386Sopenharmony_ci const SkSurfaceProps surfaceProps(0x0, kRGB_H_SkPixelGeometry); 936cb93a386Sopenharmony_ci 937cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::Make(width, height, ct, 938cb93a386Sopenharmony_ci kPremul_SkAlphaType, nullptr); 939cb93a386Sopenharmony_ci 940cb93a386Sopenharmony_ci SkSurfaceCharacterization c = proxy->createCharacterization( 941cb93a386Sopenharmony_ci maxResourceBytes, ii, backendFormat, 1, 942cb93a386Sopenharmony_ci kBottomLeft_GrSurfaceOrigin, surfaceProps, false, 943cb93a386Sopenharmony_ci willUseGLFBO0, isTextureable, prot, 944cb93a386Sopenharmony_ci vkRTSupportsInputAttachment, 945cb93a386Sopenharmony_ci forVulkanSecondaryCommandBuffer); 946cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !c.isValid()); 947cb93a386Sopenharmony_ci }; 948cb93a386Sopenharmony_ci 949cb93a386Sopenharmony_ci GrBackendFormat goodBackendFormat = dContext->defaultBackendFormat(kRGBA_8888_SkColorType, 950cb93a386Sopenharmony_ci GrRenderable::kYes); 951cb93a386Sopenharmony_ci SkASSERT(goodBackendFormat.isValid()); 952cb93a386Sopenharmony_ci 953cb93a386Sopenharmony_ci GrBackendFormat badBackendFormat; 954cb93a386Sopenharmony_ci SkASSERT(!badBackendFormat.isValid()); 955cb93a386Sopenharmony_ci 956cb93a386Sopenharmony_ci SkColorType kGoodCT = kRGBA_8888_SkColorType; 957cb93a386Sopenharmony_ci SkColorType kBadCT = kUnknown_SkColorType; 958cb93a386Sopenharmony_ci 959cb93a386Sopenharmony_ci static const bool kIsTextureable = true; 960cb93a386Sopenharmony_ci static const bool kIsNotTextureable = false; 961cb93a386Sopenharmony_ci 962cb93a386Sopenharmony_ci static const bool kGoodUseFBO0 = false; 963cb93a386Sopenharmony_ci static const bool kBadUseFBO0 = true; 964cb93a386Sopenharmony_ci 965cb93a386Sopenharmony_ci static const bool kGoodVkInputAttachment = false; 966cb93a386Sopenharmony_ci static const bool kBadVkInputAttachment = true; 967cb93a386Sopenharmony_ci 968cb93a386Sopenharmony_ci static const bool kGoodForVkSCB = false; 969cb93a386Sopenharmony_ci static const bool kBadForVkSCB = true; 970cb93a386Sopenharmony_ci 971cb93a386Sopenharmony_ci int goodWidth = 64; 972cb93a386Sopenharmony_ci int goodHeight = 64; 973cb93a386Sopenharmony_ci int badWidths[] = { 0, 1048576 }; 974cb93a386Sopenharmony_ci int badHeights[] = { 0, 1048576 }; 975cb93a386Sopenharmony_ci 976cb93a386Sopenharmony_ci 977cb93a386Sopenharmony_ci // In each of the check_create_fails calls there is one bad parameter that should cause the 978cb93a386Sopenharmony_ci // creation of the characterization to fail. 979cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, badHeights[0], kGoodCT, kGoodUseFBO0, 980cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB); 981cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, badHeights[1], kGoodCT, kGoodUseFBO0, 982cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB); 983cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, badWidths[0], goodHeight, kGoodCT, kGoodUseFBO0, 984cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB); 985cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, badWidths[1], goodHeight, kGoodCT, kGoodUseFBO0, 986cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB); 987cb93a386Sopenharmony_ci check_create_fails(badBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0, 988cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB); 989cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kBadCT, kGoodUseFBO0, 990cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB); 991cb93a386Sopenharmony_ci // This fails because we always try to make a characterization that is textureable and we can't 992cb93a386Sopenharmony_ci // have UseFBO0 be true and textureable. 993cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0, 994cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kGoodForVkSCB); 995cb93a386Sopenharmony_ci if (dContext->backend() == GrBackendApi::kVulkan) { 996cb93a386Sopenharmony_ci // The bad parameter in this case is the GrProtected::kYes since none of our test contexts 997cb93a386Sopenharmony_ci // are made protected we can't have a protected surface. 998cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0, 999cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kYes, kGoodVkInputAttachment, 1000cb93a386Sopenharmony_ci kGoodForVkSCB); 1001cb93a386Sopenharmony_ci // The following fails because forVulkanSecondaryCommandBuffer is true and 1002cb93a386Sopenharmony_ci // isTextureable is true. This is not a legal combination. 1003cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0, 1004cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kGoodVkInputAttachment, kBadForVkSCB); 1005cb93a386Sopenharmony_ci // The following fails because forVulkanSecondaryCommandBuffer is true and 1006cb93a386Sopenharmony_ci // vkRTSupportsInputAttachment is true. This is not a legal combination. 1007cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0, 1008cb93a386Sopenharmony_ci kIsNotTextureable, GrProtected::kNo, kBadVkInputAttachment, 1009cb93a386Sopenharmony_ci kBadForVkSCB); 1010cb93a386Sopenharmony_ci // The following fails because forVulkanSecondaryCommandBuffer is true and 1011cb93a386Sopenharmony_ci // willUseGLFBO0 is true. This is not a legal combination. 1012cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kBadUseFBO0, 1013cb93a386Sopenharmony_ci kIsNotTextureable, GrProtected::kNo, kGoodVkInputAttachment, 1014cb93a386Sopenharmony_ci kBadForVkSCB); 1015cb93a386Sopenharmony_ci } else { 1016cb93a386Sopenharmony_ci // The following set vulkan only flags on non vulkan backends. 1017cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0, 1018cb93a386Sopenharmony_ci kIsTextureable, GrProtected::kNo, kBadVkInputAttachment, kGoodForVkSCB); 1019cb93a386Sopenharmony_ci check_create_fails(goodBackendFormat, goodWidth, goodHeight, kGoodCT, kGoodUseFBO0, 1020cb93a386Sopenharmony_ci kIsNotTextureable, GrProtected::kNo, kGoodVkInputAttachment, 1021cb93a386Sopenharmony_ci kBadForVkSCB); 1022cb93a386Sopenharmony_ci } 1023cb93a386Sopenharmony_ci} 1024cb93a386Sopenharmony_ci 1025cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 1026cb93a386Sopenharmony_ci// Test that flushing a DDL via SkSurface::flush works 1027cb93a386Sopenharmony_ci 1028cb93a386Sopenharmony_cistruct FulfillInfo { 1029cb93a386Sopenharmony_ci sk_sp<SkPromiseImageTexture> fTex; 1030cb93a386Sopenharmony_ci bool fFulfilled = false; 1031cb93a386Sopenharmony_ci bool fReleased = false; 1032cb93a386Sopenharmony_ci}; 1033cb93a386Sopenharmony_ci 1034cb93a386Sopenharmony_cistatic sk_sp<SkPromiseImageTexture> tracking_fulfill_proc(void* context) { 1035cb93a386Sopenharmony_ci FulfillInfo* info = (FulfillInfo*) context; 1036cb93a386Sopenharmony_ci info->fFulfilled = true; 1037cb93a386Sopenharmony_ci return info->fTex; 1038cb93a386Sopenharmony_ci} 1039cb93a386Sopenharmony_ci 1040cb93a386Sopenharmony_cistatic void tracking_release_proc(void* context) { 1041cb93a386Sopenharmony_ci FulfillInfo* info = (FulfillInfo*) context; 1042cb93a386Sopenharmony_ci info->fReleased = true; 1043cb93a386Sopenharmony_ci} 1044cb93a386Sopenharmony_ci 1045cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLSkSurfaceFlush, reporter, ctxInfo) { 1046cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 1047cb93a386Sopenharmony_ci 1048cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 1049cb93a386Sopenharmony_ci sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii); 1050cb93a386Sopenharmony_ci 1051cb93a386Sopenharmony_ci SkSurfaceCharacterization characterization; 1052cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&characterization)); 1053cb93a386Sopenharmony_ci 1054cb93a386Sopenharmony_ci auto mbet = sk_gpu_test::ManagedBackendTexture::MakeFromInfo(context, ii); 1055cb93a386Sopenharmony_ci if (!mbet) { 1056cb93a386Sopenharmony_ci ERRORF(reporter, "Could not make texture."); 1057cb93a386Sopenharmony_ci return; 1058cb93a386Sopenharmony_ci } 1059cb93a386Sopenharmony_ci 1060cb93a386Sopenharmony_ci FulfillInfo fulfillInfo; 1061cb93a386Sopenharmony_ci fulfillInfo.fTex = SkPromiseImageTexture::Make(mbet->texture()); 1062cb93a386Sopenharmony_ci 1063cb93a386Sopenharmony_ci sk_sp<SkDeferredDisplayList> ddl; 1064cb93a386Sopenharmony_ci 1065cb93a386Sopenharmony_ci { 1066cb93a386Sopenharmony_ci SkDeferredDisplayListRecorder recorder(characterization); 1067cb93a386Sopenharmony_ci 1068cb93a386Sopenharmony_ci GrBackendFormat format = context->defaultBackendFormat(kRGBA_8888_SkColorType, 1069cb93a386Sopenharmony_ci GrRenderable::kNo); 1070cb93a386Sopenharmony_ci SkASSERT(format.isValid()); 1071cb93a386Sopenharmony_ci 1072cb93a386Sopenharmony_ci SkCanvas* canvas = recorder.getCanvas(); 1073cb93a386Sopenharmony_ci 1074cb93a386Sopenharmony_ci sk_sp<SkImage> promiseImage = SkImage::MakePromiseTexture( 1075cb93a386Sopenharmony_ci canvas->recordingContext()->threadSafeProxy(), 1076cb93a386Sopenharmony_ci format, 1077cb93a386Sopenharmony_ci SkISize::Make(32, 32), 1078cb93a386Sopenharmony_ci GrMipmapped::kNo, 1079cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 1080cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 1081cb93a386Sopenharmony_ci kPremul_SkAlphaType, 1082cb93a386Sopenharmony_ci nullptr, 1083cb93a386Sopenharmony_ci tracking_fulfill_proc, 1084cb93a386Sopenharmony_ci tracking_release_proc, 1085cb93a386Sopenharmony_ci &fulfillInfo); 1086cb93a386Sopenharmony_ci 1087cb93a386Sopenharmony_ci canvas->clear(SK_ColorRED); 1088cb93a386Sopenharmony_ci canvas->drawImage(promiseImage, 0, 0); 1089cb93a386Sopenharmony_ci ddl = recorder.detach(); 1090cb93a386Sopenharmony_ci } 1091cb93a386Sopenharmony_ci 1092cb93a386Sopenharmony_ci context->flushAndSubmit(); 1093cb93a386Sopenharmony_ci 1094cb93a386Sopenharmony_ci s->draw(ddl); 1095cb93a386Sopenharmony_ci 1096cb93a386Sopenharmony_ci GrFlushInfo flushInfo; 1097cb93a386Sopenharmony_ci s->flush(SkSurface::BackendSurfaceAccess::kPresent, flushInfo); 1098cb93a386Sopenharmony_ci context->submit(); 1099cb93a386Sopenharmony_ci 1100cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, fulfillInfo.fFulfilled); 1101cb93a386Sopenharmony_ci 1102cb93a386Sopenharmony_ci // In order to receive the done callback with the low-level APIs we need to re-flush 1103cb93a386Sopenharmony_ci s->flush(); 1104cb93a386Sopenharmony_ci context->submit(true); 1105cb93a386Sopenharmony_ci 1106cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, fulfillInfo.fReleased); 1107cb93a386Sopenharmony_ci 1108cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, fulfillInfo.fTex->unique()); 1109cb93a386Sopenharmony_ci fulfillInfo.fTex.reset(); 1110cb93a386Sopenharmony_ci} 1111cb93a386Sopenharmony_ci 1112cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 1113cb93a386Sopenharmony_ci// Ensure that reusing a single DDLRecorder to create multiple DDLs works cleanly 1114cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLMultipleDDLs, reporter, ctxInfo) { 1115cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 1116cb93a386Sopenharmony_ci 1117cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32); 1118cb93a386Sopenharmony_ci sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii); 1119cb93a386Sopenharmony_ci 1120cb93a386Sopenharmony_ci SkBitmap bitmap; 1121cb93a386Sopenharmony_ci bitmap.allocPixels(ii); 1122cb93a386Sopenharmony_ci 1123cb93a386Sopenharmony_ci SkSurfaceCharacterization characterization; 1124cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&characterization)); 1125cb93a386Sopenharmony_ci 1126cb93a386Sopenharmony_ci SkDeferredDisplayListRecorder recorder(characterization); 1127cb93a386Sopenharmony_ci 1128cb93a386Sopenharmony_ci SkCanvas* canvas1 = recorder.getCanvas(); 1129cb93a386Sopenharmony_ci 1130cb93a386Sopenharmony_ci canvas1->clear(SK_ColorRED); 1131cb93a386Sopenharmony_ci 1132cb93a386Sopenharmony_ci canvas1->save(); 1133cb93a386Sopenharmony_ci canvas1->clipRect(SkRect::MakeXYWH(8, 8, 16, 16)); 1134cb93a386Sopenharmony_ci 1135cb93a386Sopenharmony_ci sk_sp<SkDeferredDisplayList> ddl1 = recorder.detach(); 1136cb93a386Sopenharmony_ci 1137cb93a386Sopenharmony_ci SkCanvas* canvas2 = recorder.getCanvas(); 1138cb93a386Sopenharmony_ci 1139cb93a386Sopenharmony_ci SkPaint p; 1140cb93a386Sopenharmony_ci p.setColor(SK_ColorGREEN); 1141cb93a386Sopenharmony_ci canvas2->drawRect(SkRect::MakeWH(32, 32), p); 1142cb93a386Sopenharmony_ci 1143cb93a386Sopenharmony_ci sk_sp<SkDeferredDisplayList> ddl2 = recorder.detach(); 1144cb93a386Sopenharmony_ci 1145cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData()); 1146cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, ddl2->priv().lazyProxyData()); 1147cb93a386Sopenharmony_ci 1148cb93a386Sopenharmony_ci // The lazy proxy data being different ensures that the SkSurface, SkCanvas and backing- 1149cb93a386Sopenharmony_ci // lazy proxy are all different between the two DDLs 1150cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, ddl1->priv().lazyProxyData() != ddl2->priv().lazyProxyData()); 1151cb93a386Sopenharmony_ci 1152cb93a386Sopenharmony_ci s->draw(ddl1); 1153cb93a386Sopenharmony_ci s->draw(ddl2); 1154cb93a386Sopenharmony_ci 1155cb93a386Sopenharmony_ci // Make sure the clipRect from DDL1 didn't percolate into DDL2 1156cb93a386Sopenharmony_ci s->readPixels(ii, bitmap.getPixels(), bitmap.rowBytes(), 0, 0); 1157cb93a386Sopenharmony_ci for (int y = 0; y < 32; ++y) { 1158cb93a386Sopenharmony_ci for (int x = 0; x < 32; ++x) { 1159cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, bitmap.getColor(x, y) == SK_ColorGREEN); 1160cb93a386Sopenharmony_ci if (bitmap.getColor(x, y) != SK_ColorGREEN) { 1161cb93a386Sopenharmony_ci return; // we only really need to report the error once 1162cb93a386Sopenharmony_ci } 1163cb93a386Sopenharmony_ci } 1164cb93a386Sopenharmony_ci } 1165cb93a386Sopenharmony_ci} 1166cb93a386Sopenharmony_ci 1167cb93a386Sopenharmony_ci#ifdef SK_GL 1168cb93a386Sopenharmony_ci 1169cb93a386Sopenharmony_cistatic sk_sp<SkPromiseImageTexture> noop_fulfill_proc(void*) { 1170cb93a386Sopenharmony_ci SkASSERT(0); 1171cb93a386Sopenharmony_ci return nullptr; 1172cb93a386Sopenharmony_ci} 1173cb93a386Sopenharmony_ci 1174cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 1175cb93a386Sopenharmony_ci// Check that the texture-specific flags (i.e., for external & rectangle textures) work 1176cb93a386Sopenharmony_ci// for promise images. As such, this is a GL-only test. 1177cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLTextureFlagsTest, reporter, ctxInfo) { 1178cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 1179cb93a386Sopenharmony_ci 1180cb93a386Sopenharmony_ci SkImageInfo ii = SkImageInfo::MakeN32Premul(32, 32); 1181cb93a386Sopenharmony_ci sk_sp<SkSurface> s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii); 1182cb93a386Sopenharmony_ci 1183cb93a386Sopenharmony_ci SkSurfaceCharacterization characterization; 1184cb93a386Sopenharmony_ci SkAssertResult(s->characterize(&characterization)); 1185cb93a386Sopenharmony_ci 1186cb93a386Sopenharmony_ci SkDeferredDisplayListRecorder recorder(characterization); 1187cb93a386Sopenharmony_ci 1188cb93a386Sopenharmony_ci for (GrGLenum target : { GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_2D } ) { 1189cb93a386Sopenharmony_ci for (auto mipMapped : { GrMipmapped::kNo, GrMipmapped::kYes }) { 1190cb93a386Sopenharmony_ci GrBackendFormat format = GrBackendFormat::MakeGL(GR_GL_RGBA8, target); 1191cb93a386Sopenharmony_ci 1192cb93a386Sopenharmony_ci sk_sp<SkImage> image = SkImage::MakePromiseTexture( 1193cb93a386Sopenharmony_ci recorder.getCanvas()->recordingContext()->threadSafeProxy(), 1194cb93a386Sopenharmony_ci format, 1195cb93a386Sopenharmony_ci SkISize::Make(32, 32), 1196cb93a386Sopenharmony_ci mipMapped, 1197cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 1198cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 1199cb93a386Sopenharmony_ci kPremul_SkAlphaType, 1200cb93a386Sopenharmony_ci /*color space*/nullptr, 1201cb93a386Sopenharmony_ci noop_fulfill_proc, 1202cb93a386Sopenharmony_ci /*release proc*/ nullptr, 1203cb93a386Sopenharmony_ci /*context*/nullptr); 1204cb93a386Sopenharmony_ci if (GR_GL_TEXTURE_2D != target && mipMapped == GrMipmapped::kYes) { 1205cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !image); 1206cb93a386Sopenharmony_ci continue; 1207cb93a386Sopenharmony_ci } 1208cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, image); 1209cb93a386Sopenharmony_ci 1210cb93a386Sopenharmony_ci GrTextureProxy* backingProxy = sk_gpu_test::GetTextureImageProxy(image.get(), context); 1211cb93a386Sopenharmony_ci 1212cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backingProxy->mipmapped() == mipMapped); 1213cb93a386Sopenharmony_ci if (GR_GL_TEXTURE_2D == target) { 1214cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !backingProxy->hasRestrictedSampling()); 1215cb93a386Sopenharmony_ci } else { 1216cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backingProxy->hasRestrictedSampling()); 1217cb93a386Sopenharmony_ci } 1218cb93a386Sopenharmony_ci } 1219cb93a386Sopenharmony_ci } 1220cb93a386Sopenharmony_ci} 1221cb93a386Sopenharmony_ci#endif // SK_GL 1222cb93a386Sopenharmony_ci 1223cb93a386Sopenharmony_ci//////////////////////////////////////////////////////////////////////////////// 1224cb93a386Sopenharmony_ci// Test colorType and pixelConfig compatibility. 1225cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(DDLCompatibilityTest, reporter, ctxInfo) { 1226cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 1227cb93a386Sopenharmony_ci 1228cb93a386Sopenharmony_ci for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) { 1229cb93a386Sopenharmony_ci SkColorType colorType = static_cast<SkColorType>(ct); 1230cb93a386Sopenharmony_ci 1231cb93a386Sopenharmony_ci SurfaceParameters params(context); 1232cb93a386Sopenharmony_ci params.setColorType(colorType); 1233cb93a386Sopenharmony_ci params.setColorSpace(nullptr); 1234cb93a386Sopenharmony_ci 1235cb93a386Sopenharmony_ci test_make_render_target(reporter, context, params); 1236cb93a386Sopenharmony_ci } 1237cb93a386Sopenharmony_ci 1238cb93a386Sopenharmony_ci} 1239