1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2018 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// This is a GPU-backend specific test. It relies on static intializers to work 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU && defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26 && defined(SK_VULKAN) 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 15cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 16cb93a386Sopenharmony_ci#include "include/core/SkImage.h" 17cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 18cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSemaphore.h" 19cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 20cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkBackendContext.h" 21cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkExtensions.h" 22cb93a386Sopenharmony_ci#include "src/core/SkAutoMalloc.h" 23cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 24cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h" 25cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 26cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h" 27cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLDefines.h" 28cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLUtil.h" 29cb93a386Sopenharmony_ci#include "tests/Test.h" 30cb93a386Sopenharmony_ci#include "tools/gpu/GrContextFactory.h" 31cb93a386Sopenharmony_ci#include "tools/gpu/vk/VkTestUtils.h" 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci#include <android/hardware_buffer.h> 34cb93a386Sopenharmony_ci#include <cinttypes> 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci#include <EGL/egl.h> 37cb93a386Sopenharmony_ci#include <EGL/eglext.h> 38cb93a386Sopenharmony_ci#include <GLES/gl.h> 39cb93a386Sopenharmony_ci#include <GLES/glext.h> 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_cistatic const int DEV_W = 16, DEV_H = 16; 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ciclass BaseTestHelper { 44cb93a386Sopenharmony_cipublic: 45cb93a386Sopenharmony_ci virtual ~BaseTestHelper() {} 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci virtual bool init(skiatest::Reporter* reporter) = 0; 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci virtual void cleanup() = 0; 50cb93a386Sopenharmony_ci virtual void releaseImage() = 0; 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci virtual sk_sp<SkImage> importHardwareBufferForRead(skiatest::Reporter* reporter, 53cb93a386Sopenharmony_ci AHardwareBuffer* buffer) = 0; 54cb93a386Sopenharmony_ci virtual sk_sp<SkSurface> importHardwareBufferForWrite(skiatest::Reporter* reporter, 55cb93a386Sopenharmony_ci AHardwareBuffer* buffer) = 0; 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci virtual void doClientSync() = 0; 58cb93a386Sopenharmony_ci virtual bool flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, sk_sp<SkSurface>) = 0; 59cb93a386Sopenharmony_ci virtual bool importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle, 60cb93a386Sopenharmony_ci sk_sp<SkSurface>) = 0; 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci virtual void makeCurrent() = 0; 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci virtual GrDirectContext* directContext() = 0; 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci int getFdHandle() { return fFdHandle; } 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ciprotected: 69cb93a386Sopenharmony_ci BaseTestHelper() {} 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci int fFdHandle = 0; 72cb93a386Sopenharmony_ci}; 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci#ifdef SK_GL 75cb93a386Sopenharmony_ciclass EGLTestHelper : public BaseTestHelper { 76cb93a386Sopenharmony_cipublic: 77cb93a386Sopenharmony_ci EGLTestHelper(const GrContextOptions& options) : fFactory(options) {} 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ci ~EGLTestHelper() override {} 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci void releaseImage() override { 82cb93a386Sopenharmony_ci this->makeCurrent(); 83cb93a386Sopenharmony_ci if (!fGLCtx) { 84cb93a386Sopenharmony_ci return; 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci if (EGL_NO_IMAGE_KHR != fImage) { 87cb93a386Sopenharmony_ci fGLCtx->destroyEGLImage(fImage); 88cb93a386Sopenharmony_ci fImage = EGL_NO_IMAGE_KHR; 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci if (fTexID) { 91cb93a386Sopenharmony_ci GR_GL_CALL(fGLCtx->gl(), DeleteTextures(1, &fTexID)); 92cb93a386Sopenharmony_ci fTexID = 0; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci void cleanup() override { 97cb93a386Sopenharmony_ci this->releaseImage(); 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci bool init(skiatest::Reporter* reporter) override; 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_ci sk_sp<SkImage> importHardwareBufferForRead(skiatest::Reporter* reporter, 103cb93a386Sopenharmony_ci AHardwareBuffer* buffer) override; 104cb93a386Sopenharmony_ci sk_sp<SkSurface> importHardwareBufferForWrite(skiatest::Reporter* reporter, 105cb93a386Sopenharmony_ci AHardwareBuffer* buffer) override; 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci void doClientSync() override; 108cb93a386Sopenharmony_ci bool flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, sk_sp<SkSurface>) override; 109cb93a386Sopenharmony_ci bool importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle, 110cb93a386Sopenharmony_ci sk_sp<SkSurface>) override; 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci void makeCurrent() override { fGLCtx->makeCurrent(); } 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci GrDirectContext* directContext() override { return fDirectContext; } 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ciprivate: 117cb93a386Sopenharmony_ci bool importHardwareBuffer(skiatest::Reporter* reporter, AHardwareBuffer* buffer); 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_ci typedef EGLClientBuffer (*EGLGetNativeClientBufferANDROIDProc)(const struct AHardwareBuffer*); 120cb93a386Sopenharmony_ci typedef EGLImageKHR (*EGLCreateImageKHRProc)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, 121cb93a386Sopenharmony_ci const EGLint*); 122cb93a386Sopenharmony_ci typedef void (*EGLImageTargetTexture2DOESProc)(EGLenum, void*); 123cb93a386Sopenharmony_ci EGLGetNativeClientBufferANDROIDProc fEGLGetNativeClientBufferANDROID; 124cb93a386Sopenharmony_ci EGLCreateImageKHRProc fEGLCreateImageKHR; 125cb93a386Sopenharmony_ci EGLImageTargetTexture2DOESProc fEGLImageTargetTexture2DOES; 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci PFNEGLCREATESYNCKHRPROC fEGLCreateSyncKHR; 128cb93a386Sopenharmony_ci PFNEGLWAITSYNCKHRPROC fEGLWaitSyncKHR; 129cb93a386Sopenharmony_ci PFNEGLGETSYNCATTRIBKHRPROC fEGLGetSyncAttribKHR; 130cb93a386Sopenharmony_ci PFNEGLDUPNATIVEFENCEFDANDROIDPROC fEGLDupNativeFenceFDANDROID; 131cb93a386Sopenharmony_ci PFNEGLDESTROYSYNCKHRPROC fEGLDestroySyncKHR; 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci EGLImageKHR fImage = EGL_NO_IMAGE_KHR; 134cb93a386Sopenharmony_ci GrGLuint fTexID = 0; 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_ci sk_gpu_test::GrContextFactory fFactory; 137cb93a386Sopenharmony_ci sk_gpu_test::ContextInfo fGLESContextInfo; 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci sk_gpu_test::GLTestContext* fGLCtx = nullptr; 140cb93a386Sopenharmony_ci GrDirectContext* fDirectContext = nullptr; 141cb93a386Sopenharmony_ci}; 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_cibool EGLTestHelper::init(skiatest::Reporter* reporter) { 144cb93a386Sopenharmony_ci fGLESContextInfo = fFactory.getContextInfo(sk_gpu_test::GrContextFactory::kGLES_ContextType); 145cb93a386Sopenharmony_ci fDirectContext = fGLESContextInfo.directContext(); 146cb93a386Sopenharmony_ci fGLCtx = fGLESContextInfo.glContext(); 147cb93a386Sopenharmony_ci if (!fDirectContext || !fGLCtx) { 148cb93a386Sopenharmony_ci return false; 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_ci if (kGLES_GrGLStandard != fGLCtx->gl()->fStandard) { 152cb93a386Sopenharmony_ci return false; 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci // Confirm we have egl and the needed extensions 156cb93a386Sopenharmony_ci if (!fGLCtx->gl()->hasExtension("EGL_KHR_image") || 157cb93a386Sopenharmony_ci !fGLCtx->gl()->hasExtension("EGL_ANDROID_get_native_client_buffer") || 158cb93a386Sopenharmony_ci !fGLCtx->gl()->hasExtension("GL_OES_EGL_image_external") || 159cb93a386Sopenharmony_ci !fGLCtx->gl()->hasExtension("GL_OES_EGL_image") || 160cb93a386Sopenharmony_ci !fGLCtx->gl()->hasExtension("EGL_KHR_fence_sync") || 161cb93a386Sopenharmony_ci !fGLCtx->gl()->hasExtension("EGL_ANDROID_native_fence_sync")) { 162cb93a386Sopenharmony_ci return false; 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci fEGLGetNativeClientBufferANDROID = 166cb93a386Sopenharmony_ci (EGLGetNativeClientBufferANDROIDProc) eglGetProcAddress("eglGetNativeClientBufferANDROID"); 167cb93a386Sopenharmony_ci if (!fEGLGetNativeClientBufferANDROID) { 168cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the eglGetNativeClientBufferAndroid proc"); 169cb93a386Sopenharmony_ci return false; 170cb93a386Sopenharmony_ci } 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_ci fEGLCreateImageKHR = (EGLCreateImageKHRProc) eglGetProcAddress("eglCreateImageKHR"); 173cb93a386Sopenharmony_ci if (!fEGLCreateImageKHR) { 174cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the proc eglCreateImageKHR"); 175cb93a386Sopenharmony_ci return false; 176cb93a386Sopenharmony_ci } 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci fEGLImageTargetTexture2DOES = 179cb93a386Sopenharmony_ci (EGLImageTargetTexture2DOESProc) eglGetProcAddress("glEGLImageTargetTexture2DOES"); 180cb93a386Sopenharmony_ci if (!fEGLImageTargetTexture2DOES) { 181cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the proc EGLImageTargetTexture2DOES"); 182cb93a386Sopenharmony_ci return false; 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci fEGLCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) eglGetProcAddress("eglCreateSyncKHR"); 186cb93a386Sopenharmony_ci if (!fEGLCreateSyncKHR) { 187cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the proc eglCreateSyncKHR"); 188cb93a386Sopenharmony_ci return false; 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ci } 191cb93a386Sopenharmony_ci fEGLWaitSyncKHR = (PFNEGLWAITSYNCKHRPROC) eglGetProcAddress("eglWaitSyncKHR"); 192cb93a386Sopenharmony_ci if (!fEGLWaitSyncKHR) { 193cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the proc eglWaitSyncKHR"); 194cb93a386Sopenharmony_ci return false; 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci } 197cb93a386Sopenharmony_ci fEGLGetSyncAttribKHR = (PFNEGLGETSYNCATTRIBKHRPROC) eglGetProcAddress("eglGetSyncAttribKHR"); 198cb93a386Sopenharmony_ci if (!fEGLGetSyncAttribKHR) { 199cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the proc eglGetSyncAttribKHR"); 200cb93a386Sopenharmony_ci return false; 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ci } 203cb93a386Sopenharmony_ci fEGLDupNativeFenceFDANDROID = 204cb93a386Sopenharmony_ci (PFNEGLDUPNATIVEFENCEFDANDROIDPROC) eglGetProcAddress("eglDupNativeFenceFDANDROID"); 205cb93a386Sopenharmony_ci if (!fEGLDupNativeFenceFDANDROID) { 206cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the proc eglDupNativeFenceFDANDROID"); 207cb93a386Sopenharmony_ci return false; 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci } 210cb93a386Sopenharmony_ci fEGLDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) eglGetProcAddress("eglDestroySyncKHR"); 211cb93a386Sopenharmony_ci if (!fEGLDestroySyncKHR) { 212cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to get the proc eglDestroySyncKHR"); 213cb93a386Sopenharmony_ci return false; 214cb93a386Sopenharmony_ci 215cb93a386Sopenharmony_ci } 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ci return true; 218cb93a386Sopenharmony_ci} 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_cibool EGLTestHelper::importHardwareBuffer(skiatest::Reporter* reporter, AHardwareBuffer* buffer) { 221cb93a386Sopenharmony_ci while (fGLCtx->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {} 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_ci EGLClientBuffer eglClientBuffer = fEGLGetNativeClientBufferANDROID(buffer); 224cb93a386Sopenharmony_ci EGLint eglAttribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 225cb93a386Sopenharmony_ci EGL_NONE }; 226cb93a386Sopenharmony_ci EGLDisplay eglDisplay = eglGetCurrentDisplay(); 227cb93a386Sopenharmony_ci fImage = fEGLCreateImageKHR(eglDisplay, EGL_NO_CONTEXT, 228cb93a386Sopenharmony_ci EGL_NATIVE_BUFFER_ANDROID, 229cb93a386Sopenharmony_ci eglClientBuffer, eglAttribs); 230cb93a386Sopenharmony_ci if (EGL_NO_IMAGE_KHR == fImage) { 231cb93a386Sopenharmony_ci SkDebugf("Could not create EGL image, err = (%#x)\n", (int) eglGetError() ); 232cb93a386Sopenharmony_ci return false; 233cb93a386Sopenharmony_ci } 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci GR_GL_CALL(fGLCtx->gl(), GenTextures(1, &fTexID)); 236cb93a386Sopenharmony_ci if (!fTexID) { 237cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to create GL Texture"); 238cb93a386Sopenharmony_ci return false; 239cb93a386Sopenharmony_ci } 240cb93a386Sopenharmony_ci GR_GL_CALL_NOERRCHECK(fGLCtx->gl(), BindTexture(GR_GL_TEXTURE_2D, fTexID)); 241cb93a386Sopenharmony_ci if (fGLCtx->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) { 242cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to bind GL Texture"); 243cb93a386Sopenharmony_ci return false; 244cb93a386Sopenharmony_ci } 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_ci fEGLImageTargetTexture2DOES(GL_TEXTURE_2D, fImage); 247cb93a386Sopenharmony_ci if (GrGLenum error = fGLCtx->gl()->fFunctions.fGetError(); error != GR_GL_NO_ERROR) { 248cb93a386Sopenharmony_ci ERRORF(reporter, "EGLImageTargetTexture2DOES failed (%#x)", (int) error); 249cb93a386Sopenharmony_ci return false; 250cb93a386Sopenharmony_ci } 251cb93a386Sopenharmony_ci 252cb93a386Sopenharmony_ci fDirectContext->resetContext(kTextureBinding_GrGLBackendState); 253cb93a386Sopenharmony_ci return true; 254cb93a386Sopenharmony_ci} 255cb93a386Sopenharmony_ci 256cb93a386Sopenharmony_cisk_sp<SkImage> EGLTestHelper::importHardwareBufferForRead(skiatest::Reporter* reporter, 257cb93a386Sopenharmony_ci AHardwareBuffer* buffer) { 258cb93a386Sopenharmony_ci if (!this->importHardwareBuffer(reporter, buffer)) { 259cb93a386Sopenharmony_ci return nullptr; 260cb93a386Sopenharmony_ci } 261cb93a386Sopenharmony_ci GrGLTextureInfo textureInfo; 262cb93a386Sopenharmony_ci textureInfo.fTarget = GR_GL_TEXTURE_2D; 263cb93a386Sopenharmony_ci textureInfo.fID = fTexID; 264cb93a386Sopenharmony_ci textureInfo.fFormat = GR_GL_RGBA8; 265cb93a386Sopenharmony_ci 266cb93a386Sopenharmony_ci GrBackendTexture backendTex(DEV_W, DEV_H, GrMipmapped::kNo, textureInfo); 267cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.isValid()); 268cb93a386Sopenharmony_ci 269cb93a386Sopenharmony_ci sk_sp<SkImage> image = SkImage::MakeFromTexture(fDirectContext, 270cb93a386Sopenharmony_ci backendTex, 271cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 272cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 273cb93a386Sopenharmony_ci kPremul_SkAlphaType, 274cb93a386Sopenharmony_ci nullptr); 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci if (!image) { 277cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to make wrapped GL SkImage"); 278cb93a386Sopenharmony_ci return nullptr; 279cb93a386Sopenharmony_ci } 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ci return image; 282cb93a386Sopenharmony_ci} 283cb93a386Sopenharmony_ci 284cb93a386Sopenharmony_cisk_sp<SkSurface> EGLTestHelper::importHardwareBufferForWrite(skiatest::Reporter* reporter, 285cb93a386Sopenharmony_ci AHardwareBuffer* buffer) { 286cb93a386Sopenharmony_ci if (!this->importHardwareBuffer(reporter, buffer)) { 287cb93a386Sopenharmony_ci return nullptr; 288cb93a386Sopenharmony_ci } 289cb93a386Sopenharmony_ci GrGLTextureInfo textureInfo; 290cb93a386Sopenharmony_ci textureInfo.fTarget = GR_GL_TEXTURE_2D; 291cb93a386Sopenharmony_ci textureInfo.fID = fTexID; 292cb93a386Sopenharmony_ci textureInfo.fFormat = GR_GL_RGBA8; 293cb93a386Sopenharmony_ci 294cb93a386Sopenharmony_ci GrBackendTexture backendTex(DEV_W, DEV_H, GrMipmapped::kNo, textureInfo); 295cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.isValid()); 296cb93a386Sopenharmony_ci 297cb93a386Sopenharmony_ci sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(fDirectContext, 298cb93a386Sopenharmony_ci backendTex, 299cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 300cb93a386Sopenharmony_ci 0, 301cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 302cb93a386Sopenharmony_ci nullptr, nullptr); 303cb93a386Sopenharmony_ci 304cb93a386Sopenharmony_ci if (!surface) { 305cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to make wrapped GL SkSurface"); 306cb93a386Sopenharmony_ci return nullptr; 307cb93a386Sopenharmony_ci } 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ci return surface; 310cb93a386Sopenharmony_ci} 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_cibool EGLTestHelper::flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, 313cb93a386Sopenharmony_ci sk_sp<SkSurface> surface) { 314cb93a386Sopenharmony_ci EGLDisplay eglDisplay = eglGetCurrentDisplay(); 315cb93a386Sopenharmony_ci EGLSyncKHR eglsync = fEGLCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); 316cb93a386Sopenharmony_ci if (EGL_NO_SYNC_KHR == eglsync) { 317cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to create EGLSync for EGL_SYNC_NATIVE_FENCE_ANDROID\n"); 318cb93a386Sopenharmony_ci return false; 319cb93a386Sopenharmony_ci } 320cb93a386Sopenharmony_ci 321cb93a386Sopenharmony_ci surface->flushAndSubmit(); 322cb93a386Sopenharmony_ci GR_GL_CALL(fGLCtx->gl(), Flush()); 323cb93a386Sopenharmony_ci fFdHandle = fEGLDupNativeFenceFDANDROID(eglDisplay, eglsync); 324cb93a386Sopenharmony_ci 325cb93a386Sopenharmony_ci EGLint result = fEGLDestroySyncKHR(eglDisplay, eglsync); 326cb93a386Sopenharmony_ci if (EGL_TRUE != result) { 327cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to delete EGLSync, error: %d\n", result); 328cb93a386Sopenharmony_ci return false; 329cb93a386Sopenharmony_ci } 330cb93a386Sopenharmony_ci 331cb93a386Sopenharmony_ci return true; 332cb93a386Sopenharmony_ci} 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_cibool EGLTestHelper::importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle, 335cb93a386Sopenharmony_ci sk_sp<SkSurface> surface) { 336cb93a386Sopenharmony_ci EGLDisplay eglDisplay = eglGetCurrentDisplay(); 337cb93a386Sopenharmony_ci EGLint attr[] = { 338cb93a386Sopenharmony_ci EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fdHandle, 339cb93a386Sopenharmony_ci EGL_NONE 340cb93a386Sopenharmony_ci }; 341cb93a386Sopenharmony_ci EGLSyncKHR eglsync = fEGLCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attr); 342cb93a386Sopenharmony_ci if (EGL_NO_SYNC_KHR == eglsync) { 343cb93a386Sopenharmony_ci ERRORF(reporter, 344cb93a386Sopenharmony_ci "Failed to create EGLSync when importing EGL_SYNC_NATIVE_FENCE_FD_ANDROID\n"); 345cb93a386Sopenharmony_ci return false; 346cb93a386Sopenharmony_ci } 347cb93a386Sopenharmony_ci EGLint result = fEGLWaitSyncKHR(eglDisplay, eglsync, 0); 348cb93a386Sopenharmony_ci if (EGL_TRUE != result) { 349cb93a386Sopenharmony_ci ERRORF(reporter, "Failed called to eglWaitSyncKHR, error: %d\n", result); 350cb93a386Sopenharmony_ci // Don't return false yet, try to delete the sync first 351cb93a386Sopenharmony_ci } 352cb93a386Sopenharmony_ci result = fEGLDestroySyncKHR(eglDisplay, eglsync); 353cb93a386Sopenharmony_ci if (EGL_TRUE != result) { 354cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to delete EGLSync, error: %d\n", result); 355cb93a386Sopenharmony_ci return false; 356cb93a386Sopenharmony_ci } 357cb93a386Sopenharmony_ci return true; 358cb93a386Sopenharmony_ci} 359cb93a386Sopenharmony_ci 360cb93a386Sopenharmony_civoid EGLTestHelper::doClientSync() { 361cb93a386Sopenharmony_ci this->directContext()->flush(); 362cb93a386Sopenharmony_ci this->directContext()->submit(true); 363cb93a386Sopenharmony_ci} 364cb93a386Sopenharmony_ci#endif // SK_GL 365cb93a386Sopenharmony_ci 366cb93a386Sopenharmony_ci#define DECLARE_VK_PROC(name) PFN_vk##name fVk##name 367cb93a386Sopenharmony_ci 368cb93a386Sopenharmony_ci#define ACQUIRE_INST_VK_PROC(name) \ 369cb93a386Sopenharmony_ci do { \ 370cb93a386Sopenharmony_ci fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\ 371cb93a386Sopenharmony_ci VK_NULL_HANDLE)); \ 372cb93a386Sopenharmony_ci if (fVk##name == nullptr) { \ 373cb93a386Sopenharmony_ci ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \ 374cb93a386Sopenharmony_ci return false; \ 375cb93a386Sopenharmony_ci } \ 376cb93a386Sopenharmony_ci } while(false) 377cb93a386Sopenharmony_ci 378cb93a386Sopenharmony_ci#define ACQUIRE_DEVICE_VK_PROC(name) \ 379cb93a386Sopenharmony_ci do { \ 380cb93a386Sopenharmony_ci fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \ 381cb93a386Sopenharmony_ci if (fVk##name == nullptr) { \ 382cb93a386Sopenharmony_ci ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \ 383cb93a386Sopenharmony_ci return false; \ 384cb93a386Sopenharmony_ci } \ 385cb93a386Sopenharmony_ci } while(false) 386cb93a386Sopenharmony_ci 387cb93a386Sopenharmony_ciclass VulkanTestHelper : public BaseTestHelper { 388cb93a386Sopenharmony_cipublic: 389cb93a386Sopenharmony_ci VulkanTestHelper() {} 390cb93a386Sopenharmony_ci 391cb93a386Sopenharmony_ci ~VulkanTestHelper() override {} 392cb93a386Sopenharmony_ci 393cb93a386Sopenharmony_ci void releaseImage() override { 394cb93a386Sopenharmony_ci if (VK_NULL_HANDLE == fDevice) { 395cb93a386Sopenharmony_ci return; 396cb93a386Sopenharmony_ci } 397cb93a386Sopenharmony_ci if (fImage != VK_NULL_HANDLE) { 398cb93a386Sopenharmony_ci fVkDestroyImage(fDevice, fImage, nullptr); 399cb93a386Sopenharmony_ci fImage = VK_NULL_HANDLE; 400cb93a386Sopenharmony_ci } 401cb93a386Sopenharmony_ci 402cb93a386Sopenharmony_ci if (fMemory != VK_NULL_HANDLE) { 403cb93a386Sopenharmony_ci fVkFreeMemory(fDevice, fMemory, nullptr); 404cb93a386Sopenharmony_ci fMemory = VK_NULL_HANDLE; 405cb93a386Sopenharmony_ci } 406cb93a386Sopenharmony_ci } 407cb93a386Sopenharmony_ci void cleanup() override { 408cb93a386Sopenharmony_ci fDirectContext.reset(); 409cb93a386Sopenharmony_ci this->releaseImage(); 410cb93a386Sopenharmony_ci if (fSignalSemaphore != VK_NULL_HANDLE) { 411cb93a386Sopenharmony_ci fVkDestroySemaphore(fDevice, fSignalSemaphore, nullptr); 412cb93a386Sopenharmony_ci fSignalSemaphore = VK_NULL_HANDLE; 413cb93a386Sopenharmony_ci } 414cb93a386Sopenharmony_ci fBackendContext.fMemoryAllocator.reset(); 415cb93a386Sopenharmony_ci if (fDevice != VK_NULL_HANDLE) { 416cb93a386Sopenharmony_ci fVkDeviceWaitIdle(fDevice); 417cb93a386Sopenharmony_ci fVkDestroyDevice(fDevice, nullptr); 418cb93a386Sopenharmony_ci fDevice = VK_NULL_HANDLE; 419cb93a386Sopenharmony_ci } 420cb93a386Sopenharmony_ci#ifdef SK_ENABLE_VK_LAYERS 421cb93a386Sopenharmony_ci if (fDebugCallback != VK_NULL_HANDLE) { 422cb93a386Sopenharmony_ci fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr); 423cb93a386Sopenharmony_ci } 424cb93a386Sopenharmony_ci#endif 425cb93a386Sopenharmony_ci if (fBackendContext.fInstance != VK_NULL_HANDLE) { 426cb93a386Sopenharmony_ci fVkDestroyInstance(fBackendContext.fInstance, nullptr); 427cb93a386Sopenharmony_ci fBackendContext.fInstance = VK_NULL_HANDLE; 428cb93a386Sopenharmony_ci } 429cb93a386Sopenharmony_ci 430cb93a386Sopenharmony_ci delete fExtensions; 431cb93a386Sopenharmony_ci 432cb93a386Sopenharmony_ci sk_gpu_test::FreeVulkanFeaturesStructs(fFeatures); 433cb93a386Sopenharmony_ci delete fFeatures; 434cb93a386Sopenharmony_ci } 435cb93a386Sopenharmony_ci 436cb93a386Sopenharmony_ci bool init(skiatest::Reporter* reporter) override; 437cb93a386Sopenharmony_ci 438cb93a386Sopenharmony_ci void doClientSync() override { 439cb93a386Sopenharmony_ci if (!fDirectContext) { 440cb93a386Sopenharmony_ci return; 441cb93a386Sopenharmony_ci } 442cb93a386Sopenharmony_ci 443cb93a386Sopenharmony_ci fDirectContext->submit(true); 444cb93a386Sopenharmony_ci } 445cb93a386Sopenharmony_ci 446cb93a386Sopenharmony_ci bool flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, sk_sp<SkSurface>) override; 447cb93a386Sopenharmony_ci bool importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle, 448cb93a386Sopenharmony_ci sk_sp<SkSurface>) override; 449cb93a386Sopenharmony_ci 450cb93a386Sopenharmony_ci sk_sp<SkImage> importHardwareBufferForRead(skiatest::Reporter* reporter, 451cb93a386Sopenharmony_ci AHardwareBuffer* buffer) override; 452cb93a386Sopenharmony_ci 453cb93a386Sopenharmony_ci sk_sp<SkSurface> importHardwareBufferForWrite(skiatest::Reporter* reporter, 454cb93a386Sopenharmony_ci AHardwareBuffer* buffer) override; 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_ci void makeCurrent() override {} 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_ci GrDirectContext* directContext() override { return fDirectContext.get(); } 459cb93a386Sopenharmony_ci 460cb93a386Sopenharmony_ciprivate: 461cb93a386Sopenharmony_ci bool checkOptimalHardwareBuffer(skiatest::Reporter* reporter); 462cb93a386Sopenharmony_ci 463cb93a386Sopenharmony_ci bool importHardwareBuffer(skiatest::Reporter* reporter, AHardwareBuffer* buffer, bool forWrite, 464cb93a386Sopenharmony_ci GrVkImageInfo* outImageInfo); 465cb93a386Sopenharmony_ci 466cb93a386Sopenharmony_ci bool setupSemaphoreForSignaling(skiatest::Reporter* reporter, GrBackendSemaphore*); 467cb93a386Sopenharmony_ci bool exportSemaphore(skiatest::Reporter* reporter, const GrBackendSemaphore&); 468cb93a386Sopenharmony_ci 469cb93a386Sopenharmony_ci DECLARE_VK_PROC(DestroyInstance); 470cb93a386Sopenharmony_ci DECLARE_VK_PROC(DeviceWaitIdle); 471cb93a386Sopenharmony_ci DECLARE_VK_PROC(DestroyDevice); 472cb93a386Sopenharmony_ci 473cb93a386Sopenharmony_ci DECLARE_VK_PROC(GetPhysicalDeviceExternalSemaphoreProperties); 474cb93a386Sopenharmony_ci DECLARE_VK_PROC(GetPhysicalDeviceImageFormatProperties2); 475cb93a386Sopenharmony_ci DECLARE_VK_PROC(GetPhysicalDeviceMemoryProperties2); 476cb93a386Sopenharmony_ci 477cb93a386Sopenharmony_ci DECLARE_VK_PROC(GetAndroidHardwareBufferPropertiesANDROID); 478cb93a386Sopenharmony_ci 479cb93a386Sopenharmony_ci DECLARE_VK_PROC(CreateImage); 480cb93a386Sopenharmony_ci DECLARE_VK_PROC(GetImageMemoryRequirements2); 481cb93a386Sopenharmony_ci DECLARE_VK_PROC(DestroyImage); 482cb93a386Sopenharmony_ci 483cb93a386Sopenharmony_ci DECLARE_VK_PROC(AllocateMemory); 484cb93a386Sopenharmony_ci DECLARE_VK_PROC(BindImageMemory2); 485cb93a386Sopenharmony_ci DECLARE_VK_PROC(FreeMemory); 486cb93a386Sopenharmony_ci 487cb93a386Sopenharmony_ci DECLARE_VK_PROC(CreateSemaphore); 488cb93a386Sopenharmony_ci DECLARE_VK_PROC(GetSemaphoreFdKHR); 489cb93a386Sopenharmony_ci DECLARE_VK_PROC(ImportSemaphoreFdKHR); 490cb93a386Sopenharmony_ci DECLARE_VK_PROC(DestroySemaphore); 491cb93a386Sopenharmony_ci 492cb93a386Sopenharmony_ci VkImage fImage = VK_NULL_HANDLE; 493cb93a386Sopenharmony_ci VkDeviceMemory fMemory = VK_NULL_HANDLE; 494cb93a386Sopenharmony_ci 495cb93a386Sopenharmony_ci GrVkExtensions* fExtensions = nullptr; 496cb93a386Sopenharmony_ci VkPhysicalDeviceFeatures2* fFeatures = nullptr; 497cb93a386Sopenharmony_ci VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE; 498cb93a386Sopenharmony_ci PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugCallback = nullptr; 499cb93a386Sopenharmony_ci 500cb93a386Sopenharmony_ci // We hold on to the semaphore so we can delete once the GPU is done. 501cb93a386Sopenharmony_ci VkSemaphore fSignalSemaphore = VK_NULL_HANDLE; 502cb93a386Sopenharmony_ci 503cb93a386Sopenharmony_ci VkDevice fDevice = VK_NULL_HANDLE; 504cb93a386Sopenharmony_ci 505cb93a386Sopenharmony_ci GrVkBackendContext fBackendContext; 506cb93a386Sopenharmony_ci sk_sp<GrDirectContext> fDirectContext; 507cb93a386Sopenharmony_ci}; 508cb93a386Sopenharmony_ci 509cb93a386Sopenharmony_cibool VulkanTestHelper::init(skiatest::Reporter* reporter) { 510cb93a386Sopenharmony_ci PFN_vkGetInstanceProcAddr instProc; 511cb93a386Sopenharmony_ci PFN_vkGetDeviceProcAddr devProc; 512cb93a386Sopenharmony_ci if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) { 513cb93a386Sopenharmony_ci return false; 514cb93a386Sopenharmony_ci } 515cb93a386Sopenharmony_ci auto getProc = [&instProc, &devProc](const char* proc_name, 516cb93a386Sopenharmony_ci VkInstance instance, VkDevice device) { 517cb93a386Sopenharmony_ci if (device != VK_NULL_HANDLE) { 518cb93a386Sopenharmony_ci return devProc(device, proc_name); 519cb93a386Sopenharmony_ci } 520cb93a386Sopenharmony_ci return instProc(instance, proc_name); 521cb93a386Sopenharmony_ci }; 522cb93a386Sopenharmony_ci 523cb93a386Sopenharmony_ci fExtensions = new GrVkExtensions(); 524cb93a386Sopenharmony_ci fFeatures = new VkPhysicalDeviceFeatures2; 525cb93a386Sopenharmony_ci memset(fFeatures, 0, sizeof(VkPhysicalDeviceFeatures2)); 526cb93a386Sopenharmony_ci fFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 527cb93a386Sopenharmony_ci fFeatures->pNext = nullptr; 528cb93a386Sopenharmony_ci 529cb93a386Sopenharmony_ci fBackendContext.fInstance = VK_NULL_HANDLE; 530cb93a386Sopenharmony_ci fBackendContext.fDevice = VK_NULL_HANDLE; 531cb93a386Sopenharmony_ci 532cb93a386Sopenharmony_ci if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, fExtensions, 533cb93a386Sopenharmony_ci fFeatures, &fDebugCallback)) { 534cb93a386Sopenharmony_ci return false; 535cb93a386Sopenharmony_ci } 536cb93a386Sopenharmony_ci fDevice = fBackendContext.fDevice; 537cb93a386Sopenharmony_ci 538cb93a386Sopenharmony_ci if (fDebugCallback != VK_NULL_HANDLE) { 539cb93a386Sopenharmony_ci fDestroyDebugCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc( 540cb93a386Sopenharmony_ci fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT"); 541cb93a386Sopenharmony_ci } 542cb93a386Sopenharmony_ci 543cb93a386Sopenharmony_ci ACQUIRE_INST_VK_PROC(DestroyInstance); 544cb93a386Sopenharmony_ci ACQUIRE_INST_VK_PROC(DeviceWaitIdle); 545cb93a386Sopenharmony_ci ACQUIRE_INST_VK_PROC(DestroyDevice); 546cb93a386Sopenharmony_ci 547cb93a386Sopenharmony_ci if (!fExtensions->hasExtension(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, 548cb93a386Sopenharmony_ci 2)) { 549cb93a386Sopenharmony_ci return false; 550cb93a386Sopenharmony_ci } 551cb93a386Sopenharmony_ci if (!fExtensions->hasExtension(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, 1)) { 552cb93a386Sopenharmony_ci return false; 553cb93a386Sopenharmony_ci } 554cb93a386Sopenharmony_ci if (!fExtensions->hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)) { 555cb93a386Sopenharmony_ci return false; 556cb93a386Sopenharmony_ci } 557cb93a386Sopenharmony_ci if (!fExtensions->hasExtension(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, 1)) { 558cb93a386Sopenharmony_ci // return false; 559cb93a386Sopenharmony_ci } 560cb93a386Sopenharmony_ci 561cb93a386Sopenharmony_ci ACQUIRE_INST_VK_PROC(GetPhysicalDeviceMemoryProperties2); 562cb93a386Sopenharmony_ci ACQUIRE_INST_VK_PROC(GetPhysicalDeviceImageFormatProperties2); 563cb93a386Sopenharmony_ci ACQUIRE_INST_VK_PROC(GetPhysicalDeviceExternalSemaphoreProperties); 564cb93a386Sopenharmony_ci 565cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(GetAndroidHardwareBufferPropertiesANDROID); 566cb93a386Sopenharmony_ci 567cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(CreateImage); 568cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(GetImageMemoryRequirements2); 569cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(DestroyImage); 570cb93a386Sopenharmony_ci 571cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(AllocateMemory); 572cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(BindImageMemory2); 573cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(FreeMemory); 574cb93a386Sopenharmony_ci 575cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(CreateSemaphore); 576cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(GetSemaphoreFdKHR); 577cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(ImportSemaphoreFdKHR); 578cb93a386Sopenharmony_ci ACQUIRE_DEVICE_VK_PROC(DestroySemaphore); 579cb93a386Sopenharmony_ci 580cb93a386Sopenharmony_ci fDirectContext = GrDirectContext::MakeVulkan(fBackendContext); 581cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, fDirectContext.get()); 582cb93a386Sopenharmony_ci if (!fDirectContext) { 583cb93a386Sopenharmony_ci return false; 584cb93a386Sopenharmony_ci } 585cb93a386Sopenharmony_ci 586cb93a386Sopenharmony_ci return this->checkOptimalHardwareBuffer(reporter); 587cb93a386Sopenharmony_ci} 588cb93a386Sopenharmony_ci 589cb93a386Sopenharmony_cibool VulkanTestHelper::checkOptimalHardwareBuffer(skiatest::Reporter* reporter) { 590cb93a386Sopenharmony_ci VkResult err; 591cb93a386Sopenharmony_ci 592cb93a386Sopenharmony_ci VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo; 593cb93a386Sopenharmony_ci externalImageFormatInfo.sType = 594cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO; 595cb93a386Sopenharmony_ci externalImageFormatInfo.pNext = nullptr; 596cb93a386Sopenharmony_ci externalImageFormatInfo.handleType = 597cb93a386Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; 598cb93a386Sopenharmony_ci //externalImageFormatInfo.handType = 0x80; 599cb93a386Sopenharmony_ci 600cb93a386Sopenharmony_ci // We will create the hardware buffer with gpu sampled so these usages should all be valid 601cb93a386Sopenharmony_ci VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | 602cb93a386Sopenharmony_ci VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 603cb93a386Sopenharmony_ci VK_IMAGE_USAGE_TRANSFER_DST_BIT; 604cb93a386Sopenharmony_ci VkPhysicalDeviceImageFormatInfo2 imageFormatInfo; 605cb93a386Sopenharmony_ci imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2; 606cb93a386Sopenharmony_ci imageFormatInfo.pNext = &externalImageFormatInfo; 607cb93a386Sopenharmony_ci imageFormatInfo.format = VK_FORMAT_R8G8B8A8_UNORM; 608cb93a386Sopenharmony_ci imageFormatInfo.type = VK_IMAGE_TYPE_2D; 609cb93a386Sopenharmony_ci imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL; 610cb93a386Sopenharmony_ci imageFormatInfo.usage = usageFlags; 611cb93a386Sopenharmony_ci imageFormatInfo.flags = 0; 612cb93a386Sopenharmony_ci 613cb93a386Sopenharmony_ci VkAndroidHardwareBufferUsageANDROID hwbUsage; 614cb93a386Sopenharmony_ci hwbUsage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID; 615cb93a386Sopenharmony_ci hwbUsage.pNext = nullptr; 616cb93a386Sopenharmony_ci 617cb93a386Sopenharmony_ci VkExternalImageFormatProperties externalImgFormatProps; 618cb93a386Sopenharmony_ci externalImgFormatProps.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES; 619cb93a386Sopenharmony_ci externalImgFormatProps.pNext = &hwbUsage; 620cb93a386Sopenharmony_ci 621cb93a386Sopenharmony_ci VkImageFormatProperties2 imgFormProps; 622cb93a386Sopenharmony_ci imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; 623cb93a386Sopenharmony_ci imgFormProps.pNext = &externalImgFormatProps; 624cb93a386Sopenharmony_ci 625cb93a386Sopenharmony_ci err = fVkGetPhysicalDeviceImageFormatProperties2(fBackendContext.fPhysicalDevice, 626cb93a386Sopenharmony_ci &imageFormatInfo, &imgFormProps); 627cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 628cb93a386Sopenharmony_ci ERRORF(reporter, "vkGetPhysicalDeviceImageFormatProperites failed, err: %d", err); 629cb93a386Sopenharmony_ci return false; 630cb93a386Sopenharmony_ci } 631cb93a386Sopenharmony_ci 632cb93a386Sopenharmony_ci const VkImageFormatProperties& imageFormatProperties = imgFormProps.imageFormatProperties; 633cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, DEV_W <= imageFormatProperties.maxExtent.width); 634cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, DEV_H <= imageFormatProperties.maxExtent.height); 635cb93a386Sopenharmony_ci 636cb93a386Sopenharmony_ci const VkExternalMemoryProperties& externalImageFormatProps = 637cb93a386Sopenharmony_ci externalImgFormatProps.externalMemoryProperties; 638cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SkToBool(VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT & 639cb93a386Sopenharmony_ci externalImageFormatProps.externalMemoryFeatures)); 640cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SkToBool(VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT & 641cb93a386Sopenharmony_ci externalImageFormatProps.externalMemoryFeatures)); 642cb93a386Sopenharmony_ci 643cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, SkToBool(AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE & 644cb93a386Sopenharmony_ci hwbUsage.androidHardwareBufferUsage)); 645cb93a386Sopenharmony_ci 646cb93a386Sopenharmony_ci return true; 647cb93a386Sopenharmony_ci} 648cb93a386Sopenharmony_ci 649cb93a386Sopenharmony_cibool VulkanTestHelper::importHardwareBuffer(skiatest::Reporter* reporter, 650cb93a386Sopenharmony_ci AHardwareBuffer* buffer, 651cb93a386Sopenharmony_ci bool forWrite, 652cb93a386Sopenharmony_ci GrVkImageInfo* outImageInfo) { 653cb93a386Sopenharmony_ci VkResult err; 654cb93a386Sopenharmony_ci 655cb93a386Sopenharmony_ci VkAndroidHardwareBufferFormatPropertiesANDROID hwbFormatProps; 656cb93a386Sopenharmony_ci hwbFormatProps.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID; 657cb93a386Sopenharmony_ci hwbFormatProps.pNext = nullptr; 658cb93a386Sopenharmony_ci 659cb93a386Sopenharmony_ci VkAndroidHardwareBufferPropertiesANDROID hwbProps; 660cb93a386Sopenharmony_ci hwbProps.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID; 661cb93a386Sopenharmony_ci hwbProps.pNext = &hwbFormatProps; 662cb93a386Sopenharmony_ci 663cb93a386Sopenharmony_ci err = fVkGetAndroidHardwareBufferPropertiesANDROID(fDevice, buffer, &hwbProps); 664cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 665cb93a386Sopenharmony_ci ERRORF(reporter, "GetAndroidHardwareBufferPropertiesAndroid failed, err: %d", err); 666cb93a386Sopenharmony_ci return false; 667cb93a386Sopenharmony_ci } 668cb93a386Sopenharmony_ci 669cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_FORMAT_R8G8B8A8_UNORM == hwbFormatProps.format); 670cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 671cb93a386Sopenharmony_ci SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & hwbFormatProps.formatFeatures) && 672cb93a386Sopenharmony_ci SkToBool(VK_FORMAT_FEATURE_TRANSFER_SRC_BIT & hwbFormatProps.formatFeatures) && 673cb93a386Sopenharmony_ci SkToBool(VK_FORMAT_FEATURE_TRANSFER_DST_BIT & hwbFormatProps.formatFeatures)); 674cb93a386Sopenharmony_ci if (forWrite) { 675cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 676cb93a386Sopenharmony_ci SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT & hwbFormatProps.formatFeatures)); 677cb93a386Sopenharmony_ci 678cb93a386Sopenharmony_ci } 679cb93a386Sopenharmony_ci 680cb93a386Sopenharmony_ci bool useExternalFormat = VK_FORMAT_UNDEFINED == hwbFormatProps.format; 681cb93a386Sopenharmony_ci const VkExternalFormatANDROID externalFormatInfo { 682cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID, // sType 683cb93a386Sopenharmony_ci nullptr, // pNext 684cb93a386Sopenharmony_ci useExternalFormat ? hwbFormatProps.externalFormat : 0, // externalFormat 685cb93a386Sopenharmony_ci }; 686cb93a386Sopenharmony_ci 687cb93a386Sopenharmony_ci const VkExternalMemoryImageCreateInfo externalMemoryImageInfo { 688cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, // sType 689cb93a386Sopenharmony_ci &externalFormatInfo, // pNext 690cb93a386Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, // handleTypes 691cb93a386Sopenharmony_ci }; 692cb93a386Sopenharmony_ci 693cb93a386Sopenharmony_ci VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | 694cb93a386Sopenharmony_ci VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 695cb93a386Sopenharmony_ci VK_IMAGE_USAGE_TRANSFER_DST_BIT; 696cb93a386Sopenharmony_ci if (forWrite) { 697cb93a386Sopenharmony_ci usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 698cb93a386Sopenharmony_ci } 699cb93a386Sopenharmony_ci 700cb93a386Sopenharmony_ci const VkImageCreateInfo imageCreateInfo = { 701cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 702cb93a386Sopenharmony_ci &externalMemoryImageInfo, // pNext 703cb93a386Sopenharmony_ci 0, // VkImageCreateFlags 704cb93a386Sopenharmony_ci VK_IMAGE_TYPE_2D, // VkImageType 705cb93a386Sopenharmony_ci hwbFormatProps.format, // VkFormat 706cb93a386Sopenharmony_ci { DEV_W, DEV_H, 1 }, // VkExtent3D 707cb93a386Sopenharmony_ci 1, // mipLevels 708cb93a386Sopenharmony_ci 1, // arrayLayers 709cb93a386Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // samples 710cb93a386Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling 711cb93a386Sopenharmony_ci usageFlags, // VkImageUsageFlags 712cb93a386Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode 713cb93a386Sopenharmony_ci 0, // queueFamilyCount 714cb93a386Sopenharmony_ci 0, // pQueueFamilyIndices 715cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout 716cb93a386Sopenharmony_ci }; 717cb93a386Sopenharmony_ci 718cb93a386Sopenharmony_ci err = fVkCreateImage(fDevice, &imageCreateInfo, nullptr, &fImage); 719cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 720cb93a386Sopenharmony_ci ERRORF(reporter, "Create Image failed, err: %d", err); 721cb93a386Sopenharmony_ci return false; 722cb93a386Sopenharmony_ci } 723cb93a386Sopenharmony_ci 724cb93a386Sopenharmony_ci VkPhysicalDeviceMemoryProperties2 phyDevMemProps; 725cb93a386Sopenharmony_ci phyDevMemProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; 726cb93a386Sopenharmony_ci phyDevMemProps.pNext = nullptr; 727cb93a386Sopenharmony_ci 728cb93a386Sopenharmony_ci uint32_t typeIndex = 0; 729cb93a386Sopenharmony_ci uint32_t heapIndex = 0; 730cb93a386Sopenharmony_ci bool foundHeap = false; 731cb93a386Sopenharmony_ci fVkGetPhysicalDeviceMemoryProperties2(fBackendContext.fPhysicalDevice, &phyDevMemProps); 732cb93a386Sopenharmony_ci uint32_t memTypeCnt = phyDevMemProps.memoryProperties.memoryTypeCount; 733cb93a386Sopenharmony_ci for (uint32_t i = 0; i < memTypeCnt && !foundHeap; ++i) { 734cb93a386Sopenharmony_ci if (hwbProps.memoryTypeBits & (1 << i)) { 735cb93a386Sopenharmony_ci const VkPhysicalDeviceMemoryProperties& pdmp = phyDevMemProps.memoryProperties; 736cb93a386Sopenharmony_ci uint32_t supportedFlags = pdmp.memoryTypes[i].propertyFlags & 737cb93a386Sopenharmony_ci VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 738cb93a386Sopenharmony_ci if (supportedFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) { 739cb93a386Sopenharmony_ci typeIndex = i; 740cb93a386Sopenharmony_ci heapIndex = pdmp.memoryTypes[i].heapIndex; 741cb93a386Sopenharmony_ci foundHeap = true; 742cb93a386Sopenharmony_ci } 743cb93a386Sopenharmony_ci } 744cb93a386Sopenharmony_ci } 745cb93a386Sopenharmony_ci if (!foundHeap) { 746cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to find valid heap for imported memory"); 747cb93a386Sopenharmony_ci return false; 748cb93a386Sopenharmony_ci } 749cb93a386Sopenharmony_ci 750cb93a386Sopenharmony_ci VkImportAndroidHardwareBufferInfoANDROID hwbImportInfo; 751cb93a386Sopenharmony_ci hwbImportInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID; 752cb93a386Sopenharmony_ci hwbImportInfo.pNext = nullptr; 753cb93a386Sopenharmony_ci hwbImportInfo.buffer = buffer; 754cb93a386Sopenharmony_ci 755cb93a386Sopenharmony_ci VkMemoryDedicatedAllocateInfo dedicatedAllocInfo; 756cb93a386Sopenharmony_ci dedicatedAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; 757cb93a386Sopenharmony_ci dedicatedAllocInfo.pNext = &hwbImportInfo; 758cb93a386Sopenharmony_ci dedicatedAllocInfo.image = fImage; 759cb93a386Sopenharmony_ci dedicatedAllocInfo.buffer = VK_NULL_HANDLE; 760cb93a386Sopenharmony_ci 761cb93a386Sopenharmony_ci VkMemoryAllocateInfo allocInfo = { 762cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType 763cb93a386Sopenharmony_ci &dedicatedAllocInfo, // pNext 764cb93a386Sopenharmony_ci hwbProps.allocationSize, // allocationSize 765cb93a386Sopenharmony_ci typeIndex, // memoryTypeIndex 766cb93a386Sopenharmony_ci }; 767cb93a386Sopenharmony_ci 768cb93a386Sopenharmony_ci err = fVkAllocateMemory(fDevice, &allocInfo, nullptr, &fMemory); 769cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 770cb93a386Sopenharmony_ci ERRORF(reporter, "AllocateMemory failed for imported buffer, err: %d", err); 771cb93a386Sopenharmony_ci return false; 772cb93a386Sopenharmony_ci } 773cb93a386Sopenharmony_ci 774cb93a386Sopenharmony_ci VkBindImageMemoryInfo bindImageInfo; 775cb93a386Sopenharmony_ci bindImageInfo.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO; 776cb93a386Sopenharmony_ci bindImageInfo.pNext = nullptr; 777cb93a386Sopenharmony_ci bindImageInfo.image = fImage; 778cb93a386Sopenharmony_ci bindImageInfo.memory = fMemory; 779cb93a386Sopenharmony_ci bindImageInfo.memoryOffset = 0; 780cb93a386Sopenharmony_ci 781cb93a386Sopenharmony_ci err = fVkBindImageMemory2(fDevice, 1, &bindImageInfo); 782cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 783cb93a386Sopenharmony_ci ERRORF(reporter, "BindImageMemory failed for imported buffer, err: %d", err); 784cb93a386Sopenharmony_ci return false; 785cb93a386Sopenharmony_ci } 786cb93a386Sopenharmony_ci 787cb93a386Sopenharmony_ci GrVkAlloc alloc; 788cb93a386Sopenharmony_ci alloc.fMemory = fMemory; 789cb93a386Sopenharmony_ci alloc.fOffset = 0; 790cb93a386Sopenharmony_ci alloc.fSize = hwbProps.allocationSize; 791cb93a386Sopenharmony_ci alloc.fFlags = 0; 792cb93a386Sopenharmony_ci 793cb93a386Sopenharmony_ci outImageInfo->fImage = fImage; 794cb93a386Sopenharmony_ci outImageInfo->fAlloc = alloc; 795cb93a386Sopenharmony_ci outImageInfo->fImageTiling = VK_IMAGE_TILING_OPTIMAL; 796cb93a386Sopenharmony_ci outImageInfo->fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; 797cb93a386Sopenharmony_ci outImageInfo->fFormat = VK_FORMAT_R8G8B8A8_UNORM; 798cb93a386Sopenharmony_ci outImageInfo->fImageUsageFlags = usageFlags; 799cb93a386Sopenharmony_ci outImageInfo->fLevelCount = 1; 800cb93a386Sopenharmony_ci outImageInfo->fCurrentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL; 801cb93a386Sopenharmony_ci return true; 802cb93a386Sopenharmony_ci} 803cb93a386Sopenharmony_ci 804cb93a386Sopenharmony_cisk_sp<SkImage> VulkanTestHelper::importHardwareBufferForRead(skiatest::Reporter* reporter, 805cb93a386Sopenharmony_ci AHardwareBuffer* buffer) { 806cb93a386Sopenharmony_ci GrVkImageInfo imageInfo; 807cb93a386Sopenharmony_ci if (!this->importHardwareBuffer(reporter, buffer, false, &imageInfo)) { 808cb93a386Sopenharmony_ci return nullptr; 809cb93a386Sopenharmony_ci } 810cb93a386Sopenharmony_ci 811cb93a386Sopenharmony_ci GrBackendTexture backendTex(DEV_W, DEV_H, imageInfo); 812cb93a386Sopenharmony_ci 813cb93a386Sopenharmony_ci sk_sp<SkImage> wrappedImage = SkImage::MakeFromTexture(fDirectContext.get(), 814cb93a386Sopenharmony_ci backendTex, 815cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 816cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 817cb93a386Sopenharmony_ci kPremul_SkAlphaType, 818cb93a386Sopenharmony_ci nullptr); 819cb93a386Sopenharmony_ci 820cb93a386Sopenharmony_ci if (!wrappedImage.get()) { 821cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to create wrapped Vulkan SkImage"); 822cb93a386Sopenharmony_ci return nullptr; 823cb93a386Sopenharmony_ci } 824cb93a386Sopenharmony_ci 825cb93a386Sopenharmony_ci return wrappedImage; 826cb93a386Sopenharmony_ci} 827cb93a386Sopenharmony_ci 828cb93a386Sopenharmony_cibool VulkanTestHelper::flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, 829cb93a386Sopenharmony_ci sk_sp<SkSurface> surface) { 830cb93a386Sopenharmony_ci surface->flushAndSubmit(); 831cb93a386Sopenharmony_ci surface.reset(); 832cb93a386Sopenharmony_ci GrBackendSemaphore semaphore; 833cb93a386Sopenharmony_ci if (!this->setupSemaphoreForSignaling(reporter, &semaphore)) { 834cb93a386Sopenharmony_ci return false; 835cb93a386Sopenharmony_ci } 836cb93a386Sopenharmony_ci GrFlushInfo info; 837cb93a386Sopenharmony_ci info.fNumSemaphores = 1; 838cb93a386Sopenharmony_ci info.fSignalSemaphores = &semaphore; 839cb93a386Sopenharmony_ci GrSemaphoresSubmitted submitted = fDirectContext->flush(info); 840cb93a386Sopenharmony_ci fDirectContext->submit(); 841cb93a386Sopenharmony_ci if (GrSemaphoresSubmitted::kNo == submitted) { 842cb93a386Sopenharmony_ci ERRORF(reporter, "Failing call to flush on GrDirectContext"); 843cb93a386Sopenharmony_ci return false; 844cb93a386Sopenharmony_ci } 845cb93a386Sopenharmony_ci SkASSERT(semaphore.isInitialized()); 846cb93a386Sopenharmony_ci if (!this->exportSemaphore(reporter, semaphore)) { 847cb93a386Sopenharmony_ci return false; 848cb93a386Sopenharmony_ci } 849cb93a386Sopenharmony_ci return true; 850cb93a386Sopenharmony_ci} 851cb93a386Sopenharmony_ci 852cb93a386Sopenharmony_cibool VulkanTestHelper::setupSemaphoreForSignaling(skiatest::Reporter* reporter, 853cb93a386Sopenharmony_ci GrBackendSemaphore* beSemaphore) { 854cb93a386Sopenharmony_ci // Query supported info 855cb93a386Sopenharmony_ci VkPhysicalDeviceExternalSemaphoreInfo exSemInfo; 856cb93a386Sopenharmony_ci exSemInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO; 857cb93a386Sopenharmony_ci exSemInfo.pNext = nullptr; 858cb93a386Sopenharmony_ci exSemInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; 859cb93a386Sopenharmony_ci 860cb93a386Sopenharmony_ci VkExternalSemaphoreProperties exSemProps; 861cb93a386Sopenharmony_ci exSemProps.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES; 862cb93a386Sopenharmony_ci exSemProps.pNext = nullptr; 863cb93a386Sopenharmony_ci 864cb93a386Sopenharmony_ci fVkGetPhysicalDeviceExternalSemaphoreProperties(fBackendContext.fPhysicalDevice, &exSemInfo, 865cb93a386Sopenharmony_ci &exSemProps); 866cb93a386Sopenharmony_ci 867cb93a386Sopenharmony_ci if (!SkToBool(exSemProps.exportFromImportedHandleTypes & 868cb93a386Sopenharmony_ci VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) { 869cb93a386Sopenharmony_ci ERRORF(reporter, "HANDLE_TYPE_SYNC_FD not listed as exportFromImportedHandleTypes"); 870cb93a386Sopenharmony_ci return false; 871cb93a386Sopenharmony_ci } 872cb93a386Sopenharmony_ci if (!SkToBool(exSemProps.compatibleHandleTypes & 873cb93a386Sopenharmony_ci VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) { 874cb93a386Sopenharmony_ci ERRORF(reporter, "HANDLE_TYPE_SYNC_FD not listed as compatibleHandleTypes"); 875cb93a386Sopenharmony_ci return false; 876cb93a386Sopenharmony_ci } 877cb93a386Sopenharmony_ci if (!SkToBool(exSemProps.externalSemaphoreFeatures & 878cb93a386Sopenharmony_ci VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) || 879cb93a386Sopenharmony_ci !SkToBool(exSemProps.externalSemaphoreFeatures & 880cb93a386Sopenharmony_ci VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT)) { 881cb93a386Sopenharmony_ci ERRORF(reporter, "HANDLE_TYPE_SYNC_FD doesn't support export and import feature"); 882cb93a386Sopenharmony_ci return false; 883cb93a386Sopenharmony_ci } 884cb93a386Sopenharmony_ci 885cb93a386Sopenharmony_ci VkExportSemaphoreCreateInfo exportInfo; 886cb93a386Sopenharmony_ci exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO; 887cb93a386Sopenharmony_ci exportInfo.pNext = nullptr; 888cb93a386Sopenharmony_ci exportInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; 889cb93a386Sopenharmony_ci 890cb93a386Sopenharmony_ci VkSemaphoreCreateInfo semaphoreInfo; 891cb93a386Sopenharmony_ci semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 892cb93a386Sopenharmony_ci semaphoreInfo.pNext = &exportInfo; 893cb93a386Sopenharmony_ci semaphoreInfo.flags = 0; 894cb93a386Sopenharmony_ci 895cb93a386Sopenharmony_ci VkSemaphore semaphore; 896cb93a386Sopenharmony_ci VkResult err = fVkCreateSemaphore(fDevice, &semaphoreInfo, nullptr, &semaphore); 897cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 898cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to create signal semaphore, err: %d", err); 899cb93a386Sopenharmony_ci return false; 900cb93a386Sopenharmony_ci } 901cb93a386Sopenharmony_ci beSemaphore->initVulkan(semaphore); 902cb93a386Sopenharmony_ci return true; 903cb93a386Sopenharmony_ci} 904cb93a386Sopenharmony_ci 905cb93a386Sopenharmony_cibool VulkanTestHelper::exportSemaphore(skiatest::Reporter* reporter, 906cb93a386Sopenharmony_ci const GrBackendSemaphore& beSemaphore) { 907cb93a386Sopenharmony_ci VkSemaphore semaphore = beSemaphore.vkSemaphore(); 908cb93a386Sopenharmony_ci if (VK_NULL_HANDLE == semaphore) { 909cb93a386Sopenharmony_ci ERRORF(reporter, "Invalid vulkan handle in export call"); 910cb93a386Sopenharmony_ci return false; 911cb93a386Sopenharmony_ci } 912cb93a386Sopenharmony_ci 913cb93a386Sopenharmony_ci VkSemaphoreGetFdInfoKHR getFdInfo; 914cb93a386Sopenharmony_ci getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; 915cb93a386Sopenharmony_ci getFdInfo.pNext = nullptr; 916cb93a386Sopenharmony_ci getFdInfo.semaphore = semaphore; 917cb93a386Sopenharmony_ci getFdInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; 918cb93a386Sopenharmony_ci 919cb93a386Sopenharmony_ci VkResult err = fVkGetSemaphoreFdKHR(fDevice, &getFdInfo, &fFdHandle); 920cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 921cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to export signal semaphore, err: %d", err); 922cb93a386Sopenharmony_ci return false; 923cb93a386Sopenharmony_ci } 924cb93a386Sopenharmony_ci fSignalSemaphore = semaphore; 925cb93a386Sopenharmony_ci return true; 926cb93a386Sopenharmony_ci} 927cb93a386Sopenharmony_ci 928cb93a386Sopenharmony_cibool VulkanTestHelper::importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle, 929cb93a386Sopenharmony_ci sk_sp<SkSurface> surface) { 930cb93a386Sopenharmony_ci VkSemaphoreCreateInfo semaphoreInfo; 931cb93a386Sopenharmony_ci semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 932cb93a386Sopenharmony_ci semaphoreInfo.pNext = nullptr; 933cb93a386Sopenharmony_ci semaphoreInfo.flags = 0; 934cb93a386Sopenharmony_ci 935cb93a386Sopenharmony_ci VkSemaphore semaphore; 936cb93a386Sopenharmony_ci VkResult err = fVkCreateSemaphore(fDevice, &semaphoreInfo, nullptr, &semaphore); 937cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 938cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to create import semaphore, err: %d", err); 939cb93a386Sopenharmony_ci return false; 940cb93a386Sopenharmony_ci } 941cb93a386Sopenharmony_ci 942cb93a386Sopenharmony_ci VkImportSemaphoreFdInfoKHR importInfo; 943cb93a386Sopenharmony_ci importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; 944cb93a386Sopenharmony_ci importInfo.pNext = nullptr; 945cb93a386Sopenharmony_ci importInfo.semaphore = semaphore; 946cb93a386Sopenharmony_ci importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT; 947cb93a386Sopenharmony_ci importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; 948cb93a386Sopenharmony_ci importInfo.fd = fdHandle; 949cb93a386Sopenharmony_ci 950cb93a386Sopenharmony_ci err = fVkImportSemaphoreFdKHR(fDevice, &importInfo); 951cb93a386Sopenharmony_ci if (VK_SUCCESS != err) { 952cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to import semaphore, err: %d", err); 953cb93a386Sopenharmony_ci return false; 954cb93a386Sopenharmony_ci } 955cb93a386Sopenharmony_ci 956cb93a386Sopenharmony_ci GrBackendSemaphore beSemaphore; 957cb93a386Sopenharmony_ci beSemaphore.initVulkan(semaphore); 958cb93a386Sopenharmony_ci if (!surface->wait(1, &beSemaphore)) { 959cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to add wait semaphore to surface"); 960cb93a386Sopenharmony_ci fVkDestroySemaphore(fDevice, semaphore, nullptr); 961cb93a386Sopenharmony_ci return false; 962cb93a386Sopenharmony_ci } 963cb93a386Sopenharmony_ci return true; 964cb93a386Sopenharmony_ci} 965cb93a386Sopenharmony_ci 966cb93a386Sopenharmony_cisk_sp<SkSurface> VulkanTestHelper::importHardwareBufferForWrite(skiatest::Reporter* reporter, 967cb93a386Sopenharmony_ci AHardwareBuffer* buffer) { 968cb93a386Sopenharmony_ci GrVkImageInfo imageInfo; 969cb93a386Sopenharmony_ci if (!this->importHardwareBuffer(reporter, buffer, true, &imageInfo)) { 970cb93a386Sopenharmony_ci return nullptr; 971cb93a386Sopenharmony_ci } 972cb93a386Sopenharmony_ci 973cb93a386Sopenharmony_ci GrBackendTexture backendTex(DEV_W, DEV_H, imageInfo); 974cb93a386Sopenharmony_ci 975cb93a386Sopenharmony_ci sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(fDirectContext.get(), 976cb93a386Sopenharmony_ci backendTex, 977cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 978cb93a386Sopenharmony_ci 0, 979cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 980cb93a386Sopenharmony_ci nullptr, nullptr); 981cb93a386Sopenharmony_ci 982cb93a386Sopenharmony_ci if (!surface.get()) { 983cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to create wrapped Vulkan SkSurface"); 984cb93a386Sopenharmony_ci return nullptr; 985cb93a386Sopenharmony_ci } 986cb93a386Sopenharmony_ci 987cb93a386Sopenharmony_ci return surface; 988cb93a386Sopenharmony_ci} 989cb93a386Sopenharmony_ci 990cb93a386Sopenharmony_cistatic SkPMColor get_src_color(int x, int y) { 991cb93a386Sopenharmony_ci SkASSERT(x >= 0 && x < DEV_W); 992cb93a386Sopenharmony_ci SkASSERT(y >= 0 && y < DEV_H); 993cb93a386Sopenharmony_ci 994cb93a386Sopenharmony_ci U8CPU r = x; 995cb93a386Sopenharmony_ci U8CPU g = y; 996cb93a386Sopenharmony_ci U8CPU b = 0xc; 997cb93a386Sopenharmony_ci 998cb93a386Sopenharmony_ci U8CPU a = 0xff; 999cb93a386Sopenharmony_ci switch ((x+y) % 5) { 1000cb93a386Sopenharmony_ci case 0: 1001cb93a386Sopenharmony_ci a = 0xff; 1002cb93a386Sopenharmony_ci break; 1003cb93a386Sopenharmony_ci case 1: 1004cb93a386Sopenharmony_ci a = 0x80; 1005cb93a386Sopenharmony_ci break; 1006cb93a386Sopenharmony_ci case 2: 1007cb93a386Sopenharmony_ci a = 0xCC; 1008cb93a386Sopenharmony_ci break; 1009cb93a386Sopenharmony_ci case 4: 1010cb93a386Sopenharmony_ci a = 0x01; 1011cb93a386Sopenharmony_ci break; 1012cb93a386Sopenharmony_ci case 3: 1013cb93a386Sopenharmony_ci a = 0x00; 1014cb93a386Sopenharmony_ci break; 1015cb93a386Sopenharmony_ci } 1016cb93a386Sopenharmony_ci a = 0xff; 1017cb93a386Sopenharmony_ci return SkPremultiplyARGBInline(a, r, g, b); 1018cb93a386Sopenharmony_ci} 1019cb93a386Sopenharmony_ci 1020cb93a386Sopenharmony_cistatic SkBitmap make_src_bitmap() { 1021cb93a386Sopenharmony_ci static SkBitmap bmp; 1022cb93a386Sopenharmony_ci if (bmp.isNull()) { 1023cb93a386Sopenharmony_ci bmp.allocN32Pixels(DEV_W, DEV_H); 1024cb93a386Sopenharmony_ci intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels()); 1025cb93a386Sopenharmony_ci for (int y = 0; y < DEV_H; ++y) { 1026cb93a386Sopenharmony_ci for (int x = 0; x < DEV_W; ++x) { 1027cb93a386Sopenharmony_ci SkPMColor* pixel = reinterpret_cast<SkPMColor*>( 1028cb93a386Sopenharmony_ci pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel()); 1029cb93a386Sopenharmony_ci *pixel = get_src_color(x, y); 1030cb93a386Sopenharmony_ci } 1031cb93a386Sopenharmony_ci } 1032cb93a386Sopenharmony_ci } 1033cb93a386Sopenharmony_ci return bmp; 1034cb93a386Sopenharmony_ci} 1035cb93a386Sopenharmony_ci 1036cb93a386Sopenharmony_cistatic bool check_read(skiatest::Reporter* reporter, const SkBitmap& srcBitmap, 1037cb93a386Sopenharmony_ci const SkBitmap& dstBitmap) { 1038cb93a386Sopenharmony_ci bool result = true; 1039cb93a386Sopenharmony_ci for (int y = 0; y < DEV_H && result; ++y) { 1040cb93a386Sopenharmony_ci for (int x = 0; x < DEV_W && result; ++x) { 1041cb93a386Sopenharmony_ci const uint32_t srcPixel = *srcBitmap.getAddr32(x, y); 1042cb93a386Sopenharmony_ci const uint32_t dstPixel = *dstBitmap.getAddr32(x, y); 1043cb93a386Sopenharmony_ci if (srcPixel != dstPixel) { 1044cb93a386Sopenharmony_ci ERRORF(reporter, "Expected readback pixel (%d, %d) value 0x%08x, got 0x%08x.", 1045cb93a386Sopenharmony_ci x, y, srcPixel, dstPixel); 1046cb93a386Sopenharmony_ci result = false; 1047cb93a386Sopenharmony_ci } /*else { 1048cb93a386Sopenharmony_ci ERRORF(reporter, "Got good readback pixel (%d, %d) value 0x%08x, got 0x%08x.", 1049cb93a386Sopenharmony_ci x, y, srcPixel, dstPixel); 1050cb93a386Sopenharmony_ci 1051cb93a386Sopenharmony_ci }*/ 1052cb93a386Sopenharmony_ci } 1053cb93a386Sopenharmony_ci } 1054cb93a386Sopenharmony_ci return result; 1055cb93a386Sopenharmony_ci} 1056cb93a386Sopenharmony_ci 1057cb93a386Sopenharmony_cistatic void cleanup_resources(BaseTestHelper* srcHelper, BaseTestHelper* dstHelper, 1058cb93a386Sopenharmony_ci AHardwareBuffer* buffer) { 1059cb93a386Sopenharmony_ci if (srcHelper) { 1060cb93a386Sopenharmony_ci srcHelper->cleanup(); 1061cb93a386Sopenharmony_ci } 1062cb93a386Sopenharmony_ci if (dstHelper) { 1063cb93a386Sopenharmony_ci dstHelper->cleanup(); 1064cb93a386Sopenharmony_ci } 1065cb93a386Sopenharmony_ci if (buffer) { 1066cb93a386Sopenharmony_ci AHardwareBuffer_release(buffer); 1067cb93a386Sopenharmony_ci } 1068cb93a386Sopenharmony_ci} 1069cb93a386Sopenharmony_ci 1070cb93a386Sopenharmony_cienum class SrcType { 1071cb93a386Sopenharmony_ci kCPU, 1072cb93a386Sopenharmony_ci kEGL, 1073cb93a386Sopenharmony_ci kVulkan, 1074cb93a386Sopenharmony_ci}; 1075cb93a386Sopenharmony_ci 1076cb93a386Sopenharmony_cienum class DstType { 1077cb93a386Sopenharmony_ci kEGL, 1078cb93a386Sopenharmony_ci kVulkan, 1079cb93a386Sopenharmony_ci}; 1080cb93a386Sopenharmony_ci 1081cb93a386Sopenharmony_civoid run_test(skiatest::Reporter* reporter, const GrContextOptions& options, 1082cb93a386Sopenharmony_ci SrcType srcType, DstType dstType, bool shareSyncs) { 1083cb93a386Sopenharmony_ci if (SrcType::kCPU == srcType && shareSyncs) { 1084cb93a386Sopenharmony_ci // We don't currently test this since we don't do any syncs in this case. 1085cb93a386Sopenharmony_ci return; 1086cb93a386Sopenharmony_ci } 1087cb93a386Sopenharmony_ci std::unique_ptr<BaseTestHelper> srcHelper; 1088cb93a386Sopenharmony_ci std::unique_ptr<BaseTestHelper> dstHelper; 1089cb93a386Sopenharmony_ci AHardwareBuffer* buffer = nullptr; 1090cb93a386Sopenharmony_ci if (SrcType::kVulkan == srcType) { 1091cb93a386Sopenharmony_ci srcHelper.reset(new VulkanTestHelper()); 1092cb93a386Sopenharmony_ci } else if (SrcType::kEGL == srcType) { 1093cb93a386Sopenharmony_ci#ifdef SK_GL 1094cb93a386Sopenharmony_ci srcHelper.reset(new EGLTestHelper(options)); 1095cb93a386Sopenharmony_ci#else 1096cb93a386Sopenharmony_ci SkASSERT(false, "SrcType::kEGL used without OpenGL support."); 1097cb93a386Sopenharmony_ci#endif 1098cb93a386Sopenharmony_ci } 1099cb93a386Sopenharmony_ci if (srcHelper) { 1100cb93a386Sopenharmony_ci if (!srcHelper->init(reporter)) { 1101cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1102cb93a386Sopenharmony_ci return; 1103cb93a386Sopenharmony_ci } 1104cb93a386Sopenharmony_ci } 1105cb93a386Sopenharmony_ci 1106cb93a386Sopenharmony_ci if (DstType::kVulkan == dstType) { 1107cb93a386Sopenharmony_ci dstHelper.reset(new VulkanTestHelper()); 1108cb93a386Sopenharmony_ci } else { 1109cb93a386Sopenharmony_ci#ifdef SK_GL 1110cb93a386Sopenharmony_ci SkASSERT(DstType::kEGL == dstType); 1111cb93a386Sopenharmony_ci dstHelper.reset(new EGLTestHelper(options)); 1112cb93a386Sopenharmony_ci#else 1113cb93a386Sopenharmony_ci SkASSERT(false, "DstType::kEGL used without OpenGL support."); 1114cb93a386Sopenharmony_ci#endif 1115cb93a386Sopenharmony_ci } 1116cb93a386Sopenharmony_ci if (dstHelper) { 1117cb93a386Sopenharmony_ci if (!dstHelper->init(reporter)) { 1118cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1119cb93a386Sopenharmony_ci return; 1120cb93a386Sopenharmony_ci } 1121cb93a386Sopenharmony_ci } 1122cb93a386Sopenharmony_ci 1123cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1124cb93a386Sopenharmony_ci // Setup SkBitmaps 1125cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1126cb93a386Sopenharmony_ci 1127cb93a386Sopenharmony_ci SkBitmap srcBitmap = make_src_bitmap(); 1128cb93a386Sopenharmony_ci SkBitmap dstBitmapSurface; 1129cb93a386Sopenharmony_ci dstBitmapSurface.allocN32Pixels(DEV_W, DEV_H); 1130cb93a386Sopenharmony_ci SkBitmap dstBitmapFinal; 1131cb93a386Sopenharmony_ci dstBitmapFinal.allocN32Pixels(DEV_W, DEV_H); 1132cb93a386Sopenharmony_ci 1133cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1134cb93a386Sopenharmony_ci // Setup AHardwareBuffer 1135cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1136cb93a386Sopenharmony_ci 1137cb93a386Sopenharmony_ci AHardwareBuffer_Desc hwbDesc; 1138cb93a386Sopenharmony_ci hwbDesc.width = DEV_W; 1139cb93a386Sopenharmony_ci hwbDesc.height = DEV_H; 1140cb93a386Sopenharmony_ci hwbDesc.layers = 1; 1141cb93a386Sopenharmony_ci if (SrcType::kCPU == srcType) { 1142cb93a386Sopenharmony_ci hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER | 1143cb93a386Sopenharmony_ci AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN | 1144cb93a386Sopenharmony_ci AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; 1145cb93a386Sopenharmony_ci } else { 1146cb93a386Sopenharmony_ci hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER | 1147cb93a386Sopenharmony_ci AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER | 1148cb93a386Sopenharmony_ci AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | 1149cb93a386Sopenharmony_ci AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT; 1150cb93a386Sopenharmony_ci } 1151cb93a386Sopenharmony_ci hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; 1152cb93a386Sopenharmony_ci // The following three are not used in the allocate 1153cb93a386Sopenharmony_ci hwbDesc.stride = 0; 1154cb93a386Sopenharmony_ci hwbDesc.rfu0= 0; 1155cb93a386Sopenharmony_ci hwbDesc.rfu1= 0; 1156cb93a386Sopenharmony_ci 1157cb93a386Sopenharmony_ci if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) { 1158cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to allocated hardware buffer, error: %d", error); 1159cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1160cb93a386Sopenharmony_ci return; 1161cb93a386Sopenharmony_ci } 1162cb93a386Sopenharmony_ci 1163cb93a386Sopenharmony_ci if (SrcType::kCPU == srcType) { 1164cb93a386Sopenharmony_ci // Get actual desc for allocated buffer so we know the stride for uploading cpu data. 1165cb93a386Sopenharmony_ci AHardwareBuffer_describe(buffer, &hwbDesc); 1166cb93a386Sopenharmony_ci 1167cb93a386Sopenharmony_ci uint32_t* bufferAddr; 1168cb93a386Sopenharmony_ci if (AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, nullptr, 1169cb93a386Sopenharmony_ci reinterpret_cast<void**>(&bufferAddr))) { 1170cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to lock hardware buffer"); 1171cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1172cb93a386Sopenharmony_ci return; 1173cb93a386Sopenharmony_ci } 1174cb93a386Sopenharmony_ci 1175cb93a386Sopenharmony_ci int bbp = srcBitmap.bytesPerPixel(); 1176cb93a386Sopenharmony_ci uint32_t* src = (uint32_t*)srcBitmap.getPixels(); 1177cb93a386Sopenharmony_ci uint32_t* dst = bufferAddr; 1178cb93a386Sopenharmony_ci for (int y = 0; y < DEV_H; ++y) { 1179cb93a386Sopenharmony_ci memcpy(dst, src, DEV_W * bbp); 1180cb93a386Sopenharmony_ci src += DEV_W; 1181cb93a386Sopenharmony_ci dst += hwbDesc.stride; 1182cb93a386Sopenharmony_ci } 1183cb93a386Sopenharmony_ci 1184cb93a386Sopenharmony_ci for (int y = 0; y < DEV_H; ++y) { 1185cb93a386Sopenharmony_ci for (int x = 0; x < DEV_W; ++x) { 1186cb93a386Sopenharmony_ci const uint32_t srcPixel = *srcBitmap.getAddr32(x, y); 1187cb93a386Sopenharmony_ci uint32_t dstPixel = bufferAddr[y * hwbDesc.stride + x]; 1188cb93a386Sopenharmony_ci if (srcPixel != dstPixel) { 1189cb93a386Sopenharmony_ci ERRORF(reporter, "CPU HWB Expected readpix (%d, %d) value 0x%08x, got 0x%08x.", 1190cb93a386Sopenharmony_ci x, y, srcPixel, dstPixel); 1191cb93a386Sopenharmony_ci } 1192cb93a386Sopenharmony_ci } 1193cb93a386Sopenharmony_ci } 1194cb93a386Sopenharmony_ci 1195cb93a386Sopenharmony_ci AHardwareBuffer_unlock(buffer, nullptr); 1196cb93a386Sopenharmony_ci 1197cb93a386Sopenharmony_ci } else { 1198cb93a386Sopenharmony_ci srcHelper->makeCurrent(); 1199cb93a386Sopenharmony_ci sk_sp<SkSurface> surface = srcHelper->importHardwareBufferForWrite(reporter, buffer); 1200cb93a386Sopenharmony_ci 1201cb93a386Sopenharmony_ci if (!surface) { 1202cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1203cb93a386Sopenharmony_ci return; 1204cb93a386Sopenharmony_ci } 1205cb93a386Sopenharmony_ci 1206cb93a386Sopenharmony_ci sk_sp<SkImage> srcBmpImage = SkImage::MakeFromBitmap(srcBitmap); 1207cb93a386Sopenharmony_ci surface->getCanvas()->drawImage(srcBmpImage, 0, 0); 1208cb93a386Sopenharmony_ci 1209cb93a386Sopenharmony_ci // If we are testing sharing of syncs, don't do a read here since it forces sychronization 1210cb93a386Sopenharmony_ci // to occur. 1211cb93a386Sopenharmony_ci if (!shareSyncs) { 1212cb93a386Sopenharmony_ci bool readResult = surface->readPixels(dstBitmapSurface, 0, 0); 1213cb93a386Sopenharmony_ci if (!readResult) { 1214cb93a386Sopenharmony_ci ERRORF(reporter, "Read Pixels on surface failed"); 1215cb93a386Sopenharmony_ci surface.reset(); 1216cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1217cb93a386Sopenharmony_ci return; 1218cb93a386Sopenharmony_ci } 1219cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, check_read(reporter, srcBitmap, dstBitmapSurface)); 1220cb93a386Sopenharmony_ci } 1221cb93a386Sopenharmony_ci 1222cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1223cb93a386Sopenharmony_ci // Cleanup GL/EGL and add syncs 1224cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1225cb93a386Sopenharmony_ci 1226cb93a386Sopenharmony_ci if (shareSyncs) { 1227cb93a386Sopenharmony_ci if (!srcHelper->flushSurfaceAndSignalSemaphore(reporter, std::move(surface))) { 1228cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1229cb93a386Sopenharmony_ci return; 1230cb93a386Sopenharmony_ci } 1231cb93a386Sopenharmony_ci } else { 1232cb93a386Sopenharmony_ci surface.reset(); 1233cb93a386Sopenharmony_ci srcHelper->doClientSync(); 1234cb93a386Sopenharmony_ci srcHelper->releaseImage(); 1235cb93a386Sopenharmony_ci } 1236cb93a386Sopenharmony_ci } 1237cb93a386Sopenharmony_ci 1238cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1239cb93a386Sopenharmony_ci // Import the HWB into backend and draw it to a surface 1240cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////// 1241cb93a386Sopenharmony_ci 1242cb93a386Sopenharmony_ci dstHelper->makeCurrent(); 1243cb93a386Sopenharmony_ci sk_sp<SkImage> wrappedImage = dstHelper->importHardwareBufferForRead(reporter, buffer); 1244cb93a386Sopenharmony_ci 1245cb93a386Sopenharmony_ci if (!wrappedImage) { 1246cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1247cb93a386Sopenharmony_ci return; 1248cb93a386Sopenharmony_ci } 1249cb93a386Sopenharmony_ci 1250cb93a386Sopenharmony_ci auto direct = dstHelper->directContext(); 1251cb93a386Sopenharmony_ci 1252cb93a386Sopenharmony_ci // Make SkSurface to render wrapped HWB into. 1253cb93a386Sopenharmony_ci SkImageInfo imageInfo = SkImageInfo::Make(DEV_W, DEV_H, kRGBA_8888_SkColorType, 1254cb93a386Sopenharmony_ci kPremul_SkAlphaType, nullptr); 1255cb93a386Sopenharmony_ci 1256cb93a386Sopenharmony_ci sk_sp<SkSurface> dstSurf = SkSurface::MakeRenderTarget(direct, 1257cb93a386Sopenharmony_ci SkBudgeted::kNo, imageInfo, 0, 1258cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 1259cb93a386Sopenharmony_ci nullptr, false); 1260cb93a386Sopenharmony_ci if (!dstSurf.get()) { 1261cb93a386Sopenharmony_ci ERRORF(reporter, "Failed to create destination SkSurface"); 1262cb93a386Sopenharmony_ci wrappedImage.reset(); 1263cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1264cb93a386Sopenharmony_ci return; 1265cb93a386Sopenharmony_ci } 1266cb93a386Sopenharmony_ci 1267cb93a386Sopenharmony_ci if (shareSyncs) { 1268cb93a386Sopenharmony_ci if (!dstHelper->importAndWaitOnSemaphore(reporter, srcHelper->getFdHandle(), dstSurf)) { 1269cb93a386Sopenharmony_ci wrappedImage.reset(); 1270cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1271cb93a386Sopenharmony_ci return; 1272cb93a386Sopenharmony_ci } 1273cb93a386Sopenharmony_ci } 1274cb93a386Sopenharmony_ci dstSurf->getCanvas()->drawImage(wrappedImage, 0, 0); 1275cb93a386Sopenharmony_ci 1276cb93a386Sopenharmony_ci bool readResult = dstSurf->readPixels(dstBitmapFinal, 0, 0); 1277cb93a386Sopenharmony_ci if (!readResult) { 1278cb93a386Sopenharmony_ci ERRORF(reporter, "Read Pixels failed"); 1279cb93a386Sopenharmony_ci wrappedImage.reset(); 1280cb93a386Sopenharmony_ci dstSurf.reset(); 1281cb93a386Sopenharmony_ci dstHelper->doClientSync(); 1282cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1283cb93a386Sopenharmony_ci return; 1284cb93a386Sopenharmony_ci } 1285cb93a386Sopenharmony_ci 1286cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, check_read(reporter, srcBitmap, dstBitmapFinal)); 1287cb93a386Sopenharmony_ci 1288cb93a386Sopenharmony_ci dstSurf.reset(); 1289cb93a386Sopenharmony_ci wrappedImage.reset(); 1290cb93a386Sopenharmony_ci dstHelper->doClientSync(); 1291cb93a386Sopenharmony_ci cleanup_resources(srcHelper.get(), dstHelper.get(), buffer); 1292cb93a386Sopenharmony_ci} 1293cb93a386Sopenharmony_ci 1294cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_CPU_Vulkan, reporter, options) { 1295cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kCPU, DstType::kVulkan, false); 1296cb93a386Sopenharmony_ci} 1297cb93a386Sopenharmony_ci 1298cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_Vulkan_Vulkan, reporter, options) { 1299cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kVulkan, DstType::kVulkan, false); 1300cb93a386Sopenharmony_ci} 1301cb93a386Sopenharmony_ci 1302cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_Vulkan_Vulkan_Syncs, reporter, options) { 1303cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kVulkan, DstType::kVulkan, true); 1304cb93a386Sopenharmony_ci} 1305cb93a386Sopenharmony_ci 1306cb93a386Sopenharmony_ci#if defined(SK_GL) 1307cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_EGL_Vulkan, reporter, options) { 1308cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kEGL, DstType::kVulkan, false); 1309cb93a386Sopenharmony_ci} 1310cb93a386Sopenharmony_ci 1311cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_CPU_EGL, reporter, options) { 1312cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kCPU, DstType::kEGL, false); 1313cb93a386Sopenharmony_ci} 1314cb93a386Sopenharmony_ci 1315cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_EGL_EGL, reporter, options) { 1316cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kEGL, DstType::kEGL, false); 1317cb93a386Sopenharmony_ci} 1318cb93a386Sopenharmony_ci 1319cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_Vulkan_EGL, reporter, options) { 1320cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kVulkan, DstType::kEGL, false); 1321cb93a386Sopenharmony_ci} 1322cb93a386Sopenharmony_ci 1323cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_EGL_EGL_Syncs, reporter, options) { 1324cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kEGL, DstType::kEGL, true); 1325cb93a386Sopenharmony_ci} 1326cb93a386Sopenharmony_ci 1327cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_Vulkan_EGL_Syncs, reporter, options) { 1328cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kVulkan, DstType::kEGL, true); 1329cb93a386Sopenharmony_ci} 1330cb93a386Sopenharmony_ci 1331cb93a386Sopenharmony_ciDEF_GPUTEST(VulkanHardwareBuffer_EGL_Vulkan_Syncs, reporter, options) { 1332cb93a386Sopenharmony_ci run_test(reporter, options, SrcType::kEGL, DstType::kVulkan, true); 1333cb93a386Sopenharmony_ci} 1334cb93a386Sopenharmony_ci#endif 1335cb93a386Sopenharmony_ci 1336cb93a386Sopenharmony_ci#endif // SK_SUPPORT_GPU && defined(SK_BUILD_FOR_ANDROID) && 1337cb93a386Sopenharmony_ci // __ANDROID_API__ >= 26 && defined(SK_VULKAN) 1338cb93a386Sopenharmony_ci 1339