diff --git a/CMakeLists.txt b/CMakeLists.txt index 59420c7486..cedf8c2ba9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -481,6 +481,49 @@ elseif (DE_OS_IS_IOS) target_link_libraries(deqp tcutil-platform xscore ${DEQP_MODULE_LIBRARIES}) set_target_properties(deqp PROPERTIES XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2") set_target_properties(deqp PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer: ${DEQP_IOS_CODE_SIGN_IDENTITY}") +elseif (DE_OS_IS_OHOS) + include_directories( + framework/platform/ohos + framework/platform/ohos/context + framework/platform/ohos/display + framework/platform/ohos/rosen_context + framework/delibs/debase + framework/delibs/decpp + framework/delibs/deutil + framework/common + framework/qphelper + framework/egl + framework/egl/wrapper + framework/opengl + framework/opengl/wrapper + framework/openglcts/modules + modules + external/openglcts/modules + external/openglcts/modules/common + external/vulkancts/framework/vulkan + build/external/vulkancts/framework/vulkan + ) + set(DEQP_SRCS + framework/platform/ohos/appmain.cpp + framework/platform/ohos/tcuOhosPlatform.cpp + framework/platform/ohos/display/window/tcuOhosWindowFactory.cpp + framework/platform/ohos/display/window/tcuOhosNativeWindow.cpp + framework/platform/ohos/display/tcuOhosNativeDisplay.cpp + framework/platform/ohos/display/tcuOhosEglDisplayFactory.cpp + framework/platform/ohos/display/pixmap/tcuOhosPixmapFactory.cpp + framework/platform/ohos/display/pixmap/tcuOhosNativePixmap.cpp + framework/platform/ohos/context/tcuOhosNativeContext.cpp + framework/platform/ohos/context/tcuOhosEglContextFactory.cpp + framework/platform/ohos/rosen_context/ohos_context_i_app.cpp + ) + + set(DEQP_LIBS + tcutil-platform + ${DEQP_MODULE_LIBRARIES} + ) + + add_library(deqp SHARED ${DEQP_SRCS}) + target_link_libraries(deqp ${DEQP_LIBS}) endif () if (DE_OS_IS_FUCHSIA) diff --git a/executor/tools/xeCommandLineExecutor.cpp b/executor/tools/xeCommandLineExecutor.cpp index b1fedea4e9..93752d1c73 100644 --- a/executor/tools/xeCommandLineExecutor.cpp +++ b/executor/tools/xeCommandLineExecutor.cpp @@ -45,7 +45,7 @@ #include #include -#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32) +#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_WIN32) || (DE_OS == DE_OS_OHOS) #include #endif @@ -504,7 +504,7 @@ xe::CommLink *createCommLink(const CommandLine &cmdLine) } } -#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) +#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OHOS) static xe::BatchExecutor *s_executor = nullptr; diff --git a/external/libpng/CMakeLists.txt b/external/libpng/CMakeLists.txt index d9de774dfd..f460fb0bdf 100644 --- a/external/libpng/CMakeLists.txt +++ b/external/libpng/CMakeLists.txt @@ -65,7 +65,7 @@ if (DE_DEBUG EQUAL 1) add_definitions(-DPNG_DEBUG) endif () -if (DE_OS_IS_UNIX OR DE_OS_IS_QNX) +if (DE_OS_IS_UNIX OR DE_OS_IS_QNX OR DE_OS_IS_OHOS) # for snprintf() add_definitions(-D_XOPEN_SOURCE=600) endif () diff --git a/external/vulkan-validationlayers/CMakeLists.txt b/external/vulkan-validationlayers/CMakeLists.txt index 512f1d3de7..673b6f8634 100644 --- a/external/vulkan-validationlayers/CMakeLists.txt +++ b/external/vulkan-validationlayers/CMakeLists.txt @@ -19,7 +19,7 @@ endif () # VVL have issues building on Windows caused by build type mismatch in dependencies. # We exclude them from the Windows build for now. VK-GL-CTS issue: 5052 -if (NOT DE_OS_IS_ANDROID AND NOT DE_OS_IS_IOS AND NOT DE_OS_IS_WIN32 AND "${SBT_STRIPPED}" STREQUAL "" AND EXISTS ${VULKAN_VALIDATIONLAYERS_ABS_PATH}/external) +if (NOT DE_OS_IS_ANDROID AND NOT DE_OS_IS_IOS AND NOT DE_OS_IS_WIN32 AND NOT DE_OS_IS_OHOS AND "${SBT_STRIPPED}" STREQUAL "" AND EXISTS ${VULKAN_VALIDATIONLAYERS_ABS_PATH}/external) if (EXISTS ${VULKAN_VALIDATIONLAYERS_ABS_PATH}/CMakeLists.txt) message(STATUS "vulkan-validationlayers found") set(CMAKE_C_FLAGS ${DE_3RD_PARTY_C_FLAGS}) diff --git a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp index 8438539759..d78384ea00 100644 --- a/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp +++ b/external/vulkancts/modules/vulkan/util/vktExternalMemoryUtil.cpp @@ -25,7 +25,7 @@ #ifndef CTS_USES_VULKANSC -#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) +#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_OHOS) #include #include #include @@ -77,7 +77,7 @@ NativeHandle::NativeHandle(const NativeHandle &other) { if (other.m_fd >= 0) { -#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) +#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_OHOS) DE_ASSERT(!other.m_win32Handle.internal); DE_ASSERT(!other.m_androidHardwareBuffer.internal); m_fd = dup(other.m_fd); @@ -200,7 +200,7 @@ void NativeHandle::reset(void) { if (m_fd >= 0) { -#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) +#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_OHOS) DE_ASSERT(!m_win32Handle.internal); DE_ASSERT(!m_androidHardwareBuffer.internal); ::close(m_fd); diff --git a/external/zlib/CMakeLists.txt b/external/zlib/CMakeLists.txt index 960a1c9d64..41acfd7885 100644 --- a/external/zlib/CMakeLists.txt +++ b/external/zlib/CMakeLists.txt @@ -60,7 +60,7 @@ elseif (DE_COMPILER_IS_GCC OR DE_COMPILER_IS_CLANG) endif () -if (DE_OS_IS_UNIX OR DE_OS_IS_QNX) +if (DE_OS_IS_UNIX OR DE_OS_IS_QNX OR DE_OS_IS_OHOS) add_definitions(-D_XOPEN_SOURCE=600) endif () diff --git a/framework/common/tcuVectorUtil.hpp b/framework/common/tcuVectorUtil.hpp index 790c7a497c..78a15b0d16 100644 --- a/framework/common/tcuVectorUtil.hpp +++ b/framework/common/tcuVectorUtil.hpp @@ -39,7 +39,7 @@ namespace tcu static const float PI = 3.141592653589793238f; #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_QNX) || \ - (DE_OS == DE_OS_WIN32 && DE_COMPILER == DE_COMPILER_CLANG) + (DE_OS == DE_OS_WIN32 && DE_COMPILER == DE_COMPILER_CLANG) || (DE_OS == DE_OS_OHOS) inline float abs(float f) { return deFloatAbs(f); diff --git a/framework/delibs/cmake/Defs.cmake b/framework/delibs/cmake/Defs.cmake index d45a06a241..495e8ed39f 100644 --- a/framework/delibs/cmake/Defs.cmake +++ b/framework/delibs/cmake/Defs.cmake @@ -67,6 +67,7 @@ DE_MAKE_ENV_BOOL("DE_OS" "OSX") DE_MAKE_ENV_BOOL("DE_OS" "ANDROID") DE_MAKE_ENV_BOOL("DE_OS" "IOS") DE_MAKE_ENV_BOOL("DE_OS" "FUCHSIA") +DE_MAKE_ENV_BOOL("DE_OS" "OHOS") # Prevent mixed compile with GCC and Clang if (NOT (CMAKE_C_COMPILER_ID MATCHES "GNU") EQUAL (CMAKE_CXX_COMPILER_ID MATCHES "GNU")) diff --git a/framework/delibs/debase/CMakeLists.txt b/framework/delibs/debase/CMakeLists.txt index b0886af6d4..c5f46c2e11 100644 --- a/framework/delibs/debase/CMakeLists.txt +++ b/framework/delibs/debase/CMakeLists.txt @@ -29,7 +29,7 @@ set(DEBASE_SRCS add_library(debase STATIC ${DEBASE_SRCS}) # link debase to libm on unix systems -if (DE_OS_IS_UNIX OR DE_OS_IS_QNX) +if (DE_OS_IS_UNIX OR DE_OS_IS_QNX OR DE_OS_IS_OHOS) target_link_libraries(debase m) add_definitions(-D_XOPEN_SOURCE=600) diff --git a/framework/delibs/debase/deDefs.c b/framework/delibs/debase/deDefs.c index e1eff67bf8..30a6ce3cfe 100644 --- a/framework/delibs/debase/deDefs.c +++ b/framework/delibs/debase/deDefs.c @@ -128,7 +128,7 @@ void deAssertFail(const char *reason, const char *file, int line) fprintf(stderr, "Assertion '%s' failed at %s:%d\n", reason, file, line); raise(SIGTRAP); abort(); -#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_FUCHSIA) +#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) __assert_fail(reason, file, (unsigned int)line, "Unknown function"); #elif (DE_OS == DE_OS_QNX) __assert(reason, file, (unsigned int)line, "Unknown function"); diff --git a/framework/delibs/debase/deDefs.h b/framework/delibs/debase/deDefs.h index f69b67b8e5..6a420a83d4 100644 --- a/framework/delibs/debase/deDefs.h +++ b/framework/delibs/debase/deDefs.h @@ -79,6 +79,7 @@ #define DE_OS_IOS 7 /*!< iOS */ #define DE_OS_QNX 8 /*!< QNX */ #define DE_OS_FUCHSIA 9 /*!< Fuchsia */ +#define DE_OS_OHOS 10 /*!< OHOS */ /* OS detection (set to one of DE_OS_*). */ #if defined(DE_OS) diff --git a/framework/delibs/debase/deMemory.c b/framework/delibs/debase/deMemory.c index 39178b6f19..fa96723f1e 100644 --- a/framework/delibs/debase/deMemory.c +++ b/framework/delibs/debase/deMemory.c @@ -33,7 +33,7 @@ #define DE_ALIGNED_MALLOC_WIN32 1 #define DE_ALIGNED_MALLOC_GENERIC 2 -#if (DE_OS == DE_OS_UNIX) || ((DE_OS == DE_OS_ANDROID) && (DE_ANDROID_API >= 21)) +#if (DE_OS == DE_OS_UNIX) || ((DE_OS == DE_OS_ANDROID) && (DE_ANDROID_API >= 21)) || (DE_OS == DE_OS_OHOS) #define DE_ALIGNED_MALLOC DE_ALIGNED_MALLOC_POSIX #if defined(__FreeBSD__) #include diff --git a/framework/delibs/decpp/deDirectoryIterator.hpp b/framework/delibs/decpp/deDirectoryIterator.hpp index f4852414cc..fb4222abaf 100644 --- a/framework/delibs/decpp/deDirectoryIterator.hpp +++ b/framework/delibs/decpp/deDirectoryIterator.hpp @@ -34,7 +34,7 @@ #elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_SYMBIAN) || \ (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_QNX) || \ (DE_OS == DE_OS_WIN32 && (DE_COMPILER == DE_COMPILER_CLANG || DE_COMPILER == DE_COMPILER_GCC)) || \ - (DE_OS == DE_OS_FUCHSIA) + (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) #define DE_DIRITER DE_DIRITER_POSIX #endif diff --git a/framework/delibs/decpp/deFilePath.cpp b/framework/delibs/decpp/deFilePath.cpp index 3e304e2d27..54bdf0af93 100644 --- a/framework/delibs/decpp/deFilePath.cpp +++ b/framework/delibs/decpp/deFilePath.cpp @@ -251,7 +251,7 @@ static void createDirectoryImpl(const char *path) if (!CreateDirectory(path, nullptr)) throw std::runtime_error("Failed to create directory"); #elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || \ - (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) + (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) if (mkdir(path, 0777) != 0) throw std::runtime_error("Failed to create directory"); #else diff --git a/framework/delibs/depool/CMakeLists.txt b/framework/delibs/depool/CMakeLists.txt index 1270d45399..7fec755ecf 100644 --- a/framework/delibs/depool/CMakeLists.txt +++ b/framework/delibs/depool/CMakeLists.txt @@ -27,7 +27,7 @@ set(DEPOOL_SRCS dePoolTest.h ) -if (DE_OS_IS_UNIX OR DE_OS_IS_QNX) +if (DE_OS_IS_UNIX OR DE_OS_IS_QNX OR DE_OS_IS_OHOS) # vsnprintf add_definitions(-D_XOPEN_SOURCE=600) endif () diff --git a/framework/delibs/dethread/CMakeLists.txt b/framework/delibs/dethread/CMakeLists.txt index e7565ae739..f691b1c4f9 100644 --- a/framework/delibs/dethread/CMakeLists.txt +++ b/framework/delibs/dethread/CMakeLists.txt @@ -46,7 +46,7 @@ if (DE_OS_IS_UNIX) set(DETHREAD_LIBS ${DETHREAD_LIBS} pthread) endif () -if (DE_OS_IS_UNIX OR DE_OS_IS_ANDROID OR DE_OS_IS_OSX OR DE_OS_IS_IOS OR DE_OS_IS_QNX OR DE_OS_IS_FUCHSIA) +if (DE_OS_IS_UNIX OR DE_OS_IS_ANDROID OR DE_OS_IS_OSX OR DE_OS_IS_IOS OR DE_OS_IS_QNX OR DE_OS_IS_FUCHSIA OR DE_OS_IS_OHOS) add_definitions(-D_XOPEN_SOURCE=600) endif () diff --git a/framework/delibs/dethread/unix/deMutexUnix.c b/framework/delibs/dethread/unix/deMutexUnix.c index f6b63e4883..099490d93a 100644 --- a/framework/delibs/dethread/unix/deMutexUnix.c +++ b/framework/delibs/dethread/unix/deMutexUnix.c @@ -25,7 +25,7 @@ #if (DE_OS == DE_OS_UNIX || DE_OS == DE_OS_ANDROID || DE_OS == DE_OS_SYMBIAN || DE_OS == DE_OS_QNX || \ DE_OS == DE_OS_OSX || DE_OS == DE_OS_IOS) || \ - (DE_OS == DE_OS_FUCHSIA) + (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) #include "deMemory.h" diff --git a/framework/delibs/dethread/unix/deSemaphoreUnix.c b/framework/delibs/dethread/unix/deSemaphoreUnix.c index 2b8385b436..2b05bcf0fb 100644 --- a/framework/delibs/dethread/unix/deSemaphoreUnix.c +++ b/framework/delibs/dethread/unix/deSemaphoreUnix.c @@ -24,7 +24,7 @@ #include "deSemaphore.h" #if (DE_OS == DE_OS_UNIX || DE_OS == DE_OS_ANDROID || DE_OS == DE_OS_SYMBIAN || DE_OS == DE_OS_QNX) || \ - (DE_OS == DE_OS_FUCHSIA) + (DE_OS == DE_OS_FUCHSIA) || DE_OS == DE_OS_OHOS #include "deMemory.h" diff --git a/framework/delibs/dethread/unix/deThreadLocalUnix.c b/framework/delibs/dethread/unix/deThreadLocalUnix.c index 9d50838052..459e1ef609 100644 --- a/framework/delibs/dethread/unix/deThreadLocalUnix.c +++ b/framework/delibs/dethread/unix/deThreadLocalUnix.c @@ -24,7 +24,7 @@ #include "deThreadLocal.h" #if (DE_OS == DE_OS_UNIX || DE_OS == DE_OS_OSX || DE_OS == DE_OS_ANDROID || DE_OS == DE_OS_SYMBIAN || \ - DE_OS == DE_OS_IOS || DE_OS == DE_OS_QNX || DE_OS == DE_OS_FUCHSIA) + DE_OS == DE_OS_IOS || DE_OS == DE_OS_QNX || DE_OS == DE_OS_FUCHSIA || DE_OS == DE_OS_OHOS) #if !defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 500) #error You are using too old posix API! diff --git a/framework/delibs/dethread/unix/deThreadUnix.c b/framework/delibs/dethread/unix/deThreadUnix.c index d045bb3afb..b6e1bf8d19 100644 --- a/framework/delibs/dethread/unix/deThreadUnix.c +++ b/framework/delibs/dethread/unix/deThreadUnix.c @@ -24,7 +24,7 @@ #include "deThread.h" #if (DE_OS == DE_OS_UNIX || DE_OS == DE_OS_OSX || DE_OS == DE_OS_ANDROID || DE_OS == DE_OS_SYMBIAN || \ - DE_OS == DE_OS_IOS || DE_OS == DE_OS_QNX || DE_OS == DE_OS_FUCHSIA) + DE_OS == DE_OS_IOS || DE_OS == DE_OS_QNX || DE_OS == DE_OS_FUCHSIA || DE_OS == DE_OS_OHOS) #include "deMemory.h" #include "deInt32.h" @@ -36,7 +36,7 @@ #include #include #include -#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) +#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OHOS) #include #endif @@ -161,7 +161,7 @@ void deYield(void) sched_yield(); } -#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) +#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OHOS) uint32_t deGetNumAvailableLogicalCores(void) { diff --git a/framework/delibs/deutil/CMakeLists.txt b/framework/delibs/deutil/CMakeLists.txt index d47b8ed028..28422fcccf 100644 --- a/framework/delibs/deutil/CMakeLists.txt +++ b/framework/delibs/deutil/CMakeLists.txt @@ -45,7 +45,7 @@ if (DE_OS_IS_WIN32) set(DEUTIL_LIBS ${DEUTIL_LIBS} ws2_32) endif () -if (DE_OS_IS_UNIX OR DE_OS_IS_QNX) +if (DE_OS_IS_UNIX OR DE_OS_IS_QNX OR DE_OS_IS_OHOS) add_definitions(-D_XOPEN_SOURCE=600) endif () diff --git a/framework/delibs/deutil/deClock.c b/framework/delibs/deutil/deClock.c index 89cde503c4..c1dfb15d04 100644 --- a/framework/delibs/deutil/deClock.c +++ b/framework/delibs/deutil/deClock.c @@ -28,7 +28,7 @@ #if (DE_OS == DE_OS_WIN32) #define WIN32_LEAN_AND_MEAN #include -#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) +#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_OHOS) #include #elif (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) #include @@ -55,7 +55,7 @@ uint64_t deGetMicroseconds(void) return count.QuadPart / (freq.QuadPart / 1000000); } -#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) +#elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) struct timespec currTime; clock_gettime(CLOCK_MONOTONIC, &currTime); return (uint64_t)currTime.tv_sec * 1000000 + ((uint64_t)currTime.tv_nsec / 1000); diff --git a/framework/delibs/deutil/deDynamicLibrary.c b/framework/delibs/deutil/deDynamicLibrary.c index a7b2df9675..1a8ef32ccd 100644 --- a/framework/delibs/deutil/deDynamicLibrary.c +++ b/framework/delibs/deutil/deDynamicLibrary.c @@ -25,7 +25,7 @@ #include "deMemory.h" #if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_SYMBIAN) || \ - (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) + (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) /* Posix implementation. */ #include diff --git a/framework/delibs/deutil/deFile.c b/framework/delibs/deutil/deFile.c index 632975e272..0ba384151e 100644 --- a/framework/delibs/deutil/deFile.c +++ b/framework/delibs/deutil/deFile.c @@ -25,7 +25,7 @@ #include "deMemory.h" #if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || \ - (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) + (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) #include #include diff --git a/framework/delibs/deutil/deProcess.c b/framework/delibs/deutil/deProcess.c index b3c87079bf..f54d6a9d8a 100644 --- a/framework/delibs/deutil/deProcess.c +++ b/framework/delibs/deutil/deProcess.c @@ -26,7 +26,7 @@ #include "deString.h" #if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || \ - (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) + (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_OHOS) #include "deCommandLine.h" diff --git a/framework/delibs/deutil/deSocket.c b/framework/delibs/deutil/deSocket.c index 81c3657830..9825599d63 100644 --- a/framework/delibs/deutil/deSocket.c +++ b/framework/delibs/deutil/deSocket.c @@ -29,7 +29,7 @@ #if (DE_OS == DE_OS_WIN32) #define DE_USE_WINSOCK #elif (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || \ - (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) + (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA) || (DE_OS == DE_OS_OHOS) #define DE_USE_BERKELEY_SOCKETS #else #error Implement deSocket for your OS. diff --git a/framework/platform/ohos/appmain.cpp b/framework/platform/ohos/appmain.cpp new file mode 100755 index 0000000000..e6bfc4b27a --- /dev/null +++ b/framework/platform/ohos/appmain.cpp @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "tcuDefs.hpp" +#include "tcuCommandLine.hpp" +#include "tcuPlatform.hpp" +#include "tcuApp.hpp" +#include "tcuResource.hpp" +#include "tcuTestLog.hpp" +#include "tcuTestSessionExecutor.hpp" +#include "deUniquePtr.hpp" + +#include "common/glcConfigPackage.hpp" +#include "common/glcTestPackage.hpp" +#include "gles2/es2cTestPackage.hpp" +#include "gles3/es3cTestPackage.hpp" +#include "gles32/es32cTestPackage.hpp" +#include "gles31/es31cTestPackage.hpp" + +#include "gles2/tes2TestPackage.hpp" +#include "gles3/tes3TestPackage.hpp" +#include "gles31/tes31TestPackage.hpp" + +#include "ohos_context_i.h" + +#include "tcuTestContext.hpp" +#include "tcuOhosPlatform.hpp" +#include "appmain.h" + +tcu::Platform *createPlatform(void); + +static tcu::TestPackage *createES2Package(tcu::TestContext &testCtx) +{ + return new es2cts::TestPackage(testCtx, "KHR-GLES2"); +} + +static tcu::TestPackage *createES32Package(tcu::TestContext &testCtx) +{ + return new es32cts::ES32TestPackage(testCtx, "KHR-GLES32"); +} +static tcu::TestPackage* createES30Package(tcu::TestContext& testCtx) +{ + return new es3cts::ES30TestPackage(testCtx, "KHR-GLES3"); +} +static tcu::TestPackage* createES31Package(tcu::TestContext& testCtx) +{ + return new es31cts::ES31TestPackage(testCtx, "KHR-GLES31"); +} + +static tcu::TestPackage* createdEQPES2Package(tcu::TestContext& testCtx) +{ + return new deqp::gles2::TestPackage(testCtx); +} +static tcu::TestPackage* createdEQPES30Package(tcu::TestContext& testCtx) +{ + return new deqp::gles3::TestPackage(testCtx); +} +static tcu::TestPackage* createdEQPES31Package(tcu::TestContext& testCtx) +{ + return new deqp::gles31::TestPackage(testCtx); +} + +// Implement this in your platform port. + +void RegistPackage() +{ + + tcu::TestPackageRegistry *registry = tcu::TestPackageRegistry::getSingleton(); + + // OHOS::Rosen::RosenContext::GetInstance().GetGlesVer() == 3.2 + registry->registerPackage("KHR-GLES31", createES31Package); + registry->registerPackage("KHR-GLES2", createES2Package); + registry->registerPackage("KHR-GLES3", createES30Package); + registry->registerPackage("KHR-GLES32", createES32Package); + registry->registerPackage("dEQP-GLES2", createdEQPES2Package); + registry->registerPackage("dEQP-GLES3", createdEQPES30Package); + registry->registerPackage("dEQP-GLES31", createdEQPES31Package); +} + +bool GetCasePath(tcu::TestNode *node, std::vector &casePath, std::vector &namePath, uint32_t deep = 0) +{ + if (deep >= namePath.size()) + return false; + if (namePath[deep].compare(node->getName()) != 0) + return false; + casePath.push_back(node); + switch (node->getNodeType()) + { + case tcu::NODETYPE_ROOT: // = 0, //!< Root for all test packages. + printf("NODETYPE_ROOT\n"); + break; + case tcu::NODETYPE_PACKAGE: //, //!< Test case package -- same as group, but is omitted from XML dump. + case tcu::NODETYPE_GROUP: //, //!< Test case container -- cannot be executed. + printf("NODETYPE_GROUP\n"); + { + std::vector children; + node->getChildren(children); + for (uint32_t i = 0; i < children.size(); i++) + { + // printf("-----------%s==%s\n",children[i]->getName(),namePath[deep+1].c_str()); + if (GetCasePath(children[i], casePath, namePath, deep + 1)) + return true; + } + } + break; + case tcu::NODETYPE_SELF_VALIDATE: //, //!< Self-validating test case -- can be executed + printf("NODETYPE_SELF_VALIDATE\n"); + return true; + case tcu::NODETYPE_PERFORMANCE: //, //!< Performace test case -- can be executed + printf("NODETYPE_PERFORMANCE\n"); + return true; + case tcu::NODETYPE_CAPABILITY: //, //!< Capability score case -- can be executed + printf("NODETYPE_CAPABILITY\n"); + return true; + case tcu::NODETYPE_ACCURACY: // //!< Accuracy test case -- can be executed + printf("NODETYPE_ACCURACY\n"); + return true; + } + return false; +} + +static int isInit = 0; + +TestRunStatus_t runTest(int argc, char **argv) +{ + printf("start test main--- \n"); + int exitStatus = EXIT_SUCCESS; + TestRunStatus_t runResult; + +#if (DE_OS != DE_OS_WIN32) + // Set stdout to line-buffered mode (will be fully buffered by default if stdout is pipe). + setvbuf(stdout, nullptr, _IOLBF, 4 * 1024); +#endif + + try + { + if (isInit == 0) { + RegistPackage(); + isInit = 1; + } + + tcu::CommandLine cmdLine(argc, argv); + tcu::DirArchive archive(cmdLine.getArchiveDir()); + tcu::TestLog log(cmdLine.getLogFileName(), cmdLine.getLogFlags()); + de::UniquePtr platform(createOhosPlatform()); + de::UniquePtr app(new tcu::App(*platform, archive, log, cmdLine)); + + // Main loop. + for (;;) + { + if (!app->iterate()) + { + if (cmdLine.getRunMode() == tcu::RUNMODE_EXECUTE && + (!app->getResult().isComplete || app->getResult().numFailed)) + { + exitStatus = EXIT_FAILURE; + } + + break; + } + } + + tcu::TestRunStatus trs = app->getResult(); + printf("finish test main--- pass:%d, fail:%d, all:%d\n", + trs.numPassed, trs.numFailed, trs.numExecuted); + + runResult.isComplete = trs.isComplete; + runResult.numExecuted = trs.numExecuted; + runResult.numPassed = trs.numPassed; + runResult.numFailed = trs.numFailed; + runResult.numNotSupported = trs.numNotSupported; + runResult.numWarnings = trs.numWarnings; + runResult.numWaived = trs.numWaived; + runResult.isComplete = trs.isComplete; + printf("before return--- pass:%d, fail:%d, all:%d\n", + runResult.numPassed, runResult.numFailed, runResult.numExecuted); + return runResult; + + } + catch (const std::exception &e) + { + printf("catch error : %s", e.what()); + tcu::die("%s", e.what()); + } + + return runResult; +} \ No newline at end of file diff --git a/framework/platform/ohos/appmain.h b/framework/platform/ohos/appmain.h new file mode 100755 index 0000000000..cde7483a0a --- /dev/null +++ b/framework/platform/ohos/appmain.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef _APP_MAIN_H_ + #define _APP_MAIN_H_ + +typedef struct RunStatus +{ + int numExecuted; //!< Total number of cases executed. + int numPassed; //!< Number of cases passed. + int numFailed; //!< Number of cases failed. + int numNotSupported; //!< Number of cases not supported. + int numWarnings; //!< Number of QualityWarning / CompatibilityWarning results. + int numWaived; //!< Number of waived tests. + bool isComplete; //!< Is run complete. +} TestRunStatus_t; + + __attribute__((visibility("default"))) TestRunStatus_t runTest(int argc, char **argv); + + #endif \ No newline at end of file diff --git a/framework/platform/ohos/context/tcuOhosEglContextFactory.cpp b/framework/platform/ohos/context/tcuOhosEglContextFactory.cpp new file mode 100755 index 0000000000..43e1519936 --- /dev/null +++ b/framework/platform/ohos/context/tcuOhosEglContextFactory.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tcuOhosNativeContext.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" +#include "tcuCommandLine.hpp" +#include "tcuOhosEglContextFactory.hpp" + +using namespace tcu; +using namespace OHOS_ROSEN; +using namespace egl; + +OhosContextFactory::OhosContextFactory () + : glu::ContextFactory ("ohos", "Render Context") +{ + //TODO: +} + +glu::RenderContext* OhosContextFactory::createContext (const glu::RenderConfig& config, + const tcu::CommandLine& cmdline, const glu::RenderContext* sharedContext) const +{ + return new OhosRendContext(config, cmdline); +} diff --git a/framework/platform/ohos/context/tcuOhosEglContextFactory.hpp b/framework/platform/ohos/context/tcuOhosEglContextFactory.hpp new file mode 100755 index 0000000000..22eacefa5d --- /dev/null +++ b/framework/platform/ohos/context/tcuOhosEglContextFactory.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TCUOHOSCONTEXTFACTORY_HPP +#define _TCUOHOSCONTEXTFACTORY_HPP + +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" +#include "glwFunctions.hpp" +#include "tcuRenderTarget.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +class OhosContextFactory : public glu::ContextFactory +{ +public: + OhosContextFactory (void); + virtual glu::RenderContext* createContext (const glu::RenderConfig& config, + const tcu::CommandLine& cmdLine, const glu::RenderContext* sharedContext) const; +}; + +} +} +} +#endif // _TCUOHOSROSENNATIVECONTEXT_HPP \ No newline at end of file diff --git a/framework/platform/ohos/context/tcuOhosNativeContext.cpp b/framework/platform/ohos/context/tcuOhosNativeContext.cpp new file mode 100755 index 0000000000..736474cafc --- /dev/null +++ b/framework/platform/ohos/context/tcuOhosNativeContext.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "tcuOhosNativeContext.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" +#include "tcuCommandLine.hpp" +#include "deDynamicLibrary.hpp" + +#include "ohos_context_i.h" + +using namespace tcu; +using namespace OHOS_ROSEN; +using namespace egl; + +using de::MovePtr; +using de::UniquePtr; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::WindowParams; +using glu::ContextFactory; +using std::string; +using tcu::TextureLevel; + +class GLFunctionLoader : public glw::FunctionLoader +{ +public: + GLFunctionLoader(const char *path) + : m_library(path) + { + } + + glw::GenericFuncType get(const char *name) const + { + return m_library.getFunction(name); + } + +private: + de::DynamicLibrary m_library; +}; + +OhosRendContext::OhosRendContext(const glu::RenderConfig &config, const tcu::CommandLine &cmdLine) + : m_contextType(config.type) +{ + DE_UNREF(cmdLine); + + printf("~~~~~~~OhosRendContext~~~~~~~~\n"); + printf("config.width = %d\n", config.width); + printf("config.height = %d\n", config.height); + printf("config.redBits = %d\n", config.redBits); + printf("config.greenBits = %d\n", config.greenBits); + printf("config.blueBits = %d\n", config.blueBits); + printf("config.alphaBits = %d\n", config.alphaBits); + printf("config.depthBits = %d\n", config.depthBits); + printf("config.stencilBits = %d\n", config.stencilBits); + printf("config.numSamples = %d\n", config.numSamples); + printf("config.type.getMajorVersion() = %d\n", config.type.getMajorVersion()); + printf("config.type.getMinorVersion() = %d\n", config.type.getMinorVersion()); + printf("~~~~~~~~~~~~~~~\n"); + // TODO: + int32_t w = config.width; + int32_t h = config.height; + if (w == -1) + { + w = 512; + } + if (h == -1) + { + h = 512; + } + + OHOS::RCI_GLES_VERSION ver; + if (config.type.getMajorVersion() == 2 && config.type.getMinorVersion() == 0) + { + ver = OHOS::RCI_GLES_VERSION::V20; + } + else if (config.type.getMajorVersion() == 3 && config.type.getMinorVersion() == 0) + { + ver = OHOS::RCI_GLES_VERSION::V30; + } + else if (config.type.getMajorVersion() == 3 && config.type.getMinorVersion() == 1) + { + ver = OHOS::RCI_GLES_VERSION::V31; + } + else if (config.type.getMajorVersion() == 3 && config.type.getMinorVersion() == 2) + { + ver = OHOS::RCI_GLES_VERSION::V32; + } + else + { + printf("not supoort version: ~~~~~~~~~~~~~~~\n"); + throw tcu::NotSupportedError("not support version"); + } + + OHOS::RCI_PIXEL_FORMAT pf = { + .redBits = 8, + .greenBits = 8, + .blueBits = 8, + .alphaBits = 8, + .depthBits = 24, + .stencilBits = 8, + .numSamples = 4, + }; + if (config.redBits != -1) + { + pf.redBits = config.redBits; + } + if (config.greenBits != -1) + { + pf.greenBits = config.greenBits; + } + if (config.blueBits != -1) + { + pf.blueBits = config.blueBits; + } + if (config.alphaBits != -1) + { + pf.alphaBits = config.alphaBits; + } + if (config.depthBits != -1) + { + pf.depthBits = config.depthBits; + } + if (config.stencilBits != -1) + { + pf.stencilBits = config.stencilBits; + } + if (config.numSamples != -1) + { + pf.numSamples = config.numSamples; + } + + OHOS::RCI_SURFACE_TYPE surfaceType; + switch (config.surfaceType) + { + case glu::RenderConfig::SURFACETYPE_DONT_CARE: + surfaceType = OHOS::RCI_SURFACE_TYPE::NONE; + break; + case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE: + surfaceType = OHOS::RCI_SURFACE_TYPE::PIXMAP; + break; + case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC: + surfaceType = OHOS::RCI_SURFACE_TYPE::PBUFFER; + break; + case glu::RenderConfig::SURFACETYPE_WINDOW: + surfaceType = OHOS::RCI_SURFACE_TYPE::WINDOW; + break; + case glu::RenderConfig::SURFACETYPE_LAST: + TCU_CHECK_INTERNAL(false); + } + + OHOS::RCI_PROFILE profile; + switch (config.type.getProfile()) + { + case glu::PROFILE_ES: + profile = OHOS::RCI_PROFILE::ES; + break; + case glu::PROFILE_CORE: + profile = OHOS::RCI_PROFILE::CORE; + break; + case glu::PROFILE_COMPATIBILITY: + profile = OHOS::RCI_PROFILE::COMPATIBILITY; + break; + case glu::PROFILE_LAST: + TCU_CHECK_INTERNAL(false); + } + + int flags = 0; + if ((config.type.getFlags() & glu::CONTEXT_DEBUG) != 0) + flags |= static_cast(OHOS::RCI_CONTEXT_FLAG::DEBUG); + + if ((config.type.getFlags() & glu::CONTEXT_ROBUST) != 0) + flags |= static_cast(OHOS::RCI_CONTEXT_FLAG::ROBUST); + + if ((config.type.getFlags() & glu::CONTEXT_FORWARD_COMPATIBLE) != 0) + flags |= static_cast(OHOS::RCI_CONTEXT_FLAG::FORWARD_COMPATIBLE); + + if (!OHOS::OhosContextI::GetInstance().SetConfig(w, h, ver, pf, surfaceType, profile, static_cast(flags))) + { + throw tcu::NotSupportedError("not support context"); + } + OHOS::OhosContextI::GetInstance().InitNativeWindow(); + OHOS::OhosContextI::GetInstance().InitEglSurface(); + OHOS::OhosContextI::GetInstance().InitEglContext(); + OHOS::OhosContextI::GetInstance().MakeCurrent(); + + if (config.type.getMajorVersion() == 2 || config.type.getMajorVersion() == 3) + { + GLFunctionLoader loader("libGLESv3.so"); + glu::initFunctions(&m_glFunctions, &loader, config.type.getAPI()); + } + else + { + throw tcu::NotSupportedError("not support version"); + } + while(m_glFunctions.getError()!=0) + { + printf("err pass\n"); + } + + m_renderTarget = tcu::RenderTarget(512, 512, PixelFormat(8, 8, 8, 8), + OHOS::OhosContextI::GetInstance().GetAttrib(EGL_DEPTH_SIZE), + OHOS::OhosContextI::GetInstance().GetAttrib(EGL_STENCIL_SIZE), + OHOS::OhosContextI::GetInstance().GetAttrib(EGL_SAMPLES)); +}; + +OhosRendContext::~OhosRendContext(void) +{ + printf("~~~~~~~DEOhosRendContext~~~~~~~~\n"); + OHOS::OhosContextI::GetInstance().SwapBuffer(); +}; + +void OhosRendContext::postIterate(void) +{ + OHOS::OhosContextI::GetInstance().SwapBuffer(); +} \ No newline at end of file diff --git a/framework/platform/ohos/context/tcuOhosNativeContext.hpp b/framework/platform/ohos/context/tcuOhosNativeContext.hpp new file mode 100755 index 0000000000..ca0c1dab44 --- /dev/null +++ b/framework/platform/ohos/context/tcuOhosNativeContext.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TCUOHOSROSENNATIVECONTEXT_HPP +#define _TCUOHOSROSENNATIVECONTEXT_HPP + +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" +#include "glwFunctions.hpp" +#include "tcuRenderTarget.hpp" + +#include "display/tcuOhosNativeDisplay.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using glu::RenderContext; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +class OhosRendContext : public RenderContext +{ +public: + OhosRendContext(const glu::RenderConfig& config, const tcu::CommandLine& cmdLine); + virtual ~OhosRendContext(void); + + glu::ContextType getType(void) const { return m_contextType; } + const glw::Functions& getFunctions (void) const { return m_glFunctions; } + const tcu::RenderTarget& getRenderTarget (void) const { return m_renderTarget; } + void postIterate (void); + + virtual glw::GenericFuncType getProcAddress (const char* name) const { return m_egl.getProcAddress(name); } +private: + const eglw::DefaultLibrary m_egl; + const glu::ContextType m_contextType; + glw::Functions m_glFunctions; + tcu::RenderTarget m_renderTarget; +}; + +} // egl +} // OHOS +} // tcu +#endif // _TCUOHOSROSENNATIVECONTEXT_HPP \ No newline at end of file diff --git a/framework/platform/ohos/display/pixmap/tcuOhosNativePixmap.cpp b/framework/platform/ohos/display/pixmap/tcuOhosNativePixmap.cpp new file mode 100755 index 0000000000..19e679bb49 --- /dev/null +++ b/framework/platform/ohos/display/pixmap/tcuOhosNativePixmap.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "display/tcuOhosNativeDisplay.hpp" +#include "tcuOhosNativePixmap.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +OhosPixmap::OhosPixmap (void) + : NativePixmap(eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) +{ + //TODO: create pixmap + printf("OhosPixmap::OhosPixmap\n"); +} + +} // egl +} // OHOS +} // tcu \ No newline at end of file diff --git a/framework/platform/ohos/display/pixmap/tcuOhosNativePixmap.hpp b/framework/platform/ohos/display/pixmap/tcuOhosNativePixmap.hpp new file mode 100755 index 0000000000..b3e248b460 --- /dev/null +++ b/framework/platform/ohos/display/pixmap/tcuOhosNativePixmap.hpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TCUOHOSROSENNATIVEPIXMAP_HPP +#define _TCUOHOSROSENNATIVEPIXMAP_HPP + +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + + +class OhosPixmap : public NativePixmap +{ +public: + enum { + CAPABILITIES = (CAPABILITY_CREATE_SURFACE_LEGACY | + CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION | + CAPABILITY_READ_PIXELS) + }; + + OhosPixmap (void); + + void* getPlatformNative (void) { return this; } + +}; + +} // egl +} // OHOS +} // tcu +#endif // _TCUOHOSROSENNATIVEPIXMAP_HPP \ No newline at end of file diff --git a/framework/platform/ohos/display/pixmap/tcuOhosPixmapFactory.cpp b/framework/platform/ohos/display/pixmap/tcuOhosPixmapFactory.cpp new file mode 100755 index 0000000000..88ba084eb4 --- /dev/null +++ b/framework/platform/ohos/display/pixmap/tcuOhosPixmapFactory.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "display/tcuOhosNativeDisplay.hpp" +#include "tcuOhosPixmapFactory.hpp" +#include "tcuOhosNativePixmap.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +NativePixmap* OhosPixmapFactory::createPixmap (NativeDisplay* nativeDisplay, + int width, + int height) const +{ + //TODO create pixmap + // OhosDisplay* display = dynamic_cast(nativeDisplay); + if (nativeDisplay != nullptr) { + printf("OhosPixmapFactory::createPixmap width=%d, height=%d,\n", width, height); + } + + return new OhosPixmap(); +} + +} // egl +} // OHOS +} // tcu \ No newline at end of file diff --git a/framework/platform/ohos/display/pixmap/tcuOhosPixmapFactory.hpp b/framework/platform/ohos/display/pixmap/tcuOhosPixmapFactory.hpp new file mode 100755 index 0000000000..865900b5ca --- /dev/null +++ b/framework/platform/ohos/display/pixmap/tcuOhosPixmapFactory.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TCU_OHOS_PIXMAP_FACTORY_HPP +#define _TCU_OHOS_PIXMAP_FACTORY_HPP + +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +class OhosPixmapFactory : public eglu::NativePixmapFactory +{ +public: + OhosPixmapFactory (void) + : eglu::NativePixmapFactory ("pixmap", "Rosen Pixmap", eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) {}; + + NativePixmap* createPixmap (NativeDisplay* nativeDisplay, + int width, + int height) const; +}; + +} // egl +} // OHOS +} // tcu +#endif // _TCUOHOSROSENNATIVEPIXMAP_HPP \ No newline at end of file diff --git a/framework/platform/ohos/display/tcuOhosEglDisplayFactory.cpp b/framework/platform/ohos/display/tcuOhosEglDisplayFactory.cpp new file mode 100755 index 0000000000..3dd1063538 --- /dev/null +++ b/framework/platform/ohos/display/tcuOhosEglDisplayFactory.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tcuOhosEglDisplayFactory.hpp" +#include "window/tcuOhosWindowFactory.hpp" +#include "pixmap/tcuOhosPixmapFactory.hpp" +#include "tcuOhosNativeDisplay.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +using namespace tcu; +using namespace OHOS_ROSEN; +using namespace egl; + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +OhosDisplayFactory::OhosDisplayFactory (void) + : eglu::NativeDisplayFactory("ROSEN", "Rosen Display", OhosDisplay::CAPABILITIES) +{ + m_nativeWindowRegistry.registerFactory(new OhosWindowFactory()); + m_nativePixmapRegistry.registerFactory(new OhosPixmapFactory()); +} + +NativeDisplay* OhosDisplayFactory::createDisplay (const eglw::EGLAttrib* attribList) const +{ + DE_UNREF(attribList); + return new OhosDisplay(); +} diff --git a/framework/platform/ohos/display/tcuOhosEglDisplayFactory.hpp b/framework/platform/ohos/display/tcuOhosEglDisplayFactory.hpp new file mode 100755 index 0000000000..d6c8d6c9fe --- /dev/null +++ b/framework/platform/ohos/display/tcuOhosEglDisplayFactory.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _TCUOHOSROSENEGLDISPLAYFACTORY_HPP +#define _TCUOHOSROSENEGLDISPLAYFACTORY_HPP + +#include "egluNativeDisplay.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +class OhosDisplayFactory : public eglu::NativeDisplayFactory +{ +public: + OhosDisplayFactory (void); + eglu::NativeDisplay* createDisplay (const eglw::EGLAttrib* attribList) const; + +}; + +} // egl +} // OHOS +} // tcu + +#endif // _TCUOHOSROSENEGLDISPLAYFACTORY_HPP diff --git a/framework/platform/ohos/display/tcuOhosNativeDisplay.cpp b/framework/platform/ohos/display/tcuOhosNativeDisplay.cpp new file mode 100755 index 0000000000..d8a821664e --- /dev/null +++ b/framework/platform/ohos/display/tcuOhosNativeDisplay.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tcuOhosNativeDisplay.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +using namespace tcu; +using namespace OHOS_ROSEN; +using namespace egl; + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +OhosDisplay::OhosDisplay (void) + : NativeDisplay(eglu::NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY) +{ + printf("OhosDisplay::OhosDisplay\n"); +} + +void* OhosDisplay::getPlatformNative (void) { + printf("OhosDisplay::getPlatformNative\n"); + return this; +} + +eglw::EGLNativeDisplayType OhosDisplay::getPlatformExtension (void) +{ + printf("OhosDisplay::getPlatformExtension\n"); + return reinterpret_cast(this); +} + +eglw::EGLNativeDisplayType OhosDisplay::getLegacyNative (void) +{ + printf("OhosDisplay::getLegacyNative\n"); + return EGL_DEFAULT_DISPLAY; +} diff --git a/framework/platform/ohos/display/tcuOhosNativeDisplay.hpp b/framework/platform/ohos/display/tcuOhosNativeDisplay.hpp new file mode 100755 index 0000000000..acf67db670 --- /dev/null +++ b/framework/platform/ohos/display/tcuOhosNativeDisplay.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TCUOHOSROSENNATIVEDISPLAY_HPP +#define _TCUOHOSROSENNATIVEDISPLAY_HPP + +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +class OhosLibrary : public eglw::DefaultLibrary +{ +public: + OhosLibrary (void) + : eglw::DefaultLibrary("libEGL_impl.so") + { + } +}; + + +class OhosDisplay : public NativeDisplay +{ +public: + static const Capability CAPABILITIES = Capability(CAPABILITY_GET_DISPLAY_LEGACY); + + OhosDisplay (void); + // virtual ~OhosDisplay (void) {}; + + void* getPlatformNative (void); + eglw::EGLNativeDisplayType getPlatformExtension (void); + eglw::EGLNativeDisplayType getLegacyNative (void); + + const eglw::Library& getLibrary (void) const { return m_library; } + const eglw::EGLAttrib* getPlatformAttributes (void) const { return nullptr; } + +private: + OhosLibrary m_library; +}; + +} // egl +} // OHOS +} // tcu +#endif // _TCUOHOSROSENNATIVEDISPLAY_HPP \ No newline at end of file diff --git a/framework/platform/ohos/display/window/tcuOhosNativeWindow.cpp b/framework/platform/ohos/display/window/tcuOhosNativeWindow.cpp new file mode 100755 index 0000000000..0a1b897386 --- /dev/null +++ b/framework/platform/ohos/display/window/tcuOhosNativeWindow.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tcuOhosNativeWindow.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +OhosWindow::OhosWindow (OhosDisplay& display, const WindowParams& params) + : NativeWindow (CAPABILITIES) +{ + if (display.getPlatformNative() != nullptr) { + printf("OhosWindow params: width=%d, height=%d\n", params.width, params.height); + } + printf("OhosWindow::OhosWindow\n"); +} + +eglw::EGLNativeWindowType OhosWindow::getLegacyNative (void) +{ + printf("OhosWindow::getLegacyNative\n"); + return nullptr; +} + +void* OhosWindow::getPlatformExtension (void) +{ + printf("OhosWindow::getPlatformExtension\n"); + return nullptr; +} + +void* OhosWindow::getPlatformNative (void) +{ + printf("OhosWindow::getPlatformNative\n"); + return nullptr; +} + +IVec2 OhosWindow::getSurfaceSize (void) const +{ + IVec2 ret; + return ret; +} + +void OhosWindow::setSurfaceSize (IVec2 size) +{ + printf("setSurfaceSize IVec2: %d\n", size.x()); +} + +} // egl +} // OHOS +} // tcu \ No newline at end of file diff --git a/framework/platform/ohos/display/window/tcuOhosNativeWindow.hpp b/framework/platform/ohos/display/window/tcuOhosNativeWindow.hpp new file mode 100755 index 0000000000..10fed46e7c --- /dev/null +++ b/framework/platform/ohos/display/window/tcuOhosNativeWindow.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TCUOHOSROSENNATIVEWINDOW_HPP +#define _TCUOHOSROSENNATIVEWINDOW_HPP + +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +#include "display/tcuOhosNativeDisplay.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +class OhosWindow : public NativeWindow +{ +public: + static const Capability CAPABILITIES = Capability(CAPABILITY_CREATE_SURFACE_LEGACY | + CAPABILITY_CREATE_SURFACE_PLATFORM | + CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION | + CAPABILITY_GET_SURFACE_SIZE | + CAPABILITY_SET_SURFACE_SIZE | + CAPABILITY_GET_SCREEN_SIZE); + + OhosWindow (OhosDisplay& display, const WindowParams& params); + + eglw::EGLNativeWindowType getLegacyNative (void); + void* getPlatformExtension (void); + void* getPlatformNative (void); + + IVec2 getSurfaceSize (void) const; + void setSurfaceSize (IVec2 size); + IVec2 getScreenSize (void) const { return getSurfaceSize(); } + +}; + +} // egl +} // OHOS +} // tcu +#endif // _TCUOHOSROSENNATIVEWINDOW_HPP \ No newline at end of file diff --git a/framework/platform/ohos/display/window/tcuOhosWindowFactory.cpp b/framework/platform/ohos/display/window/tcuOhosWindowFactory.cpp new file mode 100755 index 0000000000..4ef9c8c6f9 --- /dev/null +++ b/framework/platform/ohos/display/window/tcuOhosWindowFactory.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tcuOhosWindowFactory.hpp" +#include "tcuOhosNativeWindow.hpp" +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +OhosWindowFactory::OhosWindowFactory (void) + : NativeWindowFactory ("window", "Rosen Window", OhosWindow::CAPABILITIES) +{ + //TODO: init window factory +} + +NativeWindow* OhosWindowFactory::createWindow (NativeDisplay* nativeDisplay, + const WindowParams& params) const +{ + //TODO: new native window + OhosDisplay& display = *dynamic_cast(nativeDisplay); + + return dynamic_cast(new OhosWindow(display, params)); +} + +} // egl +} // OHOS +} // tcu \ No newline at end of file diff --git a/framework/platform/ohos/display/window/tcuOhosWindowFactory.hpp b/framework/platform/ohos/display/window/tcuOhosWindowFactory.hpp new file mode 100755 index 0000000000..931eaa2ef9 --- /dev/null +++ b/framework/platform/ohos/display/window/tcuOhosWindowFactory.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _TCU_OHOS_WINDOW_FACTORY_HPP +#define _TCU_OHOS_WINDOW_FACTORY_HPP + +#include "egluGLContextFactory.hpp" +#include "eglwLibrary.hpp" +#include "eglwFunctions.hpp" +#include "eglwEnums.hpp" +#include "deUniquePtr.hpp" + +#include "display/tcuOhosNativeDisplay.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ +namespace egl +{ + +using std::string; +using de::MovePtr; +using de::UniquePtr; +using glu::ContextFactory; +using eglu::GLContextFactory; +using eglu::NativeDisplay; +using eglu::NativeDisplayFactory; +using eglu::NativeWindow; +using eglu::NativeWindowFactory; +using eglu::NativePixmap; +using eglu::NativePixmapFactory; +using eglu::WindowParams; +using tcu::TextureLevel; + +class OhosWindowFactory : public NativeWindowFactory +{ +public: + OhosWindowFactory (void); + virtual ~OhosWindowFactory (void) {}; + NativeWindow* createWindow(NativeDisplay* nativeDisplay, const WindowParams& params) const; +}; + + +} // egl +} // OHOS +} // tcu +#endif // _TCUOHOSROSENNATIVEWINDOW_HPP \ No newline at end of file diff --git a/framework/platform/ohos/rosen_context/ohos_context_i.cpp b/framework/platform/ohos/rosen_context/ohos_context_i.cpp new file mode 100755 index 0000000000..7da4e9477d --- /dev/null +++ b/framework/platform/ohos/rosen_context/ohos_context_i.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ohos_context_i.h" +#include "rosen_context_impl.h" + +using namespace OHOS; + +OhosContextI &OhosContextI::GetInstance() { + printf("old GetInstance\n"); + static Rosen::RosenContextImpl impl_; + return impl_; +} + +void OhosContextI::HiLog(const char *format, ...) { +} \ No newline at end of file diff --git a/framework/platform/ohos/rosen_context/ohos_context_i.h b/framework/platform/ohos/rosen_context/ohos_context_i.h new file mode 100755 index 0000000000..88cf9853f3 --- /dev/null +++ b/framework/platform/ohos/rosen_context/ohos_context_i.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef _ROSEN_CONTEXT_H_ + #define _ROSEN_CONTEXT_H_ + + #include + + namespace OHOS { + + enum class RCI_GLES_VERSION { V20 = 20, V30 = 30, V31 = 31, V32 = 32 }; + + enum class RCI_PROFILE { ES = 0, CORE, COMPATIBILITY }; + + enum class RCI_CONTEXT_FLAG { + NONE = 0, + ROBUST =(1<<0) , //!< Robust context + DEBUG =(1<<1 ), //!!< Debug context + FORWARD_COMPATIBLE =(1<<2) , //!< Forward-compatible context + }; + + enum class RCI_SURFACE_TYPE { NONE = 0, WINDOW, PIXMAP, PBUFFER }; + + struct RCI_PIXEL_FORMAT { + int32_t redBits; + int32_t greenBits; + int32_t blueBits; + int32_t alphaBits; + int32_t depthBits; + int32_t stencilBits; + int32_t numSamples; + }; + + class OhosContextI { + public: + virtual void HiLog(const char *format, ...) = 0; + __attribute__((visibility("default"))) static void SetInstance(void *instance); + __attribute__((visibility("default"))) static OhosContextI &GetInstance(); + + virtual bool SetConfig(int32_t w, int32_t h, RCI_GLES_VERSION ver, RCI_PIXEL_FORMAT pf, RCI_SURFACE_TYPE st, + RCI_PROFILE tp, RCI_CONTEXT_FLAG flags) = 0; + virtual bool InitNativeWindow() = 0; + virtual bool InitEglSurface() = 0; + virtual bool InitEglContext() = 0; + + virtual void MakeCurrent() = 0; + virtual void SwapBuffer() = 0; + + virtual int32_t GetAttrib(int32_t attrType) = 0; + + virtual uint64_t CreateWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; + virtual void *GetNativeWindow(uint64_t windowId) = 0; + virtual void DestoryWindow(uint64_t windowId) = 0; + + private: + }; + + } // namespace OHOS + + + #endif \ No newline at end of file diff --git a/framework/platform/ohos/rosen_context/ohos_context_i_app.cpp b/framework/platform/ohos/rosen_context/ohos_context_i_app.cpp new file mode 100755 index 0000000000..2571562f4d --- /dev/null +++ b/framework/platform/ohos/rosen_context/ohos_context_i_app.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ohos_context_i.h" +using namespace OHOS; + +OhosContextI *g_instance = nullptr; + +void OhosContextI::SetInstance(void *instance) { + // printf("iapp: setinstance\n"); + g_instance = static_cast(instance); +} + +OhosContextI &OhosContextI::GetInstance() { + // printf("iapp getinstance\n"); + return *g_instance; +} + +void OhosContextI::HiLog(const char *format, ...) {} \ No newline at end of file diff --git a/framework/platform/ohos/tcuOhosPlatform.cpp b/framework/platform/ohos/tcuOhosPlatform.cpp new file mode 100755 index 0000000000..48bfbb1a30 --- /dev/null +++ b/framework/platform/ohos/tcuOhosPlatform.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tcuOhosPlatform.hpp" + +#include "deUniquePtr.hpp" +#include "ohos_context_i.h" + +#include "egluGLContextFactory.hpp" +#include "display/tcuOhosEglDisplayFactory.hpp" +#include "context/tcuOhosEglContextFactory.hpp" + +using de::MovePtr; +using de::UniquePtr; + +using namespace tcu; +using namespace OHOS_ROSEN; + +OhosPlatform::OhosPlatform (void) +{ + printf("OhosPlatform construct!\n"); + m_nativeDisplayFactoryRegistry.registerFactory(new OHOS_ROSEN::egl::OhosDisplayFactory()); + m_contextFactoryRegistry.registerFactory(new OHOS_ROSEN::egl::OhosContextFactory()); +} + +tcu::Platform* createOhosPlatform (void) +{ + return new tcu::OHOS_ROSEN::OhosPlatform(); +} + +#include "tcuFunctionLibrary.hpp" +class VulkanLibrary : public vk::Library +{ +public: + VulkanLibrary(const char *libraryPath) + : m_library(libraryPath != nullptr ? libraryPath : "libvulkan.so") + , m_driver(m_library) + { + } + + const vk::PlatformInterface& getPlatformInterface (void) const + { + return m_driver; + } + + const tcu::FunctionLibrary& getFunctionLibrary (void) const + { + return m_library; + } + +private: + const tcu::DynamicFunctionLibrary m_library; + const vk::PlatformDriver m_driver; +}; + + +vk::wsi::Display* OhosPlatform::createWsiDisplay(vk::wsi::Type wsiType) const +{ + // if(wsiType == vk::wsi::TYPE_OHOS){ + // printf("ok\n"); + // } + return NULL; +} + +vk::Library* OhosPlatform::createLibrary(const char *libraryPath) const +{ + return new VulkanLibrary(libraryPath); +} + +bool OhosPlatform::hasDisplay(vk::wsi::Type wsiType) const +{ + // if (wsiType == vk::wsi::TYPE_OHOS) + // return true; + return false; +} + +#include +#include "deMemory.h" +void OhosPlatform::describePlatform(std::ostream& dst) const +{ + utsname sysInfo; + deMemset(&sysInfo, 0, sizeof(sysInfo)); + + if (uname(&sysInfo) != 0) + throw std::runtime_error("uname() failed"); + + dst << "OS: " << sysInfo.sysname << " " << sysInfo.release << " " << sysInfo.version << "\n"; + dst << "CPU: " << sysInfo.machine << "\n"; +} + +void OhosPlatform::getMemoryLimits(tcu::PlatformMemoryLimits& limits) const +{ + limits.totalSystemMemory = 256*1024*1024; + limits.totalDeviceLocalMemory = 0;//128*1024*1024; + limits.deviceMemoryAllocationGranularity = 64*1024; + limits.devicePageSize = 4096; + limits.devicePageTableEntrySize = 8; + limits.devicePageTableHierarchyLevels = 3; +} \ No newline at end of file diff --git a/framework/platform/ohos/tcuOhosPlatform.hpp b/framework/platform/ohos/tcuOhosPlatform.hpp new file mode 100755 index 0000000000..0ce44d8131 --- /dev/null +++ b/framework/platform/ohos/tcuOhosPlatform.hpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _TCUOHOSPLATFORM_HPP +#define _TCUOHOSPLATFORM_HPP + +#include "tcuPlatform.hpp" +#include "gluPlatform.hpp" +#include "egluPlatform.hpp" +#include "vkPlatform.hpp" +#include "vkWsiPlatform.hpp" + +namespace tcu +{ +namespace OHOS_ROSEN +{ + class OhosPlatform : public tcu::Platform, + private eglu::Platform, + private glu::Platform, + public vk::Platform + { + public: + OhosPlatform (void); + virtual ~OhosPlatform (void) {}; + const glu::Platform& getGLPlatform (void) const { return static_cast(*this); } + const eglu::Platform& getEGLPlatform (void) const { return static_cast(*this); } + const vk::Platform& getVulkanPlatform (void) const { return static_cast(*this); } + + vk::wsi::Display* createWsiDisplay (vk::wsi::Type wsiType) const; + vk::Library* createLibrary (const char *libraryPath) const; + bool hasDisplay (vk::wsi::Type wsiType) const; + void describePlatform (std::ostream& dst) const; + void getMemoryLimits (tcu::PlatformMemoryLimits& limits) const; + private: + }; + + } +} + +tcu::Platform* createOhosPlatform (void); +#endif // _TCUOHOSPLATFORM_HPP diff --git a/framework/qphelper/CMakeLists.txt b/framework/qphelper/CMakeLists.txt index b8f80bc62d..c923fa33e1 100644 --- a/framework/qphelper/CMakeLists.txt +++ b/framework/qphelper/CMakeLists.txt @@ -25,7 +25,7 @@ set(QPHELPER_LIBS ${PNG_LIBRARY} ) -if (DE_OS_IS_UNIX OR DE_OS_IS_QNX) +if (DE_OS_IS_UNIX OR DE_OS_IS_QNX OR DE_OS_IS_OHOS) # For vsnprintf() add_definitions(-D_XOPEN_SOURCE=600) endif () diff --git a/framework/qphelper/qpCrashHandler.c b/framework/qphelper/qpCrashHandler.c index 98f924b619..6d826e60c2 100644 --- a/framework/qphelper/qpCrashHandler.c +++ b/framework/qphelper/qpCrashHandler.c @@ -33,7 +33,7 @@ #include #include -#if (DE_OS == DE_OS_UNIX) +#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OHOS) #include #include #include diff --git a/framework/qphelper/qpCrashHandler.h b/framework/qphelper/qpCrashHandler.h index ca39feaec0..22f6b6da66 100644 --- a/framework/qphelper/qpCrashHandler.h +++ b/framework/qphelper/qpCrashHandler.h @@ -25,7 +25,7 @@ #include "deDefs.h" -#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) +#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_OHOS) #define QP_USE_SIGNAL_HANDLER 1 #endif diff --git a/modules/internal/ditBuildInfoTests.cpp b/modules/internal/ditBuildInfoTests.cpp index 5de5d3b778..3ed85f3ce7 100644 --- a/modules/internal/ditBuildInfoTests.cpp +++ b/modules/internal/ditBuildInfoTests.cpp @@ -50,6 +50,8 @@ static const char *getOsName(int os) return "DE_OS_SYMBIAN"; case DE_OS_IOS: return "DE_OS_IOS"; + case DE_OS_OHOS: + return "DE_OS_OHOS"; default: return nullptr; } diff --git a/ohos/README.md b/ohos/README.md new file mode 100644 index 0000000000..8822560a11 --- /dev/null +++ b/ohos/README.md @@ -0,0 +1,64 @@ +VK-GL-CTS for OpenHarmony Instructions +================= + +This document describes how to build, port, and run the VK-GL-CTS conformance tests. + +Preparation +------------------------ + +There are two ways for Build source with OpenHarmony: +1. Download the OpenHarmony Public SDK or HarmonyOS Command Line Tools, For example: +* OpenHarmony Public SDK download url: + > https://repo.huaweicloud.com/openharmony/os/5.1.0-Release/ohos-sdk-windows_linux-public.tar.gz + +* HarmonyOS Command Line Tools download url: + > https://developer.huawei.com/consumer/cn/download/command-line-tools-for-hmos + + +2. Extract the sdk and set the environment, For example: +* set node path: + ``` + export PATH=${SDK_PATH}/tool/node/bin:$PATH + node -v + v18.20.1 + ``` + +* set hvigor path: + ``` + export PATH=${SDK_PATH}/bin:$PATH + hvigorw -v + 5.18.4 + ``` + + + +Build +------------------------ +Run the script of build files in scripts folder: + +> python scripts/ohos/build_hap.py --build-root=./ohosbuild --target=deqp --clt ~/workspace/tools/command-line-tools --sdk ~/workspace/tools/ohos-sdk-5.0.1-release +* --build-roots: build root dirname (default: ohosbuild) +* --target: deqp (default: deqp) +* --clt: Command-Line-Tools +* --sdk: OpenHarmony Public SDK + +After complete the build, the "deqpCts".hap will be find in "ohosbuild\happroject\autosign\deqpCts.hap" + + +Test +--------------------- +1. Install the hap +``` +hdc install deqpCts.hap +``` + +2. Run the case +![screenshot](./figures/Screenshot.jpeg) + +**Notice** +The default project is just for OpenHarmony, If it needs to build for HarmonyOS, after build, it should using HarmonyOS Native Project, +and then copy the "libs" and "cpp", "ets", "resources" directories to the HarmonyOS Native Project. After that it can build and run on +HarmonyOS devices. + + + diff --git a/ohos/figures/Screenshot.jpeg b/ohos/figures/Screenshot.jpeg new file mode 100755 index 0000000000..da7d394a9d Binary files /dev/null and b/ohos/figures/Screenshot.jpeg differ diff --git a/ohos/happroject/AppScope/app.json5 b/ohos/happroject/AppScope/app.json5 new file mode 100755 index 0000000000..55e8d4ee49 --- /dev/null +++ b/ohos/happroject/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.OpenHarmony.app.test", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/happroject/AppScope/resources/base/element/string.json b/ohos/happroject/AppScope/resources/base/element/string.json new file mode 100755 index 0000000000..af48e0cb66 --- /dev/null +++ b/ohos/happroject/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "base test" + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/AppScope/resources/base/media/app_icon.png b/ohos/happroject/AppScope/resources/base/media/app_icon.png new file mode 100755 index 0000000000..cd45accb1d Binary files /dev/null and b/ohos/happroject/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/happroject/a.bat b/ohos/happroject/a.bat new file mode 100755 index 0000000000..886976460d --- /dev/null +++ b/ohos/happroject/a.bat @@ -0,0 +1 @@ +hdc shell \ No newline at end of file diff --git a/ohos/happroject/autosign/OpenHarmony.p12 b/ohos/happroject/autosign/OpenHarmony.p12 new file mode 100755 index 0000000000..f84fd83098 Binary files /dev/null and b/ohos/happroject/autosign/OpenHarmony.p12 differ diff --git a/ohos/happroject/autosign/OpenHarmonyProfileRelease.pem b/ohos/happroject/autosign/OpenHarmonyProfileRelease.pem new file mode 100755 index 0000000000..129a1378fa --- /dev/null +++ b/ohos/happroject/autosign/OpenHarmonyProfileRelease.pem @@ -0,0 +1,44 @@ +-----BEGIN CERTIFICATE----- +MIICRDCCAcmgAwIBAgIED+E4izAMBggqhkjOPQQDAwUAMGgxCzAJBgNVBAYTAkNO +MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh +bTEoMCYGA1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTAeFw0y +MTAyMDIxMjE0MThaFw00OTEyMzExMjE0MThaMGgxCzAJBgNVBAYTAkNOMRQwEgYD +VQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVhbTEoMCYG +A1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABE023XmRaw2DnO8NSsb+KG/uY0FtS3u5LQucdr3qWVnRW5ui +QIL6ttNZBEeLTUeYcJZCpayg9Llf+1SmDA7dY4iP2EcRo4UN3rilovtfFfsmH4ty +3SApHVFzWUl+NwdH8KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFBc6EKGrGXzlAE+s0Zgnsphadw7NMAwGCCqGSM49BAMDBQAD +ZwAwZAIwd1p3JzHN93eoPped1li0j64npgqNzwy4OrkehYAqNXpcpaEcLZ7UxW8E +I2lZJ3SbAjAkqySHb12sIwdSFKSN9KCMMEo/eUT5dUXlcKR2nZz0MJdxT5F51qcX +1CumzkcYhgU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICYTCCAeWgAwIBAgIEHmXAPTAMBggqhkjOPQQDAwUAMGgxCzAJBgNVBAYTAkNO +MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh +bTEoMCYGA1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTAeFw0y +MTAyMDIxMjE1MzJaFw00OTEyMzExMjE1MzJaMGMxCzAJBgNVBAYTAkNOMRQwEgYD +VQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVhbTEjMCEG +A1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAQhnu7Hna8XNa2KyqRf5+lBJScE4xqf89N0g0OuqAb2re8nGsvWkw26 +uDekfnBYicd+G3Cydqa2zFIwV7Talyg2ULW3r8KbGpyl84mJEPPRmCGJ+H9gtCsf ++OrJ4Y76LVWjYzBhMB8GA1UdIwQYMBaAFBc6EKGrGXzlAE+s0Zgnsphadw7NMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTbhrciFtUL +oUu33SV7ufEFfaItRzAMBggqhkjOPQQDAwUAA2gAMGUCMG3cXjiDmXTvf7D4Omhf +qcc2nuO+EMfWE+N9ZhBP5UhV34mAGWi3SfLU6rcV0urWEQIxAMYIb3epOnKhUrcm +Lfu1WKzFlpYQwmw73RaCHP2I3k6NcuWOYeNwWXSNZ8o0nzvaLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICPDCCAb+gAwIBAgIEN6dtvjAMBggqhkjOPQQDAwUAMGMxCzAJBgNVBAYTAkNO +MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh +bTEjMCEGA1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwHhcNMjEwMjAy +MTIyMTA1WhcNNDkxMjMxMTIyMTA1WjBwMQswCQYDVQQGEwJDTjEUMBIGA1UEChML +T3Blbkhhcm1vbnkxGTAXBgNVBAsTEE9wZW5IYXJtb255IFRlYW0xMDAuBgNVBAMT +J09wZW5IYXJtb255IEFwcGxpY2F0aW9uIFByb2ZpbGUgUmVsZWFzZTBZMBMGByqG +SM49AgEGCCqGSM49AwEHA0IABFfPAuu5prLiQXG+FcmSKJqtRjeDDZgfAeitKsSM +3tzhHk2oN/UD0vHGbgIrVD8fv8igUZEJFsOTNM4DbovGGJqjUjBQMB8GA1UdIwQY +MBaAFNuGtyIW1QuhS7fdJXu58QV9oi1HMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4E +FgQUy2Hpvad6TtTPlbOE7AX99l8NAVIwDAYIKoZIzj0EAwMFAANpADBmAjEArI6u +CYJiea5IJBFC7JBluWgGshKdEHdGPv3sopi34kKPZNxm9eGn9OGNBjZg/qqdAjEA +oIZqet/+DDpB7CRdTAUhisGmgE8w3ETgiibdUhrAAUOo6SSzozUQeKn+c37l5A+z +-----END CERTIFICATE----- diff --git a/ohos/happroject/autosign/UnsgnedReleasedProfileTemplate.json b/ohos/happroject/autosign/UnsgnedReleasedProfileTemplate.json new file mode 100755 index 0000000000..4f26714176 --- /dev/null +++ b/ohos/happroject/autosign/UnsgnedReleasedProfileTemplate.json @@ -0,0 +1,27 @@ +{ + "version-name": "2.0.0", + "version-code": 2, + "app-distribution-type": "os_integration", + "uuid": "5027b99e-5f9e-465d-9508-a9e0134ffe18", + "validity": { + "not-before": 1594865258, + "not-after": 1689473258 + }, + "type": "release", + "bundle-info": { + "developer-id": "OpenHarmony", + "distribution-certificate": "-----BEGIN CERTIFICATE-----\nMIICMzCCAbegAwIBAgIEaOC/zDAMBggqhkjOPQQDAwUAMGMxCzAJBgNVBAYTAkNO\nMRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh\nbTEjMCEGA1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwHhcNMjEwMjAy\nMTIxOTMxWhcNNDkxMjMxMTIxOTMxWjBoMQswCQYDVQQGEwJDTjEUMBIGA1UEChML\nT3Blbkhhcm1vbnkxGTAXBgNVBAsTEE9wZW5IYXJtb255IFRlYW0xKDAmBgNVBAMT\nH09wZW5IYXJtb255IEFwcGxpY2F0aW9uIFJlbGVhc2UwWTATBgcqhkjOPQIBBggq\nhkjOPQMBBwNCAATbYOCQQpW5fdkYHN45v0X3AHax12jPBdEDosFRIZ1eXmxOYzSG\nJwMfsHhUU90E8lI0TXYZnNmgM1sovubeQqATo1IwUDAfBgNVHSMEGDAWgBTbhrci\nFtULoUu33SV7ufEFfaItRzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFPtxruhl\ncRBQsJdwcZqLu9oNUVgaMAwGCCqGSM49BAMDBQADaAAwZQIxAJta0PQ2p4DIu/ps\nLMdLCDgQ5UH1l0B4PGhBlMgdi2zf8nk9spazEQI/0XNwpft8QAIwHSuA2WelVi/o\nzAlF08DnbJrOOtOnQq5wHOPlDYB4OtUzOYJk9scotrEnJxJzGsh/\n-----END CERTIFICATE-----\n", + "bundle-name": "com.OpenHarmony.app.test", + "apl": "system_core", + "app-feature": "hos_system_app" + }, + "acls": { + "allowed-acls": [ + "" + ] + }, + "permissions": { + "restricted-permissions": [] + }, + "issuer": "pki_internal" +} diff --git a/ohos/happroject/autosign/app1-profile.p7b b/ohos/happroject/autosign/app1-profile.p7b new file mode 100755 index 0000000000..3af6acab79 Binary files /dev/null and b/ohos/happroject/autosign/app1-profile.p7b differ diff --git a/ohos/happroject/autosign/app1.cer b/ohos/happroject/autosign/app1.cer new file mode 100755 index 0000000000..898ca9eb1c --- /dev/null +++ b/ohos/happroject/autosign/app1.cer @@ -0,0 +1,45 @@ +-----BEGIN CERTIFICATE----- +MIICSTCCAc+gAwIBAgIFAL1lEbkwCgYIKoZIzj0EAwIwYzELMAkGA1UEBhMCQ04x +FDASBgNVBAoMC09wZW5IYXJtb255MRkwFwYDVQQLDBBPcGVuSGFybW9ueSBUZWFt +MSMwIQYDVQQDDBpPcGVuSGFybW9ueSBBcHBsaWNhdGlvbiBDQTAeFw0yNTA3MDEw +MjAwNTJaFw0yNjA3MDEwMjAwNTJaMGgxCzAJBgNVBAYTAkNOMRQwEgYDVQQKDAtP +cGVuSGFybW9ueTEZMBcGA1UECwwQT3Blbkhhcm1vbnkgVGVhbTEoMCYGA1UEAwwf +T3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUmVsZWFzZTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABEbcRm7Lwylqxb5s051fFlK+GDKWq4NeffjuO/UmpCJZPKD+2Mfs +G+L+FOZX+ExLgYhb3pItOTixPr0Neb6o3SejazBpMB0GA1UdDgQWBBT2DFtz5tq/ +skBexSfV2RCSWcN+sTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUE +DDAKBggrBgEFBQcDAzAYBgwrBgEEAY9bAoJ4AQMECDAGAgEBCgEAMAoGCCqGSM49 +BAMCA2gAMGUCMQCHsck0VduSC/SCJoFLcIppGIZeagmdkAsI0cLP56klsCwRsjgi +i0ycj9M2aaHrpdUCMG/3JLuqVXhH7vg8AkyZ7glQZ9cb6z3GbevApsS8hwXki2TG +rhGzgYLWF14TToZI7Q== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICYTCCAeWgAwIBAgIEHmXAPTAMBggqhkjOPQQDAwUAMGgxCzAJBgNVBAYTAkNO +MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh +bTEoMCYGA1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTAeFw0y +MTAyMDIxMjE1MzJaFw00OTEyMzExMjE1MzJaMGMxCzAJBgNVBAYTAkNOMRQwEgYD +VQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVhbTEjMCEG +A1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAQhnu7Hna8XNa2KyqRf5+lBJScE4xqf89N0g0OuqAb2re8nGsvWkw26 +uDekfnBYicd+G3Cydqa2zFIwV7Talyg2ULW3r8KbGpyl84mJEPPRmCGJ+H9gtCsf ++OrJ4Y76LVWjYzBhMB8GA1UdIwQYMBaAFBc6EKGrGXzlAE+s0Zgnsphadw7NMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTbhrciFtUL +oUu33SV7ufEFfaItRzAMBggqhkjOPQQDAwUAA2gAMGUCMG3cXjiDmXTvf7D4Omhf +qcc2nuO+EMfWE+N9ZhBP5UhV34mAGWi3SfLU6rcV0urWEQIxAMYIb3epOnKhUrcm +Lfu1WKzFlpYQwmw73RaCHP2I3k6NcuWOYeNwWXSNZ8o0nzvaLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICRDCCAcmgAwIBAgIED+E4izAMBggqhkjOPQQDAwUAMGgxCzAJBgNVBAYTAkNO +MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh +bTEoMCYGA1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTAeFw0y +MTAyMDIxMjE0MThaFw00OTEyMzExMjE0MThaMGgxCzAJBgNVBAYTAkNOMRQwEgYD +VQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVhbTEoMCYG +A1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABE023XmRaw2DnO8NSsb+KG/uY0FtS3u5LQucdr3qWVnRW5ui +QIL6ttNZBEeLTUeYcJZCpayg9Llf+1SmDA7dY4iP2EcRo4UN3rilovtfFfsmH4ty +3SApHVFzWUl+NwdH8KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFBc6EKGrGXzlAE+s0Zgnsphadw7NMAwGCCqGSM49BAMDBQAD +ZwAwZAIwd1p3JzHN93eoPped1li0j64npgqNzwy4OrkehYAqNXpcpaEcLZ7UxW8E +I2lZJ3SbAjAkqySHb12sIwdSFKSN9KCMMEo/eUT5dUXlcKR2nZz0MJdxT5F51qcX +1CumzkcYhgU= +-----END CERTIFICATE----- diff --git a/ohos/happroject/autosign/rootCA.cer b/ohos/happroject/autosign/rootCA.cer new file mode 100755 index 0000000000..20f68eac36 --- /dev/null +++ b/ohos/happroject/autosign/rootCA.cer @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRDCCAcmgAwIBAgIED+E4izAMBggqhkjOPQQDAwUAMGgxCzAJBgNVBAYTAkNO +MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh +bTEoMCYGA1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTAeFw0y +MTAyMDIxMjE0MThaFw00OTEyMzExMjE0MThaMGgxCzAJBgNVBAYTAkNOMRQwEgYD +VQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVhbTEoMCYG +A1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABE023XmRaw2DnO8NSsb+KG/uY0FtS3u5LQucdr3qWVnRW5ui +QIL6ttNZBEeLTUeYcJZCpayg9Llf+1SmDA7dY4iP2EcRo4UN3rilovtfFfsmH4ty +3SApHVFzWUl+NwdH8KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFBc6EKGrGXzlAE+s0Zgnsphadw7NMAwGCCqGSM49BAMDBQAD +ZwAwZAIwd1p3JzHN93eoPped1li0j64npgqNzwy4OrkehYAqNXpcpaEcLZ7UxW8E +I2lZJ3SbAjAkqySHb12sIwdSFKSN9KCMMEo/eUT5dUXlcKR2nZz0MJdxT5F51qcX +1CumzkcYhgU= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/ohos/happroject/autosign/subCA.cer b/ohos/happroject/autosign/subCA.cer new file mode 100755 index 0000000000..6adeca7790 --- /dev/null +++ b/ohos/happroject/autosign/subCA.cer @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYTCCAeWgAwIBAgIEHmXAPTAMBggqhkjOPQQDAwUAMGgxCzAJBgNVBAYTAkNO +MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh +bTEoMCYGA1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTAeFw0y +MTAyMDIxMjE1MzJaFw00OTEyMzExMjE1MzJaMGMxCzAJBgNVBAYTAkNOMRQwEgYD +VQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVhbTEjMCEG +A1UEAxMaT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gQ0EwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAQhnu7Hna8XNa2KyqRf5+lBJScE4xqf89N0g0OuqAb2re8nGsvWkw26 +uDekfnBYicd+G3Cydqa2zFIwV7Talyg2ULW3r8KbGpyl84mJEPPRmCGJ+H9gtCsf ++OrJ4Y76LVWjYzBhMB8GA1UdIwQYMBaAFBc6EKGrGXzlAE+s0Zgnsphadw7NMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTbhrciFtUL +oUu33SV7ufEFfaItRzAMBggqhkjOPQQDAwUAA2gAMGUCMG3cXjiDmXTvf7D4Omhf +qcc2nuO+EMfWE+N9ZhBP5UhV34mAGWi3SfLU6rcV0urWEQIxAMYIb3epOnKhUrcm +Lfu1WKzFlpYQwmw73RaCHP2I3k6NcuWOYeNwWXSNZ8o0nzvaLg== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/ohos/happroject/build-profile.json5 b/ohos/happroject/build-profile.json5 new file mode 100755 index 0000000000..de836c1b73 --- /dev/null +++ b/ohos/happroject/build-profile.json5 @@ -0,0 +1,37 @@ +{ + "app": { + "signingConfigs": [ + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": 11, + "compatibleSdkVersion": 11, + "runtimeOS": "OpenHarmony" + } + ], + "buildModeSet": [ + { + "name": "debug" + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/build/outputs/default/happroject-default-unsigned.app b/ohos/happroject/build/outputs/default/happroject-default-unsigned.app new file mode 100755 index 0000000000..0153adca13 Binary files /dev/null and b/ohos/happroject/build/outputs/default/happroject-default-unsigned.app differ diff --git a/ohos/happroject/build/outputs/default/pack.info b/ohos/happroject/build/outputs/default/pack.info new file mode 100755 index 0000000000..00fa45391a --- /dev/null +++ b/ohos/happroject/build/outputs/default/pack.info @@ -0,0 +1,48 @@ +{ + "summary": { + "app": { + "bundleName": "com.OpenHarmony.app.test", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "modules": [ + { + "mainAbility": "EntryAbility", + "deviceType": [ + "default", + "tablet" + ], + "abilities": [ + { + "name": "EntryAbility", + "label": "$string:EntryAbility_label" + } + ], + "distro": { + "moduleType": "entry", + "installationFree": false, + "deliveryWithInstall": true, + "moduleName": "entry" + }, + "apiVersion": { + "compatible": 11, + "releaseType": "Release", + "target": 11 + } + } + ] + }, + "packages": [ + { + "deviceType": [ + "default", + "tablet" + ], + "moduleType": "entry", + "deliveryWithInstall": true, + "name": "entry-default" + } + ] +} diff --git a/ohos/happroject/entry/.gitignore b/ohos/happroject/entry/.gitignore new file mode 100755 index 0000000000..e2713a2779 --- /dev/null +++ b/ohos/happroject/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/happroject/entry/build-profile.json5 b/ohos/happroject/entry/build-profile.json5 new file mode 100755 index 0000000000..9d5e5d5da5 --- /dev/null +++ b/ohos/happroject/entry/build-profile.json5 @@ -0,0 +1,19 @@ +{ + "apiType": "stageMode", + "buildOption": { + "externalNativeOptions": { + "path": "./src/main/cpp/CMakeLists.txt", + "arguments": "", + "cppFlags": "", + } + }, + "targets": [ + { + "name": "default", + "runtimeOS": "OpenHarmony" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/entry/hvigorfile.ts b/ohos/happroject/entry/hvigorfile.ts new file mode 100755 index 0000000000..c6edcd9048 --- /dev/null +++ b/ohos/happroject/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/ohos/happroject/entry/libs/README.txt b/ohos/happroject/entry/libs/README.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ohos/happroject/entry/oh-package-lock.json5 b/ohos/happroject/entry/oh-package-lock.json5 new file mode 100755 index 0000000000..c5f3bf908e --- /dev/null +++ b/ohos/happroject/entry/oh-package-lock.json5 @@ -0,0 +1,19 @@ +{ + "meta": { + "stableOrder": true, + "enableUnifiedLockfile": false + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "libentry.so@src/main/cpp/types/libentry": "libentry.so@src/main/cpp/types/libentry" + }, + "packages": { + "libentry.so@src/main/cpp/types/libentry": { + "name": "libentry.so", + "version": "0.0.0", + "resolved": "src/main/cpp/types/libentry", + "registryType": "local" + } + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/oh-package.json5 b/ohos/happroject/entry/oh-package.json5 new file mode 100755 index 0000000000..54cb066266 --- /dev/null +++ b/ohos/happroject/entry/oh-package.json5 @@ -0,0 +1,11 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "libentry.so": "file:./src/main/cpp/types/libentry" + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/CMakeLists.txt b/ohos/happroject/entry/src/main/cpp/CMakeLists.txt new file mode 100755 index 0000000000..7ba1be6f04 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,28 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.4.1) +project(VncViewer) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/common + ${NATIVERENDER_ROOT_PATH}/napi + ${NATIVERENDER_ROOT_PATH}/render +) + +set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) + +add_library(entry SHARED + render/egl_core.cpp + render/plugin_render.cpp + render/app_context.cpp + plugin_manager.cpp + napi/napi_init.cpp + ) + +target_link_directories(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}) + +target_link_libraries(entry PUBLIC libEGL.so + libGLESv3.so libace_napi.z.so libhilog_ndk.z.so + libace_ndk.z.so libace_napi.z.so libuv.so libnative_vsync.so + libdeqp.so librawfile.z.so) \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/common/native_common.h b/ohos/happroject/entry/src/main/cpp/common/native_common.h new file mode 100755 index 0000000000..5d57b4b8bf --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/common/native_common.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _NATIVE_COMMON_H_ +#define _NATIVE_COMMON_H_ + +#define NAPI_RETVAL_NOTHING + +#define GET_AND_THROW_LAST_ERROR(env) \ + do { \ + const napi_extended_error_info* errorInfo = nullptr; \ + napi_get_last_error_info((env), &errorInfo); \ + bool isPending = false; \ + napi_is_exception_pending((env), &isPending); \ + if (!isPending && errorInfo != nullptr) { \ + const char* errorMessage = \ + errorInfo->error_message != nullptr ? errorInfo->error_message : "empty error message"; \ + napi_throw_error((env), nullptr, errorMessage); \ + } \ + } while (0) + +#define NAPI_ASSERT_BASE(env, assertion, message, retVal) \ + do { \ + if (!(assertion)) { \ + napi_throw_error((env), nullptr, "assertion (" #assertion ") failed: " message); \ + return retVal; \ + } \ + } while (0) + +#define NAPI_ASSERT(env, assertion, message) NAPI_ASSERT_BASE(env, assertion, message, nullptr) + +#define NAPI_ASSERT_RETURN_VOID(env, assertion, message) NAPI_ASSERT_BASE(env, assertion, message, NAPI_RETVAL_NOTHING) + +#define NAPI_CALL_BASE(env, theCall, retVal) \ + do { \ + if ((theCall) != napi_ok) { \ + GET_AND_THROW_LAST_ERROR((env)); \ + return retVal; \ + } \ + } while (0) + +#define NAPI_CALL(env, theCall) NAPI_CALL_BASE(env, theCall, nullptr) + +#define NAPI_CALL_RETURN_VOID(env, theCall) NAPI_CALL_BASE(env, theCall, NAPI_RETVAL_NOTHING) + +#define DECLARE_NAPI_PROPERTY(name, val) \ + { \ + (name), nullptr, nullptr, nullptr, nullptr, val, napi_default, nullptr \ + } + +#define DECLARE_NAPI_STATIC_PROPERTY(name, val) \ + { \ + (name), nullptr, nullptr, nullptr, nullptr, val, napi_static, nullptr \ + } + +#define DECLARE_NAPI_FUNCTION(name, func) \ + { \ + (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr \ + } + +#define DECLARE_NAPI_FUNCTION_WITH_DATA(name, func, data) \ + { \ + (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, data \ + } + +#define DECLARE_NAPI_STATIC_FUNCTION(name, func) \ + { \ + (name), nullptr, (func), nullptr, nullptr, nullptr, napi_static, nullptr \ + } + +#define DECLARE_NAPI_GETTER(name, getter) \ + { \ + (name), nullptr, nullptr, (getter), nullptr, nullptr, napi_default, nullptr \ + } + +#define DECLARE_NAPI_SETTER(name, setter) \ + { \ + (name), nullptr, nullptr, nullptr, (setter), nullptr, napi_default, nullptr \ + } + +#define DECLARE_NAPI_GETTER_SETTER(name, getter, setter) \ + { \ + (name), nullptr, nullptr, (getter), (setter), nullptr, napi_default, nullptr \ + } + +#endif /* _NATIVE_COMMON_H_ */ diff --git a/ohos/happroject/entry/src/main/cpp/common/plugin_common.h b/ohos/happroject/entry/src/main/cpp/common/plugin_common.h new file mode 100755 index 0000000000..9f22a9949f --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/common/plugin_common.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PLUGIN_COMMON_H_ +#define _PLUGIN_COMMON_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define APP_LOG_DOMAIN 0x0001 +#define APP_LOG_TAG "vkglcts" +#define LOGI(...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, APP_LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define LOGD(...) ((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, APP_LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define LOGW(...) ((void)OH_LOG_Print(LOG_APP, LOG_WARN, APP_LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define LOGE(...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, APP_LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) + +constexpr int32_t RGB_565 = 2; +constexpr int32_t RGBA_8888 = 3; + +constexpr int32_t STR_MAX_SIZE = 200; +constexpr int32_t LONG_STR_MAX_SIZE = 1024; +constexpr int32_t ERR_OK = 0; +constexpr int8_t NO_ERROR = 0; +constexpr int8_t ERROR = -1; +constexpr uint8_t PARAM0 = 0; +constexpr uint8_t PARAM1 = 1; +constexpr uint8_t PARAM2 = 2; +constexpr uint8_t PARAM3 = 3; +constexpr uint8_t PARAM4 = 4; +constexpr uint8_t PARAM5 = 5; +constexpr uint8_t PARAM6 = 6; +constexpr uint8_t PARAM7 = 7; +constexpr uint8_t PARAM8 = 8; +constexpr uint8_t PARAM9 = 9; +constexpr uint8_t PARAM10 = 10; +constexpr uint8_t PARAM11 = 11; +constexpr uint8_t PARAM12 = 12; +constexpr uint8_t PARAM60 = 60; +constexpr uint8_t PARAM100 = 100; +constexpr uint16_t PARAM1000 = 1000; +constexpr uint16_t PARAM1024 = 1024; +constexpr uint32_t PARAM100W = 1000000; + +constexpr int32_t ARGS_ONE = 1; +constexpr int32_t ARGS_TWO = 2; +constexpr int32_t ONLY_CALLBACK_MAX_PARA = 1; +constexpr int32_t ONLY_CALLBACK_MIN_PARA = 0; + +#endif // _PLUGIN_COMMON_H_ \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/napi/napi_init.cpp b/ohos/happroject/entry/src/main/cpp/napi/napi_init.cpp new file mode 100755 index 0000000000..381e6722b2 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/napi/napi_init.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "plugin_common.h" +#include "plugin_manager.h" + +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports) +{ + LOGI("Init"); + + bool ret = PluginManager::GetInstance()->Export(env, exports); + if (!ret) { + LOGE("Init failed"); + } + return exports; +} + +/* + * Napi Module define + */ +static napi_module nativerenderModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "nativerender", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; +/* + * Module register function + */ +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&nativerenderModule); +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/plugin_manager.cpp b/ohos/happroject/entry/src/main/cpp/plugin_manager.cpp new file mode 100755 index 0000000000..345919d760 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/plugin_manager.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +#include "plugin_manager.h" +#include "plugin_common.h" + +enum ContextType { + APP_LIFECYCLE = 0, + JS_PAGE_LIFECYCLE, +}; + +PluginManager PluginManager::manager_; + +void VsyncCallback(long long timestamp, void *data) { + PluginManager *pm = (PluginManager *)data; + pm->OnVsync(); +} + +void PluginManager::DoVsync(){ + { + std::lock_guard lock(mutex_); + std::vector remove; + for (auto it : renderContextMap_) { + if (!it.second.render_->OnVsync()) { + remove.push_back(it.first); + } + } + for (auto it : remove) { + PluginRender::RemoveInstance(it); + renderContextMap_.erase(it); + } + } + + OH_NativeVSync_RequestFrame(vsync_, VsyncCallback, this); +} + +void PluginManager::OnVsync() { + uv_work_t *work = new uv_work_t; + uv_queue_work( + mainLoop_, work, [](uv_work_t *) {}, + [](uv_work_t *work, int status) { + delete work; + PluginManager::GetInstance()->DoVsync(); + }); +} + +PluginManager::PluginManager() { + vsync_ = OH_NativeVSync_Create("vkglcts", 2); + OH_NativeVSync_RequestFrame(vsync_, VsyncCallback, this); +} + +PluginManager::~PluginManager() { OH_NativeVSync_Destroy(vsync_); } + +bool PluginManager::Export(napi_env env, napi_value exports) { + napi_status status; + napi_value exportInstance = nullptr; + OH_NativeXComponent *nativeXComponent = nullptr; + int32_t ret; + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + + status = napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance); + if (status != napi_ok) { + LOGE("Export false 1"); + return false; + } + + status = napi_unwrap(env, exportInstance, reinterpret_cast(&nativeXComponent)); + if (status != napi_ok) { + LOGE("Export false 2"); + return false; + } + + ret = OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize); + if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + LOGE("Export false 3"); + return false; + } + + std::string id(idStr); + auto context = PluginManager::GetInstance(); + if (context) { + { + uv_loop_t *loop = nullptr; + napi_get_uv_event_loop(env, &loop); + context->OnCreateNative(env, loop); + } + std::lock_guard lock(mutex_); + renderContextMap_[id].native_ = nativeXComponent; + renderContextMap_[id].render_ = PluginRender::GetInstance(id); + renderContextMap_[id].render_->SetNativeXComponent(nativeXComponent); + renderContextMap_[id].render_->Export(env, exports); + LOGE("Export ok %{public}s", id.c_str()); + return true; + } + LOGE("Export false 4"); + return false; +} + +void PluginManager::MainOnMessage(const uv_async_t *req) { LOGD("MainOnMessage Triggered"); } +napi_value PluginManager::NapiOnCreate(napi_env env, napi_callback_info info) { + LOGD("PluginManager::NapiOnCreate"); + uv_loop_t *loop = nullptr; + uv_check_t *check = new uv_check_t; + NAPI_CALL(env, napi_get_uv_event_loop(env, &loop)); + PluginManager::GetInstance()->OnCreateNative(env, loop); + return nullptr; +} + +napi_value PluginManager::NapiOnShow(napi_env env, napi_callback_info info) { + PluginManager::GetInstance()->OnShowNative(); + return nullptr; +} + +napi_value PluginManager::NapiOnHide(napi_env env, napi_callback_info info) { + PluginManager::GetInstance()->OnHideNative(); + return nullptr; +} + +napi_value PluginManager::NapiOnDestroy(napi_env env, napi_callback_info info) { + PluginManager::GetInstance()->OnDestroyNative(); + return nullptr; +} + +void PluginManager::OnCreateNative(napi_env env, uv_loop_t *loop) { + mainEnv_ = env; + mainLoop_ = loop; + if (mainLoop_) { + uv_async_init(mainLoop_, &mainOnMessageSignal_, reinterpret_cast(PluginManager::MainOnMessage)); + } +} + +void PluginManager::OnShowNative() { LOGD("PluginManager::OnShowNative"); } +void PluginManager::OnHideNative() { LOGD("PluginManager::OnHideNative"); } +void PluginManager::OnDestroyNative() { LOGD("PluginManager::OnDestroyNative"); } + +napi_value PluginManager::NapiOnPageShow(napi_env env, napi_callback_info info) { + LOGD("PluginManager::NapiOnPageShow"); + return nullptr; +} + +napi_value PluginManager::NapiOnPageHide(napi_env env, napi_callback_info info) { + LOGD("PluginManager::NapiOnPageHide"); + return nullptr; +} + +void PluginManager::OnPageShowNative() { LOGD("PluginManager::OnPageShowNative"); } + +void PluginManager::OnPageHideNative() { LOGD("PluginManager::OnPageHideNative"); } \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/plugin_manager.h b/ohos/happroject/entry/src/main/cpp/plugin_manager.h new file mode 100755 index 0000000000..15bfd81c96 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/plugin_manager.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PLUGIN_MANAGER_H_ +#define _PLUGIN_MANAGER_H_ + +#include +#include +#include + +#include +#include +#include +#include + +#include "native_common.h" +#include "plugin_render.h" + +struct RenderContext { + OH_NativeXComponent* native_; + PluginRender* render_; +}; + +class PluginManager { +public: + PluginManager(); + ~PluginManager(); + void OnVsync(); + void DoVsync(); + + static PluginManager* GetInstance() + { + return &PluginManager::manager_; + } + + // static napi_value GetContext(napi_env env, napi_callback_info info); + + /******************************APP Lifecycle******************************/ + static napi_value NapiOnCreate(napi_env env, napi_callback_info info); + static napi_value NapiOnShow(napi_env env, napi_callback_info info); + static napi_value NapiOnHide(napi_env env, napi_callback_info info); + static napi_value NapiOnDestroy(napi_env env, napi_callback_info info); + + void OnCreateNative(napi_env env, uv_loop_t* loop); + void OnShowNative(); + void OnHideNative(); + void OnDestroyNative(); + /*********************************************************************/ + + /******************************声明式范式******************************/ + /** JS Page : Lifecycle **/ + static napi_value NapiOnPageShow(napi_env env, napi_callback_info info); + static napi_value NapiOnPageHide(napi_env env, napi_callback_info info); + void OnPageShowNative(); + void OnPageHideNative(); + /*************************************************************************/ + +public: + // Napi export + bool Export(napi_env env, napi_value exports); +private: + static void MainOnMessage(const uv_async_t* req); + static PluginManager manager_; + + std::string id_; + std::unordered_map renderContextMap_; + OH_NativeVSync *vsync_ = nullptr; + std::mutex mutex_; + bool bInited; + +public: + napi_env mainEnv_ = nullptr; + uv_loop_t* mainLoop_ = nullptr; + uv_async_t mainOnMessageSignal_ {}; +}; + +#endif // _PLUGIN_MANAGER_H_ \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/render/app_context.cpp b/ohos/happroject/entry/src/main/cpp/render/app_context.cpp new file mode 100755 index 0000000000..b0a7eb13d0 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/render/app_context.cpp @@ -0,0 +1,339 @@ +#include + +#include "app_context.h" +#include "plugin_common.h" + +namespace OHOS { + void AppContext::HiLog(const char *format, ...) { + char buffer[1024 * 10]; + va_list args; + + } + bool AppContext::InitEgl() { + if (eglInited_) { + return true; + } + eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (eglDisplay_ == EGL_NO_DISPLAY) { + printf("Failed to create EGLDisplay gl errno : %x", eglGetError()); + return false; + } + + EGLint major, minor; + if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) { + printf("Failed to initialize EGLDisplay"); + return false; + } + + glDepthMask(GL_TRUE); + + eglGetConfigs(eglDisplay_, NULL, 0, &configCount_); + allConfigs_ = new EGLConfig[configCount_]; + eglGetConfigs(eglDisplay_, allConfigs_, configCount_, &configCount_); + + printf("config count : %d\n", configCount_); + for (int i = 0; i < configCount_; i++) { + ShowConfig(allConfigs_[i]); + } + eglInited_ = true; + return true; + } + void AppContext::ShowConfig(EGLConfig cfg) { + EGLint red, green, blue, alpha, depth, stencil, samples, sft, rt; + + eglGetConfigAttrib(eglDisplay_, cfg, EGL_RED_SIZE, &red); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_GREEN_SIZE, &green); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_BLUE_SIZE, &blue); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_ALPHA_SIZE, &alpha); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_DEPTH_SIZE, &depth); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_STENCIL_SIZE, &stencil); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_SAMPLES, &samples); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_SURFACE_TYPE, &sft); + eglGetConfigAttrib(eglDisplay_, cfg, EGL_RENDERABLE_TYPE, &rt); + + HiLog("%8d%8d%8d%8d%8d%8d%8d%8d%8d\n", red, green, blue, alpha, depth, stencil, samples, sft, rt); + } + bool AppContext::SetConfig(int32_t w, int32_t h, RCI_GLES_VERSION ver, RCI_PIXEL_FORMAT pf, RCI_SURFACE_TYPE st, + RCI_PROFILE tp, RCI_CONTEXT_FLAG flags) { + if (!eglInited_) { + eglInited_ = InitEgl(); + } + HiLog("w:%d,h:%d,ver:%d,pf.redBits:%d,st:%d,tp:%d,flags:%d\n", w, h, ver, pf.redBits, st, tp, flags); + glesVersion_ = ver; + typeProfile_ = tp; + contextFlags_ = flags; + surfaceType_ = st; + width_ = w; + height_ = h; + pixelFormat_ = pf; + + EGLint eglApi; + switch (typeProfile_) { + case RCI_PROFILE::ES: + eglApi = EGL_OPENGL_ES_API; + break; + case RCI_PROFILE::CORE: + eglApi = EGL_OPENGL_API; + break; + case RCI_PROFILE::COMPATIBILITY: + eglApi = EGL_OPENGL_API; + break; + default: + return false; + } + if (eglBindAPI(eglApi) == EGL_FALSE) { + HiLog("Failed to bind OpenGL ES API"); + return false; + } + + std::vector frameBufferAttribs; + frameBufferAttribs.push_back(EGL_SURFACE_TYPE); + switch (surfaceType_) { + case RCI_SURFACE_TYPE::NONE: + HiLog("EGL_SURFACE_TYPE:EGL_NONE"); + frameBufferAttribs.push_back(EGL_DONT_CARE); + break; + case RCI_SURFACE_TYPE::PBUFFER: + HiLog("EGL_SURFACE_TYPE:EGL_PBUFFER"); + frameBufferAttribs.push_back(EGL_PBUFFER_BIT); + break; + case RCI_SURFACE_TYPE::PIXMAP: + HiLog("EGL_SURFACE_TYPE:EGL_PIXMAP"); + frameBufferAttribs.push_back(EGL_PIXMAP_BIT); + break; + case RCI_SURFACE_TYPE::WINDOW: + HiLog("EGL_SURFACE_TYPE:EGL_WINDOW ok"); + frameBufferAttribs.push_back(EGL_WINDOW_BIT); + break; + default: + HiLog("EGL_SURFACE_TYPE:unknown"); + frameBufferAttribs.push_back(EGL_WINDOW_BIT); + break; + } + + if (pixelFormat_.redBits != -1) { + frameBufferAttribs.push_back(EGL_RED_SIZE); + frameBufferAttribs.push_back(pixelFormat_.redBits); + HiLog("EGL_RED_SIZE:%d", pixelFormat_.redBits); + } + if (pixelFormat_.greenBits != -1) { + frameBufferAttribs.push_back(EGL_GREEN_SIZE); + frameBufferAttribs.push_back(pixelFormat_.greenBits); + HiLog("EGL_GREEN_SIZE:%d", pixelFormat_.greenBits); + } + if (pixelFormat_.blueBits != -1) { + frameBufferAttribs.push_back(EGL_BLUE_SIZE); + frameBufferAttribs.push_back(pixelFormat_.blueBits); + HiLog("EGL_BLUE_SIZE:%d", pixelFormat_.blueBits); + } + if (pixelFormat_.alphaBits != -1) { + frameBufferAttribs.push_back(EGL_ALPHA_SIZE); + frameBufferAttribs.push_back(pixelFormat_.alphaBits); + HiLog("EGL_ALPHA_SIZE:%d", pixelFormat_.alphaBits); + } + if (pixelFormat_.depthBits != -1) { + frameBufferAttribs.push_back(EGL_DEPTH_SIZE); + frameBufferAttribs.push_back(pixelFormat_.depthBits); + HiLog("EGL_DEPTH_SIZE:%d", pixelFormat_.depthBits); + } + if (pixelFormat_.stencilBits != -1) { + frameBufferAttribs.push_back(EGL_STENCIL_SIZE); + frameBufferAttribs.push_back(pixelFormat_.stencilBits); + HiLog("EGL_STENCIL_SIZE:%d", pixelFormat_.stencilBits); + } + if (pixelFormat_.numSamples != -1) { + frameBufferAttribs.push_back(EGL_SAMPLES); + frameBufferAttribs.push_back(pixelFormat_.numSamples); + HiLog("EGL_SAMPLES:%d", pixelFormat_.numSamples); + } + frameBufferAttribs.push_back(EGL_RENDERABLE_TYPE); + switch (static_cast(glesVersion_) / 10) { + case 3: + HiLog("GLES3.0"); + frameBufferAttribs.push_back(EGL_OPENGL_ES3_BIT); + break; + case 2: + HiLog("GLES2.0 ok"); + frameBufferAttribs.push_back(EGL_OPENGL_ES2_BIT); + break; + default: + HiLog("GLES1.0"); + frameBufferAttribs.push_back(EGL_OPENGL_ES_BIT); + } + frameBufferAttribs.push_back(EGL_NONE); + + unsigned int ret; + EGLint count; + ret = eglChooseConfig(eglDisplay_, &frameBufferAttribs[0], &config_, 1, &count); + HiLog("ret=%d,count=%d\n", ret, count); + if (!(ret && static_cast(count) >= 1)) { + HiLog("Failed to eglChooseConfig\n"); + return false; + } + EGLint red, green, blue, alpha, depth, stencil, samples; + eglGetConfigAttrib(eglDisplay_, config_, EGL_RED_SIZE, &red); + eglGetConfigAttrib(eglDisplay_, config_, EGL_GREEN_SIZE, &green); + eglGetConfigAttrib(eglDisplay_, config_, EGL_BLUE_SIZE, &blue); + eglGetConfigAttrib(eglDisplay_, config_, EGL_ALPHA_SIZE, &alpha); + eglGetConfigAttrib(eglDisplay_, config_, EGL_DEPTH_SIZE, &depth); + eglGetConfigAttrib(eglDisplay_, config_, EGL_STENCIL_SIZE, &stencil); + eglGetConfigAttrib(eglDisplay_, config_, EGL_SAMPLES, &samples); + ShowConfig(config_); + if (pixelFormat_.redBits == -1) { + pixelFormat_.redBits = red; + } else if (pixelFormat_.redBits != red) { + HiLog("Failed to eglChooseConfig redBits %d != %d\n", pixelFormat_.redBits, red); + return false; + } + + if (pixelFormat_.greenBits == -1) { + pixelFormat_.greenBits = green; + } else if (pixelFormat_.greenBits != green) { + HiLog("Failed to eglChooseConfig redBits %d != %d\n", pixelFormat_.greenBits, green); + return false; + } + + if (pixelFormat_.blueBits != blue) { + if (pixelFormat_.blueBits != -1) + HiLog("Failed to eglChooseConfig blueBits %d != %d\n", pixelFormat_.blueBits, blue); + pixelFormat_.blueBits = blue; + } + + if (pixelFormat_.alphaBits != alpha) { + if (pixelFormat_.alphaBits != -1) + HiLog("Failed to eglChooseConfig alphaBits %d != %d\n", pixelFormat_.alphaBits, alpha); + pixelFormat_.alphaBits = alpha; + } + + if (pixelFormat_.depthBits != depth) { + if (pixelFormat_.depthBits != -1) + HiLog("Failed to eglChooseConfig depthBits %d != %d\n", pixelFormat_.depthBits, depth); + pixelFormat_.depthBits = depth; + } + + if (pixelFormat_.stencilBits != stencil) { + if (pixelFormat_.stencilBits != -1) + HiLog("Failed to eglChooseConfig stencilBits %d != %d\n", pixelFormat_.stencilBits, stencil); + pixelFormat_.stencilBits = stencil; + } + + if (pixelFormat_.numSamples != samples) { + if (pixelFormat_.numSamples != -1) + HiLog("Failed to eglChooseConfig numSamples %d != %d\n", pixelFormat_.numSamples, samples); + pixelFormat_.numSamples = samples; + } + HiLog("config ok\n"); + return true; + } + bool AppContext::InitNativeWindow() { + HiLog("InitNativeWindow"); + return true; + } + bool AppContext::InitEglSurface() { + if (eglSurface_ != EGL_NO_SURFACE) { + eglDestroySurface(eglDisplay_, eglSurface_); + eglSurface_ = EGL_NO_SURFACE; + } + + eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + std::vector surfaceAttribs; + + switch (surfaceType_) { + case RCI_SURFACE_TYPE::NONE: + break; + case RCI_SURFACE_TYPE::WINDOW: + surfaceAttribs.push_back(EGL_NONE); + + eglSurface_ = eglCreateWindowSurface(eglDisplay_, config_, nativeWindow_, &surfaceAttribs[0]); + if (eglSurface_ == EGL_NO_SURFACE) { + printf("Failed to create eglsurface!!! %x\n", eglGetError()); + return false; + } + break; + case RCI_SURFACE_TYPE::PBUFFER: + case RCI_SURFACE_TYPE::PIXMAP: + surfaceAttribs.push_back(EGL_WIDTH); + surfaceAttribs.push_back(width_); + surfaceAttribs.push_back(EGL_HEIGHT); + surfaceAttribs.push_back(height_); + surfaceAttribs.push_back(EGL_NONE); + break; + } + printf("egl surface ok\n"); + return true; + } + bool AppContext::InitEglContext() { + if (eglContext_ != EGL_NO_CONTEXT) { + eglDestroyContext(eglDisplay_, eglContext_); + eglContext_ = EGL_NO_CONTEXT; + } + + std::vector contextAttribs; + contextAttribs.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); + contextAttribs.push_back(static_cast(glesVersion_) / 10); + contextAttribs.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); + contextAttribs.push_back(static_cast(glesVersion_) % 10); + + switch (typeProfile_) { + case RCI_PROFILE::ES: + break; + case RCI_PROFILE::CORE: + contextAttribs.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); + contextAttribs.push_back(EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR); + break; + case RCI_PROFILE::COMPATIBILITY: + contextAttribs.push_back(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); + contextAttribs.push_back(EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR); + break; + } + + EGLint flags = 0; + if ((static_cast(contextFlags_) & static_cast(RCI_CONTEXT_FLAG::DEBUG)) != 0) + flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; + + if ((static_cast(contextFlags_) & static_cast(RCI_CONTEXT_FLAG::ROBUST)) != 0) + flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + + if ((static_cast(contextFlags_) & static_cast(RCI_CONTEXT_FLAG::FORWARD_COMPATIBLE)) != 0) + flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; + + contextAttribs.push_back(EGL_CONTEXT_FLAGS_KHR); + contextAttribs.push_back(flags); + + contextAttribs.push_back(EGL_NONE); + + eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, &contextAttribs[0]); + if (eglContext_ == EGL_NO_CONTEXT) { + printf("Failed to create egl context %x\n", eglGetError()); + return false; + } + printf("context ok\n"); + return true; + } + void AppContext::MakeCurrent() { + HiLog("MakeCurrent"); + if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_)) { + HiLog("eglMakeCurrent FAIL\n"); + } + } + void AppContext::SwapBuffer() { + HiLog("SwapBuffer"); + eglSwapBuffers(eglDisplay_, eglSurface_); + } + int32_t AppContext::GetAttrib(int32_t attrType) { + int32_t ret; + eglGetConfigAttrib(eglDisplay_, config_, attrType, &ret); + HiLog("attrType:%d,value:%d\n", attrType, ret); + return ret; + } + uint64_t AppContext::CreateWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { + HiLog("x:%d,y:%d,width:%d,height:%d\n", x, y, width, height); + return 0; + } + void *AppContext::GetNativeWindow(uint64_t windowId) { + HiLog("windowId:%lu\n", windowId); + return nullptr; + } + void AppContext::DestoryWindow(uint64_t windowId) { HiLog("windowId:%lu\n", windowId); } +} // namespace OHOS diff --git a/ohos/happroject/entry/src/main/cpp/render/app_context.h b/ohos/happroject/entry/src/main/cpp/render/app_context.h new file mode 100755 index 0000000000..e4bf153742 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/render/app_context.h @@ -0,0 +1,51 @@ +#ifndef CRDP_APP_CONTEXT_H +#define CRDP_APP_CONTEXT_H +#include "ohos_context_i.h" +#include +#include +#include + +namespace OHOS { + class AppContext : public OHOS::OhosContextI { + public: + AppContext() {} + bool InitEgl(); + void HiLog(const char *format, ...) override; + bool SetConfig(int32_t w, int32_t h, RCI_GLES_VERSION ver, RCI_PIXEL_FORMAT pf, RCI_SURFACE_TYPE st, + RCI_PROFILE tp, RCI_CONTEXT_FLAG flags) override; + bool InitNativeWindow() override; + bool InitEglSurface() override; + bool InitEglContext() override; + + void MakeCurrent() override; + void SwapBuffer() override; + + int32_t GetAttrib(int32_t attrType) override; + + uint64_t CreateWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; + void *GetNativeWindow(uint64_t windowId) override; + void DestoryWindow(uint64_t windowId) override; + + EGLDisplay eglDisplay_; + EGLSurface eglSurface_ = EGL_NO_SURFACE; + EGLContext eglContext_ = EGL_NO_CONTEXT; + EGLNativeWindowType nativeWindow_ = 0; + + private: + void ShowConfig(EGLConfig cfg); + EGLConfig *allConfigs_; + EGLint configCount_; + EGLConfig config_; + + RCI_GLES_VERSION glesVersion_; + RCI_PROFILE typeProfile_; + RCI_CONTEXT_FLAG contextFlags_; + RCI_SURFACE_TYPE surfaceType_; + int32_t width_; + int32_t height_; + RCI_PIXEL_FORMAT pixelFormat_; + bool eglInited_ = false; + }; +} // namespace OHOS + +#endif // CRDP_APP_CONTEXT_H diff --git a/ohos/happroject/entry/src/main/cpp/render/egl_core.cpp b/ohos/happroject/entry/src/main/cpp/render/egl_core.cpp new file mode 100755 index 0000000000..24b348cd19 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/render/egl_core.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "plugin_common.h" +#include "plugin_render.h" +#include +#include +#include + +EGLConfig getConfig(int version, EGLDisplay eglDisplay) { + int attribList[] = {EGL_SURFACE_TYPE, + EGL_WINDOW_BIT, + EGL_RED_SIZE, + 8, + EGL_GREEN_SIZE, + 8, + EGL_BLUE_SIZE, + 8, + EGL_ALPHA_SIZE, + 8, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_NONE}; + EGLConfig configs = NULL; + int configsNum; + if (!eglChooseConfig(eglDisplay, attribList, &configs, 1, &configsNum)) { + LOGE("eglChooseConfig ERROR"); + return NULL; + } + return configs; +} + +void EGLCore::SetXSize(int w, int h) { + LOGD("EGLCore::SetXSize w = %{public}d, h = %{public}d.", w, h); + width_ = w; + height_ = h; +} +void EGLCore::GLContextInit(void *window, int w, int h) { + static uint32_t createcount = 0; + createcount++; + LOGD("EGLCore::GLContextInit %{public}d, w = %{public}d, h = %{public}d", createcount, w, h); + width_ = w; + height_ = h; + + mEglWindow = reinterpret_cast(window); + appContext.nativeWindow_ = mEglWindow; + bInited = true; +} + +std::string EGLCore::StartTest(const std::string &filesDir, const std::string &caseName) { + LOGE("do connect !!!"); + testDir = filesDir; + testCase = caseName; + + std::string result = DoTest(); + + return result; +} + +void EGLCore::OnKeyEvent(uint32_t keyCode, uint32_t updown) {} +void EGLCore::OnTouch(int id, int x, int y, int type) {} + +void EGLCore::OnWindowCommand(uint16_t command) {} +void *stdout_to_hilog(void *arg) { + int *pipefd = (int *)arg; + FILE *pipe_read = fdopen(pipefd[0], "r"); + if (!pipe_read) { + perror("fdopen"); + return NULL; + } + + char line[1024]; + while (true) { + if (fgets(line, sizeof(line), pipe_read) != NULL) { + LOGE(" - %{public}s", line); + } else { + LOGE("stdout_to_hilog exit"); + break; + } + } + + fclose(pipe_read); + return nullptr; +} + +void* test_thread(void *arg) { + EGLCore *pec = (EGLCore *)arg; + pec->DoTest(); +} + +void EGLCore::UpdateScreen() { + if (doTest) { + doTest = false; + DoTest(); + } +} diff --git a/ohos/happroject/entry/src/main/cpp/render/egl_core.h b/ohos/happroject/entry/src/main/cpp/render/egl_core.h new file mode 100755 index 0000000000..f096f21220 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/render/egl_core.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _GL_CORE_ +#define _GL_CORE_ + +#include +#include +#include +#include "plugin_common.h" +#include +#include "app_context.h" +#include "ohos_context_i.h" +#include +#include +#include +#include +#include +void *stdout_to_hilog(void *arg); +void *test_thread(void *arg); +class EGLCore { +public: + EGLCore(std::string &id) : id_(id) { + OHOS::OhosContextI::SetInstance(&appContext); + LOGE("vkglcts4oh set app context instance finish"); + if (pipe(pipefd_stdout) == -1) { + LOGE("create pipe failed"); + return; + } else { + dup2(pipefd_stdout[1], STDOUT_FILENO); + close(pipefd_stdout[1]); + } + if (pipe(pipefd_stderr) == -1) { + LOGE("create pipe failed"); + return; + } else { + dup2(pipefd_stderr[1], STDERR_FILENO); + close(pipefd_stderr[1]); + } + pthread_t tid; + pthread_create(&tid, NULL, stdout_to_hilog, pipefd_stdout); + pthread_create(&tid, NULL, stdout_to_hilog, pipefd_stderr); + LOGE("pipefd_stdout ok"); + } + std::string DoTest() { + LOGE("start do test"); + std::string logFile = "--deqp-log-filename=" + testDir + "/TestResults.qpa"; + std::string glCase = "-n=" + testCase; + std::string archiveDir = "--deqp-archive-dir=" + testDir; + char *argv_[10]; + int p = 0; + argv_[p++] = strdup("./glcts_app_mock"); + argv_[p++] = strdup(logFile.c_str()); + argv_[p++] = strdup(glCase.c_str()); + argv_[p++] = strdup(archiveDir.c_str()); + argv_[p] = NULL; + + TestRunStatus_t ret = runTest(p, argv_); + LOGE("Test run totals:"); + LOGE(" passed: %{public}d/%{public}d", ret.numPassed, ret.numExecuted); + LOGE(" failed: %{public}d/%{public}d", ret.numFailed, ret.numExecuted); + LOGE(" not support: %{public}d/%{public}d", ret.numNotSupported, ret.numExecuted); + LOGE(" warning: %{public}d/%{public}d", ret.numWarnings, ret.numExecuted); + LOGE("end do test"); + char buffer[1024]; + std::snprintf(buffer, sizeof(buffer), "Test run totals:\n" + " passed: %d/%d\n" + " failed: %d/%d\n" + " not support: %d/%d\n" + " warning: %d/%d\n" + "end do test\n", + ret.numPassed, ret.numExecuted, ret.numFailed, ret.numExecuted, + ret.numNotSupported, ret.numExecuted, ret.numWarnings, ret.numExecuted); + return std::string(buffer); + } + ~EGLCore() { + LOGE("!!! EGLCore deinit"); + if (mEGLDisplay != EGL_NO_DISPLAY) { + if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) { + LOGE("EGLCore::eglMakeCurrent error = %{public}d", eglGetError()); + return; + } + eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (mEGLSurface != EGL_NO_SURFACE) { + eglDestroySurface(mEGLDisplay, mEGLSurface); + mEGLSurface = EGL_NO_SURFACE; + } + if (mEGLContext != EGL_NO_CONTEXT) { + eglDestroyContext(mEGLDisplay, mEGLContext); + mEGLContext = EGL_NO_CONTEXT; + } + } + } + void GLContextInit(void *window, int w, int h); + std::string StartTest(const std::string &filesDir, const std::string &caseName); + void UpdateScreen(); + void OnKeyEvent(uint32_t keyCode, uint32_t updown); + void OnTouch(int id, int x, int y, int type); + void OnWindowCommand(uint16_t command); + void SetXSize(int w, int h); + +public: + std::string id_; + int width_; + int height_; + +private: + EGLNativeWindowType mEglWindow; + EGLDisplay mEGLDisplay = EGL_NO_DISPLAY; + EGLConfig mEGLConfig = nullptr; + EGLContext mEGLContext = EGL_NO_CONTEXT; + EGLContext mSharedEGLContext = EGL_NO_CONTEXT; + EGLSurface mEGLSurface = EGL_NO_SURFACE; + + bool bInited = false; + + OHOS::AppContext appContext; + bool doTest = false; + int pipefd_stdout[2]; + int pipefd_stderr[2]; + std::string testDir; + std::string testCase; +}; + +#endif // _GL_CORE_ diff --git a/ohos/happroject/entry/src/main/cpp/render/ohos_context_i.h b/ohos/happroject/entry/src/main/cpp/render/ohos_context_i.h new file mode 100755 index 0000000000..5eff7c3654 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/render/ohos_context_i.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ROSEN_CONTEXT_H_ +#define _ROSEN_CONTEXT_H_ + +#include + +namespace OHOS { + + enum class RCI_GLES_VERSION { V20 = 20, V30 = 30, V31 = 31, V32 = 32 }; + + enum class RCI_PROFILE { ES = 0, CORE, COMPATIBILITY }; + + enum class RCI_CONTEXT_FLAG { + NONE = 0, + ROBUST =(1<<0) , //!< Robust context + DEBUG =(1<<1 ), //!!< Debug context + FORWARD_COMPATIBLE =(1<<2) , //!< Forward-compatible context + }; + + enum class RCI_SURFACE_TYPE { NONE = 0, WINDOW, PIXMAP, PBUFFER }; + + struct RCI_PIXEL_FORMAT { + int32_t redBits; + int32_t greenBits; + int32_t blueBits; + int32_t alphaBits; + int32_t depthBits; + int32_t stencilBits; + int32_t numSamples; + }; + + class OhosContextI { + public: + virtual void HiLog(const char *format, ...) = 0; + static void SetInstance(void *instance); + static OhosContextI &GetInstance(); + + virtual bool SetConfig(int32_t w, int32_t h, RCI_GLES_VERSION ver, RCI_PIXEL_FORMAT pf, RCI_SURFACE_TYPE st, + RCI_PROFILE tp, RCI_CONTEXT_FLAG flags) = 0; + virtual bool InitNativeWindow() = 0; + virtual bool InitEglSurface() = 0; + virtual bool InitEglContext() = 0; + + virtual void MakeCurrent() = 0; + virtual void SwapBuffer() = 0; + + virtual int32_t GetAttrib(int32_t attrType) = 0; + + virtual uint64_t CreateWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; + virtual void *GetNativeWindow(uint64_t windowId) = 0; + virtual void DestoryWindow(uint64_t windowId) = 0; + + private: + }; + +} // namespace OHOS + +typedef struct TestRunStatus +{ + int numExecuted; //!< Total number of cases executed. + int numPassed; //!< Number of cases passed. + int numFailed; //!< Number of cases failed. + int numNotSupported; //!< Number of cases not supported. + int numWarnings; //!< Number of QualityWarning / CompatibilityWarning results. + int numWaived; //!< Number of waived tests. + bool isComplete; //!< Is run complete. +} TestRunStatus_t; + +TestRunStatus_t runTest(int argc, char **argv); +#endif \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/render/plugin_render.cpp b/ohos/happroject/entry/src/main/cpp/render/plugin_render.cpp new file mode 100755 index 0000000000..07af331ee3 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/render/plugin_render.cpp @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +//#include +#include + +#include "plugin_render.h" +#include "plugin_common.h" +#include "plugin_manager.h" + +#include +#include +#include +#include + +#include "hilog/log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +std::unordered_map PluginRender::instance_; + +OH_NativeXComponent_Callback PluginRender::callback_; + +void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) { + LOGD("OnSurfaceCreatedCB"); + int32_t ret; + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); + if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + return; + } + + std::string id(idStr); + auto render = PluginRender::GetInstance(id); + render->OnSurfaceCreated(component, window); +} + +void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) { + int32_t ret; + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); + if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + return; + } + + std::string id(idStr); + auto render = PluginRender::GetInstance(id); + render->OnSurfaceChanged(component, window); +} + +void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) { + int32_t ret; + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); + if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + return; + } + + std::string id(idStr); + auto render = PluginRender::GetInstance(id); + render->OnSurfaceDestroyed(component, window); +} + +void DispatchTouchEventCB(OH_NativeXComponent *component, void *window) { + int32_t ret; + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); + if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + return; + } + + std::string id(idStr); + auto render = PluginRender::GetInstance(id); + render->DispatchTouchEvent(component, window); +} + +PluginRender::PluginRender(std::string &id) : id_(id), component_(nullptr) { + LOGE("~~~PluginRender init"); + eglCore_ = new EGLCore(id); + auto renderCallback = PluginRender::GetNXComponentCallback(); + renderCallback->OnSurfaceCreated = OnSurfaceCreatedCB; + renderCallback->OnSurfaceChanged = OnSurfaceChangedCB; + renderCallback->OnSurfaceDestroyed = OnSurfaceDestroyedCB; + renderCallback->DispatchTouchEvent = DispatchTouchEventCB; +} + +PluginRender *PluginRender::GetInstance(std::string &id, bool weak) { + if (instance_.find(id) == instance_.end()) { + if (weak) { + return nullptr; + } + PluginRender *instance = new PluginRender(id); + instance_[id] = instance; + return instance; + } else { + return instance_[id]; + } +} + +void PluginRender::RemoveInstance(std::string &id) { + if (instance_.find(id) == instance_.end()) { + return; + } + delete instance_[id]; + instance_.erase(id); +} + +OH_NativeXComponent_Callback *PluginRender::GetNXComponentCallback() { return &PluginRender::callback_; } + +PluginRender *ExpandRender(OH_NativeXComponent *component) { + int32_t ret; + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize); + if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + return nullptr; + } + + std::string id(idStr); + return PluginRender::GetInstance(id); +} + +void OnMouseEventCB(OH_NativeXComponent *component, void *window) { + auto render = ExpandRender(component); + render->OnMouseEvent(component, window); +} + +void OnMouseHoverCB(OH_NativeXComponent *component, bool isHover) { + auto render = ExpandRender(component); + render->OnMouseHover(component, isHover); +} + +static OH_NativeXComponent_MouseEvent_Callback g_mouseCallback = { + .DispatchMouseEvent = OnMouseEventCB, + .DispatchHoverEvent = OnMouseHoverCB, +}; + +void PluginRender::SetNativeXComponent(OH_NativeXComponent *component) { + component_ = component; + OH_NativeXComponent_RegisterCallback(component_, &PluginRender::callback_); + OH_NativeXComponent_RegisterMouseEventCallback(component_, &g_mouseCallback); +} + +void PluginRender::OnSurfaceCreated(OH_NativeXComponent *component, void *window) { + LOGD("PluginRender::OnSurfaceCreated"); + int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_); + if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + eglCore_->GLContextInit(window, width_, height_); + } +} + +void PluginRender::OnSurfaceChanged(OH_NativeXComponent *component, void *window) { + LOGE("PluginRender::OnSurfaceChanged"); + int32_t ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_); + if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + eglCore_->SetXSize(width_, height_); + } +} + +void PluginRender::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) { + LOGE("PluginRender::OnSurfaceDestroyed"); + delete eglCore_; + eglCore_ = nullptr; +} + +void PluginRender::OnMouseEvent(OH_NativeXComponent *component, void *window) { + OH_NativeXComponent_MouseEvent mouseEvent; + int32_t ret = OH_NativeXComponent_GetMouseEvent(component, window, &mouseEvent); + if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + int btn = mouseEvent.button; + if (btn == 1) + btn = 0; + else if (btn == 2) + btn = 2; // right + else if (btn == 4) + btn = 1; // mid + int type = mouseEvent.action; + if (type == 1) + type = 0; + else if (type == 2) + type = 1; + else if (type == 3) + type = 2; + if (mouseEvent.action == 0) { + return; + } + eglCore_->OnTouch(btn, mouseEvent.screenX, mouseEvent.screenY, type); + } +} +void PluginRender::OnMouseHover(OH_NativeXComponent *component, bool isHover) {} + +void PluginRender::DispatchTouchEvent(OH_NativeXComponent *component, void *window) { + int32_t ret = OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_); + + if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + + } else { + LOGE("Touch fail"); + } +} + +napi_value PluginRender::Export(napi_env env, napi_value exports) { + LOGE("PluginRender::Export"); + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("testNapiThreadsafefunc", PluginRender::NapiThreadsafeFunc), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; +} + +class RawFile { +public: + void Init(NativeResourceManager *mgr) { mgr_ = mgr; } + + void ReadFile(std::string path, uint8_t *out) { + RawFile *file = OH_ResourceManager_OpenRawFile(mgr_, path.c_str()); + size_t len = OH_ResourceManager_GetRawFileSize(file); + int res = OH_ResourceManager_ReadRawFile(file, out, len); + OH_ResourceManager_CloseRawFile(file); + } + void EnumFiles(std::string path, std::function callback) { + RawDir *dir = OH_ResourceManager_OpenRawDir(mgr_, path.c_str()); + int count = OH_ResourceManager_GetRawFileCount(dir); + if (count == 0) { + RawFile *file = OH_ResourceManager_OpenRawFile(mgr_, path.c_str()); + size_t len = OH_ResourceManager_GetRawFileSize(file); + OH_ResourceManager_CloseRawFile(file); + callback(path, len); + } else { + for (int i = 0; i < count; i++) { + std::string filename = OH_ResourceManager_GetRawFileName(dir, i); + if (path.length() > 0) { + EnumFiles(path + "/" + filename, callback); + } else { + EnumFiles(filename, callback); + } + } + } + OH_ResourceManager_CloseRawDir(dir); + } + +private: + NativeResourceManager *mgr_ = nullptr; +}; + +static RawFile ccrf; + +int mkdir_p(const char *path, mode_t mode) { + char tmp[PATH_MAX]; + char *p = NULL; + struct stat sb; + size_t len; + + len = strnlen(path, PATH_MAX); + if (len == 0 || len == PATH_MAX) { + return -1; + } + memcpy(tmp, path, len); + tmp[len] = '\0'; + + if (tmp[len - 1] == '/') { + tmp[len - 1] = '\0'; + } + + if (stat(tmp, &sb) == 0) { + if (S_ISDIR(sb.st_mode)) { + return 0; + } + return -1; + } + + for (p = tmp + 1; *p; p++) { + if (*p == '/') { + *p = '\0'; + if (stat(tmp, &sb) != 0) { + if (mkdir(tmp, mode) != 0) { + LOGE("mkdir '%{public}s' failed", tmp); + return -1; + } + } else if (!S_ISDIR(sb.st_mode)) { + return -1; + } + *p = '/'; + } + } + + if (mkdir(tmp, mode) != 0) { + LOGE("mkdir '%{public}s' failed", tmp); + return -1; + } + return 0; +} + +bool is_synced(std::string dir, bool isset = false) { + char files_synced[PATH_MAX]; + sprintf(files_synced, "%s/synced.txt", dir.c_str()); + if (isset) { + FILE *fp = fopen(files_synced, "w"); + fclose(fp); + return true; + } + + struct stat s; + if (stat(files_synced, &s) == 0) { + LOGE("'%{public}s' is exist\n", files_synced); + return true; + } else { + LOGE("'%{public}s' not exist\n", files_synced); + return false; + } +} + +napi_threadsafe_function g_threadsafeFunction; + +typedef struct { + napi_threadsafe_function tsfn; + pthread_t thread_id; + char filesDir[PARAM1024]; + char caseName[PARAM1024]; + NativeResourceManager *mNativeResMgr; + PluginRender *instance; + std::string result; +} ThreadContext; + +static void CallbackFunction(napi_env env, napi_value jsCallback, void *context, void *data) +{ + size_t argc = 1; + napi_value argv[1]; + ThreadContext *ctx = static_cast(data); + napi_create_string_utf8(env, ctx->result.c_str(), NAPI_AUTO_LENGTH, &argv[0]); + napi_call_function(env, nullptr, jsCallback, argc, argv, nullptr); +} + +static void* ThreadFunction(void *data) +{ + ThreadContext* ctx = (ThreadContext*)data; + sleep(2); + + LOGI("param %{public}s", ctx->filesDir); + if (ctx->instance) { + if (!is_synced(ctx->filesDir)) { + ccrf.Init(ctx->mNativeResMgr); + + ccrf.EnumFiles("", [=](std::string filename, size_t len) { + int p = filename.length() - 1; + for (; p > 0; p--) { + if (filename.c_str()[p] == '/') { + break; + } + } + std::string path = filename.substr(0, p); + std::string name = filename.substr(p + 1); + LOGI("RawFile [%{public}s][%{public}s] size = %{public}ld", path.c_str(), name.c_str(), len); + + char dst[1024]; + sprintf(dst, "%s/%s", ctx->filesDir, path.c_str()); + if (path.length() > 0) { + struct stat s; + if (stat(dst, &s) != 0) { + if(mkdir_p(dst, 0755)!=0){ + exit(0); + } + } + } + sprintf(dst, "%s/%s", ctx->filesDir, filename.c_str()); + uint8_t *data = new uint8_t[len]; + ccrf.ReadFile(filename, data); + FILE *fp = fopen(dst, "wb"); + if (fp) { + fwrite(data, 1, len, fp); + fclose(fp); + } + delete[] data; + }); + is_synced(ctx->filesDir, true); + } + LOGE("file %{public}s, case %{public}s", ctx->filesDir, ctx->caseName); + ctx->result = ctx->instance->eglCore_->StartTest(ctx->filesDir, ctx->caseName); + } + + napi_call_threadsafe_function(ctx->tsfn, ctx, napi_tsfn_nonblocking); + pthread_detach(ctx->thread_id); + return NULL; +} + +napi_value PluginRender::NapiThreadsafeFunc(napi_env env, napi_callback_info info) { + size_t argc = PARAM4; + napi_value argv[PARAM4]; + napi_value thisArg; + napi_status status; + napi_value exportInstance; + size_t result; + const napi_extended_error_info *extended_error_info; + OH_NativeXComponent *nativeXComponent = nullptr; + + int32_t ret = 0; + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + + status = napi_get_cb_info(env, info, &argc, argv, &thisArg, NULL); + if (status != napi_ok) { + napi_throw_error(env, NULL, "Failed to parse arguments"); + return NULL; + } + + status = napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance); + if (status != napi_ok) { + napi_throw_error(env, NULL, "Failed to parse xcomponent object"); + return nullptr; + } + + status = napi_unwrap(env, exportInstance, reinterpret_cast(&nativeXComponent)); + if (status != napi_ok) { + napi_throw_error(env, NULL, "Failed to unwrap xcomponent value"); + return nullptr; + } + + ret = OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize); + if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + napi_throw_error(env, NULL, "Failed to get xcomponent id"); + return nullptr; + } + + std::string id(idStr); + PluginRender *instance = PluginRender::GetInstance(id); + + // 检查参数数量 + if (argc < PARAM4) { + napi_throw_error(env, NULL, "Expected 4 arguments"); + return NULL; + } + pthread_t thread; + ThreadContext *ctx = (ThreadContext *)malloc(sizeof(ThreadContext)); + ctx->instance = instance; + ctx->mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, argv[PARAM0]); + if (ctx->mNativeResMgr == NULL) { + napi_throw_error(env, NULL, "get resource manager failed!"); + return nullptr; + } + + status = napi_get_value_string_utf8(env, argv[PARAM1], ctx->filesDir, PARAM1024, &result); + if (status != napi_ok) { + napi_throw_error(env, NULL, "get file dir failed!"); + return nullptr; + } + + status = napi_get_value_string_utf8(env, argv[PARAM2], ctx->caseName, PARAM1024, &result); + if (status != napi_ok) { + napi_throw_error(env, NULL, "get case name failed!"); + return nullptr; + } + + napi_value name; + napi_create_string_utf8(env, "NapiThreadsafeFunc", NAPI_AUTO_LENGTH, &name); + status = napi_create_threadsafe_function(env, argv[PARAM3], nullptr, name, 0, 1, + nullptr, nullptr, nullptr, CallbackFunction, &ctx->tsfn); + if (status != napi_ok) { + status = napi_get_last_error_info(env, &extended_error_info); + if (status == napi_ok && extended_error_info != NULL) { + const char *errorMessage = extended_error_info->error_message != NULL ? + extended_error_info->error_message : "Unknown error"; + LOGE("errmsg %{public}s!, engine_err_code %{public}d!.", + errorMessage, extended_error_info->engine_error_code); + std::string res = "Failed to create threadsafe function em = " + std::string(errorMessage) + + ", eec = " + std::to_string(extended_error_info->engine_error_code) + + ", ec = " + std::to_string(extended_error_info->error_code); + napi_throw_error(env, NULL, res.c_str()); + return NULL; + } + } + + pthread_create(&ctx->thread_id, nullptr, ThreadFunction, ctx); + + napi_value resultValue; + status = napi_create_int32(env, ret, &resultValue); + if (status != napi_ok) { + napi_throw_error(env, NULL, "Failed to create result value"); + return NULL; + } + + return resultValue; +} + +bool PluginRender::OnVsync() { + std::lock_guard lock(coreMutex_); + if (eglCore_ != nullptr) { + eglCore_->UpdateScreen(); + return true; + } else { + return false; + } +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/cpp/render/plugin_render.h b/ohos/happroject/entry/src/main/cpp/render/plugin_render.h new file mode 100755 index 0000000000..48b168b2d5 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/render/plugin_render.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PLUGIN_RENDER_H_ +#define _PLUGIN_RENDER_H_ + +#include +#include + +#include +#include + +#include "egl_core.h" + + +class PluginRender { +public: + PluginRender(std::string& id); + static PluginRender* GetInstance(std::string& id,bool weak = false); + static void RemoveInstance(std::string& id); + static OH_NativeXComponent_Callback* GetNXComponentCallback(); + + void SetNativeXComponent(OH_NativeXComponent* component); + +public: + // NAPI interface + napi_value Export(napi_env env, napi_value exports); + + // Exposed to JS developers by NAPI + static napi_value NapiThreadsafeFunc(napi_env env, napi_callback_info info); + + // Callback, called by ACE XComponent + void OnSurfaceCreated(OH_NativeXComponent* component, void* window); + void OnSurfaceChanged(OH_NativeXComponent* component, void* window); + void OnSurfaceDestroyed(OH_NativeXComponent* component, void* window); + void DispatchTouchEvent(OH_NativeXComponent* component, void* window); + + void OnMouseEvent(OH_NativeXComponent *component, void *window); + void OnMouseHover(OH_NativeXComponent *component, bool isHover); + bool OnVsync(); +public: + static std::unordered_map instance_; + static OH_NativeXComponent_Callback callback_; + + OH_NativeXComponent* component_; + EGLCore* eglCore_; + + + std::string id_; + uint64_t width_; + uint64_t height_; + + double x_; + double y_; + OH_NativeXComponent_TouchEvent touchEvent_; + + std::mutex coreMutex_; +}; + +#endif // _PLUGIN_RENDER_H_ diff --git a/ohos/happroject/entry/src/main/cpp/types/libentry/index.d.ts b/ohos/happroject/entry/src/main/cpp/types/libentry/index.d.ts new file mode 100755 index 0000000000..a39f3d4250 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/types/libentry/index.d.ts @@ -0,0 +1,11 @@ +import { Callback } from "@ohos.base"; +import resourceManager from '@ohos.resourceManager'; + +export interface Callback { + (data: T): void; +} + +export interface CRdpInterface { + testNapiThreadsafefunc(resmgr: resourceManager.ResourceManager, + filesDir:string, testCase: string, callback: Callback): number; +} diff --git a/ohos/happroject/entry/src/main/cpp/types/libentry/oh-package.json5 b/ohos/happroject/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100755 index 0000000000..8c49cae229 --- /dev/null +++ b/ohos/happroject/entry/src/main/cpp/types/libentry/oh-package.json5 @@ -0,0 +1,6 @@ +{ + "name": "libentry.so", + "types": "./index.d.ts", + "version": "", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/happroject/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100755 index 0000000000..d7eefae15f --- /dev/null +++ b/ohos/happroject/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,48 @@ +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import hilog from '@ohos.hilog'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; +import resourceManager from '@ohos.resourceManager'; + +export default class EntryAbility extends UIAbility { + public static resmgr : resourceManager.ResourceManager; + public static filesDir : string; + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + console.log('vkglcts4oh on destory'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/MainWindow', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + hilog.info(0x0000, 'vkglcts4oh' ,this.context.filesDir); + hilog.info(0x0000, 'vkglcts4oh' ,this.context.resourceDir); + EntryAbility.resmgr = this.context.resourceManager; + EntryAbility.filesDir = this.context.filesDir; + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + console.log("vkglcts4oh onForeground"); + } + + onBackground(): void { + console.log("vkglcts4oh onBackground"); + } +}; diff --git a/ohos/happroject/entry/src/main/ets/pages/LogUtil.ets b/ohos/happroject/entry/src/main/ets/pages/LogUtil.ets new file mode 100755 index 0000000000..590b5a2d53 --- /dev/null +++ b/ohos/happroject/entry/src/main/ets/pages/LogUtil.ets @@ -0,0 +1,26 @@ +import hilog from '@ohos.hilog'; + +export class LogUtil { + public static readonly DOMAIN: number = 0xFF00; + public static readonly TAG: string = "vkglcts"; + + public static debug(message: string, ...args: Object[]) { + hilog.debug(LogUtil.DOMAIN, LogUtil.TAG, message, args) + } + + public static info(message: string, ...args: Object[]) { + hilog.info(LogUtil.DOMAIN, LogUtil.TAG, message, args) + } + + public static log(message: string, ...args: Object[]) { + hilog.debug(LogUtil.DOMAIN, LogUtil.TAG, message, args) + } + + public static warn(message: string, ...args: Object[]) { + hilog.warn(LogUtil.DOMAIN, LogUtil.TAG, message, args) + } + + public static error(message: string, ...args: Object[]) { + hilog.error(LogUtil.DOMAIN, LogUtil.TAG, message, args) + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/ets/pages/MainWindow.ets b/ohos/happroject/entry/src/main/ets/pages/MainWindow.ets new file mode 100755 index 0000000000..baa9a40208 --- /dev/null +++ b/ohos/happroject/entry/src/main/ets/pages/MainWindow.ets @@ -0,0 +1,126 @@ +import { CRdpInterface } from 'libentry.so' +import { LogUtil } from './LogUtil' +import EntryAbility from '../entryability/EntryAbility'; + +@Extend(Text) +function style(TextAlign: TextAlign) { + .textAlign(TextAlign) + .fontSize(12) + .border({ width: 1 }) + .padding(10) + .width('100%') +} + +@Entry +@Component +struct MainWindow { + private context:CRdpInterface|undefined=undefined; + + @State text: string = "KHR-GLES2.*" + @State index: number = 0 + @State space: number = 8 + @State bEnable: boolean = true; + @State msgText: string = 'Test '; + + aboutToAppear(): void { + } + + build() { + Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) { + Text("OpenHarmony VK-GL-CTS Runner") + .fontSize(16) + .fontWeight(500) + .padding(20) + + XComponent({ id: 'mainWindow', type: 'texture', libraryname: 'entry' }) + .width(512) + .height(512) + .padding(20) + .onLoad((context) => { + this.context = context as CRdpInterface; + if (this.context) { + LogUtil.debug("XComponent loaded"); + } + }) + .onDestroy(() => { + }) + .focusable(true) + .backgroundColor(Color.Transparent) + + Select([{ value: this.text }, + { value: 'KHR-GLES3.*' }, + { value: 'KHR-GLES31.*' }, + { value: 'KHR-GLES32.*' }, + { value: 'KHR-GLESEXT.*' }, + { value: 'KHR-NoContext.*' }, + { value: 'dEQP-GLES2.*'}, + { value: 'dEQP-GLES3.*'}, + { value: 'dEQP-GLES31.*'}]) + .width('80%') + .selected(this.index) + .value(this.text) + .font({ size: 16, weight: 500 }) + .fontColor('#182431') + .selectedOptionFont({ size: 16, weight: 400 }) + .optionFont({ size: 16, weight: 400 }) + .space(this.space) + .onSelect((index:number, text?: string | undefined)=>{ + LogUtil.debug('Select Option: ' + index) + this.index = index; + if(text){ + this.text = text; + } + }) + + Button("start runner") + .enabled(this.bEnable) + .height(50) + .width('80%') + .fontSize(16) + .fontWeight(500) + .onClick(()=>{ + if (this.context) { + this.bEnable = false; + this.msgText = 'Test ' + this.text + " running: \n"; + let startTime = new Date(); + this.context.testNapiThreadsafefunc(EntryAbility.resmgr, EntryAbility.filesDir, this.text, + (data:string) => { + let endTime = new Date(); + const diffMs = Math.abs(endTime.getTime() - startTime.getTime()); + + const days = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + const hours = Math.floor(diffMs / (1000 * 60 * 60)); + const minutes = Math.floor(diffMs / (1000 * 60)); + const seconds = Math.floor(diffMs / 1000); + const diffHours = hours - days * 24; + const diffMinutes = minutes - hours * 60; + const diffSeconds = seconds - minutes * 60; + + LogUtil.debug("execute runner hours: D-" + days + " H-" + hours + + " M-" + minutes + " S-" + seconds + data); + + LogUtil.debug("execute runner diffHours: D-" + days + " H-" + diffHours + + " M-" + diffMinutes + " S-" + diffSeconds + data); + + this.msgText += "starttime: " + startTime.toLocaleString() + "\n" + + "endtime: " + endTime.toLocaleString() + "\n" + + "cost: " + days + "D-" + diffHours + + "H-" + diffMinutes + "M-" + diffSeconds + "S\n"; + this.msgText += data; + this.bEnable = true; + }); + } + }) + + Text(this.msgText) + .style(TextAlign.Start) + .margin(20) + .fontSize(16) + .fontWeight(500) + } + .backgroundColor(Color.Transparent) + .width('100%') + .height('100%') + .focusable(true) + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/module.json5 b/ohos/happroject/entry/src/main/module.json5 new file mode 100755 index 0000000000..0f1f48c744 --- /dev/null +++ b/ohos/happroject/entry/src/main/module.json5 @@ -0,0 +1,60 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, +// "launchType": "multiton", + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + { + "name": "ohos.permission.INTERNET", + "reason": "$string:internet_permission", + "usedScene": { + "abilities": [ + "ohos.samples.websocket.MainAbility" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.WRITE_USER_STORAGE", + "reason": "$string:internet_permission", + "usedScene": { + "abilities": [ + "ohos.samples.websocket.MainAbility" + ], + "when": "always" + } + } + ] + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/resources/base/element/color.json b/ohos/happroject/entry/src/main/resources/base/element/color.json new file mode 100755 index 0000000000..6c3a825a95 --- /dev/null +++ b/ohos/happroject/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#00FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/resources/base/element/string.json b/ohos/happroject/entry/src/main/resources/base/element/string.json new file mode 100755 index 0000000000..948009d1f3 --- /dev/null +++ b/ohos/happroject/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "terminal" + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/resources/base/media/icon.png b/ohos/happroject/entry/src/main/resources/base/media/icon.png new file mode 100755 index 0000000000..cd45accb1d Binary files /dev/null and b/ohos/happroject/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/happroject/entry/src/main/resources/base/media/startIcon.png b/ohos/happroject/entry/src/main/resources/base/media/startIcon.png new file mode 100755 index 0000000000..c3643d7741 Binary files /dev/null and b/ohos/happroject/entry/src/main/resources/base/media/startIcon.png differ diff --git a/ohos/happroject/entry/src/main/resources/base/profile/main_pages.json b/ohos/happroject/entry/src/main/resources/base/profile/main_pages.json new file mode 100755 index 0000000000..c4e6bcc3e3 --- /dev/null +++ b/ohos/happroject/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/MainWindow" + ] +} diff --git a/ohos/happroject/entry/src/main/resources/en_US/element/string.json b/ohos/happroject/entry/src/main/resources/en_US/element/string.json new file mode 100755 index 0000000000..948009d1f3 --- /dev/null +++ b/ohos/happroject/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "terminal" + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/main/resources/zh_CN/element/string.json b/ohos/happroject/entry/src/main/resources/zh_CN/element/string.json new file mode 100755 index 0000000000..33b70d4058 --- /dev/null +++ b/ohos/happroject/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,20 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "基础测试" + }, + { + "name": "internet_permission", + "value": "vk-gl-cts4oh" + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/happroject/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100755 index 0000000000..8aa3749775 --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/ets/test/List.test.ets b/ohos/happroject/entry/src/ohosTest/ets/test/List.test.ets new file mode 100755 index 0000000000..794c7dc4ed --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/happroject/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100755 index 0000000000..c8278e9721 --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,49 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + +export default class TestAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? ''); + let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator; + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); + let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs; + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments(); + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/happroject/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100755 index 0000000000..423b4276ec --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,17 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/happroject/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100755 index 0000000000..4b573431a7 --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,50 @@ +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import Want from '@ohos.app.ability.Want'; + +let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined +let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err : Error) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + const bundleName = abilityDelegatorArguments.bundleName; + const testAbilityName = 'TestAbility'; + const moduleName = abilityDelegatorArguments.parameters['-m']; + let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + moduleName: moduleName + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + const want: Want = { + bundleName: bundleName, + abilityName: testAbilityName, + moduleName: moduleName + }; + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); + abilityDelegator.startAbility(want, (err, data) => { + hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/module.json5 b/ohos/happroject/entry/src/ohosTest/module.json5 new file mode 100755 index 0000000000..4fc9701701 --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/happroject/entry/src/ohosTest/resources/base/element/color.json b/ohos/happroject/entry/src/ohosTest/resources/base/element/color.json new file mode 100755 index 0000000000..3c712962da --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/resources/base/element/string.json b/ohos/happroject/entry/src/ohosTest/resources/base/element/string.json new file mode 100755 index 0000000000..65d8fa5a7c --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/happroject/entry/src/ohosTest/resources/base/media/icon.png b/ohos/happroject/entry/src/ohosTest/resources/base/media/icon.png new file mode 100755 index 0000000000..cd45accb1d Binary files /dev/null and b/ohos/happroject/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/happroject/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/happroject/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100755 index 0000000000..b7e7343cac --- /dev/null +++ b/ohos/happroject/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/happroject/hvigor/hvigor-config.json5 b/ohos/happroject/hvigor/hvigor-config.json5 new file mode 100755 index 0000000000..5aa89096f0 --- /dev/null +++ b/ohos/happroject/hvigor/hvigor-config.json5 @@ -0,0 +1,6 @@ +{ + "hvigorVersion":"3.2.4", + "dependencies":{ + "@ohos/hvigor-ohos-plugin":"3.2.4" + } +} \ No newline at end of file diff --git a/ohos/happroject/hvigor/hvigor-wrapper.js b/ohos/happroject/hvigor/hvigor-wrapper.js new file mode 100755 index 0000000000..372eae8eb4 --- /dev/null +++ b/ohos/happroject/hvigor/hvigor-wrapper.js @@ -0,0 +1 @@ +"use strict";var u=require("path"),D=require("os"),e=require("fs"),t=require("crypto"),r=require("child_process"),n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},i={},C={},F=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(C,"__esModule",{value:!0}),C.maxPathLength=C.isMac=C.isLinux=C.isWindows=void 0;const E=F(D),A="Windows_NT",o="Darwin";function a(){return E.default.type()===A}function c(){return E.default.type()===o}C.isWindows=a,C.isLinux=function(){return"Linux"===E.default.type()},C.isMac=c,C.maxPathLength=function(){return c()?1016:a()?259:4095},function(e){var t=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),r=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),i=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&t(D,u,e);return r(D,u),D};Object.defineProperty(e,"__esModule",{value:!0}),e.WORK_SPACE=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.PROJECT_CACHES=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const F=i(D),E=i(u),A=C;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,A.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,A.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=E.resolve(F.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=E.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.PROJECT_CACHES="project_caches",e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=E.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=E.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=E.resolve(e.HVIGOR_USER_HOME,e.PROJECT_CACHES),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_WRAPPER_HOME=E.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.WORK_SPACE="workspace"}(i);var s={},l={};Object.defineProperty(l,"__esModule",{value:!0}),l.logInfoPrintConsole=l.logErrorAndExit=void 0,l.logErrorAndExit=function(u){u instanceof Error?console.error(u.message):console.error(u),process.exit(-1)},l.logInfoPrintConsole=function(u){console.log(u)};var B=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),d=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),f=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&B(D,u,e);return d(D,u),D};Object.defineProperty(s,"__esModule",{value:!0});var _=s.executeBuild=void 0;const p=f(e),O=f(u),h=l;_=s.executeBuild=function(u){const D=O.resolve(u,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const u=p.realpathSync(D);require(u)}catch(e){(0,h.logErrorAndExit)(`Error: ENOENT: no such file ${D},delete ${u} and retry.`)}};var P={},v={};!function(u){var D=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(u,"__esModule",{value:!0}),u.hashFile=u.hash=u.createHash=void 0;const r=D(t),i=D(e);u.createHash=(u="MD5")=>r.default.createHash(u);u.hash=(D,e)=>(0,u.createHash)(e).update(D).digest("hex");u.hashFile=(D,e)=>{if(i.default.existsSync(D))return(0,u.hash)(i.default.readFileSync(D,"utf-8"),e)}}(v);var g={},m={},R={};Object.defineProperty(R,"__esModule",{value:!0}),R.Unicode=void 0;class y{}R.Unicode=y,y.SPACE_SEPARATOR=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,y.ID_START=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,y.ID_CONTINUE=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(m,"__esModule",{value:!0}),m.JudgeUtil=void 0;const I=R;m.JudgeUtil=class{static isIgnoreChar(u){return"string"==typeof u&&("\t"===u||"\v"===u||"\f"===u||" "===u||" "===u||"\ufeff"===u||"\n"===u||"\r"===u||"\u2028"===u||"\u2029"===u)}static isSpaceSeparator(u){return"string"==typeof u&&I.Unicode.SPACE_SEPARATOR.test(u)}static isIdStartChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||"$"===u||"_"===u||I.Unicode.ID_START.test(u))}static isIdContinueChar(u){return"string"==typeof u&&(u>="a"&&u<="z"||u>="A"&&u<="Z"||u>="0"&&u<="9"||"$"===u||"_"===u||"‌"===u||"‍"===u||I.Unicode.ID_CONTINUE.test(u))}static isDigitWithoutZero(u){return/[1-9]/.test(u)}static isDigit(u){return"string"==typeof u&&/[0-9]/.test(u)}static isHexDigit(u){return"string"==typeof u&&/[0-9A-Fa-f]/.test(u)}};var N=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(g,"__esModule",{value:!0}),g.parseJsonText=g.parseJsonFile=void 0;const b=N(e),S=N(D),w=N(u),H=m;var x;!function(u){u[u.Char=0]="Char",u[u.EOF=1]="EOF",u[u.Identifier=2]="Identifier"}(x||(x={}));let M,T,V,G,j,J,W="start",U=[],L=0,$=1,k=0,K=!1,z="default",q="'",Z=1;function X(u,D=!1){T=String(u),W="start",U=[],L=0,$=1,k=0,G=void 0,K=D;do{M=Q(),nu[W]()}while("eof"!==M.type);return G}function Q(){for(z="default",j="",q="'",Z=1;;){J=Y();const u=Du[z]();if(u)return u}}function Y(){if(T[L])return String.fromCodePoint(T.codePointAt(L))}function uu(){const u=Y();return"\n"===u?($++,k=0):u?k+=u.length:k++,u&&(L+=u.length),u}g.parseJsonFile=function(u,D=!1,e="utf-8"){const t=b.default.readFileSync(w.default.resolve(u),{encoding:e});try{return X(t,D)}catch(D){if(D instanceof SyntaxError){const e=D.message.split("at");if(2===e.length)throw new Error(`${e[0].trim()}${S.default.EOL}\t at ${u}:${e[1].trim()}`)}throw new Error(`${u} is not in valid JSON/JSON5 format.`)}},g.parseJsonText=X;const Du={default(){switch(J){case"/":return uu(),void(z="comment");case void 0:return uu(),eu("eof")}if(!H.JudgeUtil.isIgnoreChar(J)&&!H.JudgeUtil.isSpaceSeparator(J))return Du[W]();uu()},start(){z="value"},beforePropertyName(){switch(J){case"$":case"_":return j=uu(),void(z="identifierName");case"\\":return uu(),void(z="identifierNameStartEscape");case"}":return eu("punctuator",uu());case'"':case"'":return q=J,uu(),void(z="string")}if(H.JudgeUtil.isIdStartChar(J))return j+=uu(),void(z="identifierName");throw Eu(x.Char,uu())},afterPropertyName(){if(":"===J)return eu("punctuator",uu());throw Eu(x.Char,uu())},beforePropertyValue(){z="value"},afterPropertyValue(){switch(J){case",":case"}":return eu("punctuator",uu())}throw Eu(x.Char,uu())},beforeArrayValue(){if("]"===J)return eu("punctuator",uu());z="value"},afterArrayValue(){switch(J){case",":case"]":return eu("punctuator",uu())}throw Eu(x.Char,uu())},end(){throw Eu(x.Char,uu())},comment(){switch(J){case"*":return uu(),void(z="multiLineComment");case"/":return uu(),void(z="singleLineComment")}throw Eu(x.Char,uu())},multiLineComment(){switch(J){case"*":return uu(),void(z="multiLineCommentAsterisk");case void 0:throw Eu(x.Char,uu())}uu()},multiLineCommentAsterisk(){switch(J){case"*":return void uu();case"/":return uu(),void(z="default");case void 0:throw Eu(x.Char,uu())}uu(),z="multiLineComment"},singleLineComment(){switch(J){case"\n":case"\r":case"\u2028":case"\u2029":return uu(),void(z="default");case void 0:return uu(),eu("eof")}uu()},value(){switch(J){case"{":case"[":return eu("punctuator",uu());case"n":return uu(),tu("ull"),eu("null",null);case"t":return uu(),tu("rue"),eu("boolean",!0);case"f":return uu(),tu("alse"),eu("boolean",!1);case"-":case"+":return"-"===uu()&&(Z=-1),void(z="numerical");case".":case"0":case"I":case"N":return void(z="numerical");case'"':case"'":return q=J,uu(),j="",void(z="string")}if(void 0===J||!H.JudgeUtil.isDigitWithoutZero(J))throw Eu(x.Char,uu());z="numerical"},numerical(){switch(J){case".":return j=uu(),void(z="decimalPointLeading");case"0":return j=uu(),void(z="zero");case"I":return uu(),tu("nfinity"),eu("numeric",Z*(1/0));case"N":return uu(),tu("aN"),eu("numeric",NaN)}if(void 0!==J&&H.JudgeUtil.isDigitWithoutZero(J))return j=uu(),void(z="decimalInteger");throw Eu(x.Char,uu())},zero(){switch(J){case".":case"e":case"E":return void(z="decimal");case"x":case"X":return j+=uu(),void(z="hexadecimal")}return eu("numeric",0)},decimalInteger(){switch(J){case".":case"e":case"E":return void(z="decimal")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimal(){switch(J){case".":j+=uu(),z="decimalFraction";break;case"e":case"E":j+=uu(),z="decimalExponent"}},decimalPointLeading(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalFraction");throw Eu(x.Char,uu())},decimalFraction(){switch(J){case"e":case"E":return j+=uu(),void(z="decimalExponent")}if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},decimalExponent(){switch(J){case"+":case"-":return j+=uu(),void(z="decimalExponentSign")}if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentSign(){if(H.JudgeUtil.isDigit(J))return j+=uu(),void(z="decimalExponentInteger");throw Eu(x.Char,uu())},decimalExponentInteger(){if(!H.JudgeUtil.isDigit(J))return eu("numeric",Z*Number(j));j+=uu()},hexadecimal(){if(H.JudgeUtil.isHexDigit(J))return j+=uu(),void(z="hexadecimalInteger");throw Eu(x.Char,uu())},hexadecimalInteger(){if(!H.JudgeUtil.isHexDigit(J))return eu("numeric",Z*Number(j));j+=uu()},identifierNameStartEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":break;default:if(!H.JudgeUtil.isIdStartChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},identifierName(){switch(J){case"$":case"_":case"‌":case"‍":return void(j+=uu());case"\\":return uu(),void(z="identifierNameEscape")}if(!H.JudgeUtil.isIdContinueChar(J))return eu("identifier",j);j+=uu()},identifierNameEscape(){if("u"!==J)throw Eu(x.Char,uu());uu();const u=ru();switch(u){case"$":case"_":case"‌":case"‍":break;default:if(!H.JudgeUtil.isIdContinueChar(u))throw Eu(x.Identifier)}j+=u,z="identifierName"},string(){switch(J){case"\\":return uu(),void(j+=function(){const u=Y(),D=function(){switch(Y()){case"b":return uu(),"\b";case"f":return uu(),"\f";case"n":return uu(),"\n";case"r":return uu(),"\r";case"t":return uu(),"\t";case"v":return uu(),"\v"}return}();if(D)return D;switch(u){case"0":if(uu(),H.JudgeUtil.isDigit(Y()))throw Eu(x.Char,uu());return"\0";case"x":return uu(),function(){let u="",D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());if(u+=uu(),D=Y(),!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());return u+=uu(),String.fromCodePoint(parseInt(u,16))}();case"u":return uu(),ru();case"\n":case"\u2028":case"\u2029":return uu(),"";case"\r":return uu(),"\n"===Y()&&uu(),""}if(void 0===u||H.JudgeUtil.isDigitWithoutZero(u))throw Eu(x.Char,uu());return uu()}());case'"':case"'":if(J===q){const u=eu("string",j);return uu(),u}return void(j+=uu());case"\n":case"\r":case void 0:throw Eu(x.Char,uu());case"\u2028":case"\u2029":!function(u){console.warn(`JSON5: '${Fu(u)}' in strings is not valid ECMAScript; consider escaping.`)}(J)}j+=uu()}};function eu(u,D){return{type:u,value:D,line:$,column:k}}function tu(u){for(const D of u){if(Y()!==D)throw Eu(x.Char,uu());uu()}}function ru(){let u="",D=4;for(;D-- >0;){const D=Y();if(!H.JudgeUtil.isHexDigit(D))throw Eu(x.Char,uu());u+=uu()}return String.fromCodePoint(parseInt(u,16))}const nu={start(){if("eof"===M.type)throw Eu(x.EOF);iu()},beforePropertyName(){switch(M.type){case"identifier":case"string":return V=M.value,void(W="afterPropertyName");case"punctuator":return void Cu();case"eof":throw Eu(x.EOF)}},afterPropertyName(){if("eof"===M.type)throw Eu(x.EOF);W="beforePropertyValue"},beforePropertyValue(){if("eof"===M.type)throw Eu(x.EOF);iu()},afterPropertyValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforePropertyName");case"}":Cu()}},beforeArrayValue(){if("eof"===M.type)throw Eu(x.EOF);"punctuator"!==M.type||"]"!==M.value?iu():Cu()},afterArrayValue(){if("eof"===M.type)throw Eu(x.EOF);switch(M.value){case",":return void(W="beforeArrayValue");case"]":Cu()}},end(){}};function iu(){const u=function(){let u;switch(M.type){case"punctuator":switch(M.value){case"{":u={};break;case"[":u=[]}break;case"null":case"boolean":case"numeric":case"string":u=M.value}return u}();if(K&&"object"==typeof u&&(u._line=$,u._column=k),void 0===G)G=u;else{const D=U[U.length-1];Array.isArray(D)?K&&"object"!=typeof u?D.push({value:u,_line:$,_column:k}):D.push(u):D[V]=K&&"object"!=typeof u?{value:u,_line:$,_column:k}:u}!function(u){if(u&&"object"==typeof u)U.push(u),W=Array.isArray(u)?"beforeArrayValue":"beforePropertyName";else{const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}}(u)}function Cu(){U.pop();const u=U[U.length-1];W=u?Array.isArray(u)?"afterArrayValue":"afterPropertyValue":"end"}function Fu(u){const D={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(D[u])return D[u];if(u<" "){const D=u.charCodeAt(0).toString(16);return`\\x${`00${D}`.substring(D.length)}`}return u}function Eu(u,D){let e="";switch(u){case x.Char:e=void 0===D?`JSON5: invalid end of input at ${$}:${k}`:`JSON5: invalid character '${Fu(D)}' at ${$}:${k}`;break;case x.EOF:e=`JSON5: invalid end of input at ${$}:${k}`;break;case x.Identifier:k-=5,e=`JSON5: invalid identifier character at ${$}:${k}`}const t=new Au(e);return t.lineNumber=$,t.columnNumber=k,t}class Au extends SyntaxError{}var ou={},au=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),cu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),su=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&au(D,u,e);return cu(D,u),D},lu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(ou,"__esModule",{value:!0}),ou.isFileExists=ou.offlinePluginConversion=ou.executeCommand=ou.getNpmPath=ou.hasNpmPackInPaths=void 0;const Bu=r,du=lu(e),fu=su(u),_u=i,pu=l;ou.hasNpmPackInPaths=function(u,D){try{return require.resolve(u,{paths:[...D]}),!0}catch(u){return!1}},ou.getNpmPath=function(){const u=process.execPath;return fu.join(fu.dirname(u),_u.NPM_TOOL)},ou.executeCommand=function(u,D,e){0!==(0,Bu.spawnSync)(u,D,e).status&&(0,pu.logErrorAndExit)(`Error: ${u} ${D} execute failed.See above for details.`)},ou.offlinePluginConversion=function(u,D){return D.startsWith("file:")||D.endsWith(".tgz")?fu.resolve(u,_u.HVIGOR,D.replace("file:","")):D},ou.isFileExists=function(u){return du.default.existsSync(u)&&du.default.statSync(u).isFile()};var Ou=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),hu=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),Pu=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&Ou(D,u,e);return hu(D,u),D},vu=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(P,"__esModule",{value:!0});var gu=P.initProjectWorkSpace=void 0;const mu=Pu(e),Ru=vu(D),yu=Pu(u),Iu=v,Nu=i,bu=g,Su=l,wu=ou;let Hu,xu,Mu;function Tu(u,D,e){return void 0!==e.dependencies&&(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,D.dependencies[u])===yu.normalize(e.dependencies[u])}function Vu(){const u=yu.join(Mu,Nu.WORK_SPACE);if((0,Su.logInfoPrintConsole)("Hvigor cleaning..."),!mu.existsSync(u))return;const D=mu.readdirSync(u);if(!D||0===D.length)return;const e=yu.resolve(Mu,"node_modules","@ohos","hvigor","bin","hvigor.js");mu.existsSync(e)&&(0,wu.executeCommand)(process.argv[0],[e,"--stop-daemon"],{});try{D.forEach((D=>{mu.rmSync(yu.resolve(u,D),{recursive:!0})}))}catch(D){(0,Su.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${u}.`)}}gu=P.initProjectWorkSpace=function(){if(Hu=function(){const u=yu.resolve(Nu.HVIGOR_PROJECT_WRAPPER_HOME,Nu.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);mu.existsSync(u)||(0,Su.logErrorAndExit)(`Error: Hvigor config file ${u} does not exist.`);return(0,bu.parseJsonFile)(u)}(),Mu=function(u){let D;D=function(u){let D=u.hvigorVersion;if(D.startsWith("file:")||D.endsWith(".tgz"))return!1;const e=u.dependencies,t=Object.getOwnPropertyNames(e);for(const u of t){const D=e[u];if(D.startsWith("file:")||D.endsWith(".tgz"))return!1}if(1===t.length&&"@ohos/hvigor-ohos-plugin"===t[0])return D>"2.5.0";return!1}(u)?function(u){let D=`${Nu.HVIGOR_ENGINE_PACKAGE_NAME}@${u.hvigorVersion}`;const e=u.dependencies;if(e){Object.getOwnPropertyNames(e).sort().forEach((u=>{D+=`,${u}@${e[u]}`}))}return(0,Iu.hash)(D)}(u):(0,Iu.hash)(process.cwd());return yu.resolve(Ru.default.homedir(),".hvigor","project_caches",D)}(Hu),xu=function(){const u=yu.resolve(Mu,Nu.WORK_SPACE,Nu.DEFAULT_PACKAGE_JSON);return mu.existsSync(u)?(0,bu.parseJsonFile)(u):{dependencies:{}}}(),!(0,wu.hasNpmPackInPaths)(Nu.HVIGOR_ENGINE_PACKAGE_NAME,[yu.join(Mu,Nu.WORK_SPACE)])||(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion)!==xu.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]||!function(){function u(u){const D=null==u?void 0:u.dependencies;return void 0===D?0:Object.getOwnPropertyNames(D).length}const D=u(Hu),e=u(xu);if(D+1!==e)return!1;for(const u in null==Hu?void 0:Hu.dependencies)if(!(0,wu.hasNpmPackInPaths)(u,[yu.join(Mu,Nu.WORK_SPACE)])||!Tu(u,Hu,xu))return!1;return!0}()){Vu();try{!function(){(0,Su.logInfoPrintConsole)("Hvigor installing...");for(const u in Hu.dependencies)Hu.dependencies[u]&&(Hu.dependencies[u]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.dependencies[u]));const u={dependencies:{...Hu.dependencies}};u.dependencies[Nu.HVIGOR_ENGINE_PACKAGE_NAME]=(0,wu.offlinePluginConversion)(Nu.HVIGOR_PROJECT_ROOT_DIR,Hu.hvigorVersion);const D=yu.join(Mu,Nu.WORK_SPACE);try{mu.mkdirSync(D,{recursive:!0});const e=yu.resolve(D,Nu.DEFAULT_PACKAGE_JSON);mu.writeFileSync(e,JSON.stringify(u))}catch(u){(0,Su.logErrorAndExit)(u)}(function(){const u=["config","set","store-dir",Nu.HVIGOR_PNPM_STORE_PATH],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)})(),function(){const u=["install"],D={cwd:yu.join(Mu,Nu.WORK_SPACE),stdio:["inherit","inherit","inherit"]};(0,wu.executeCommand)(Nu.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,u,D)}(),(0,Su.logInfoPrintConsole)("Hvigor install success.")}()}catch(u){Vu()}}return Mu};var Gu={};!function(t){var C=n&&n.__createBinding||(Object.create?function(u,D,e,t){void 0===t&&(t=e);var r=Object.getOwnPropertyDescriptor(D,e);r&&!("get"in r?!D.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return D[e]}}),Object.defineProperty(u,t,r)}:function(u,D,e,t){void 0===t&&(t=e),u[t]=D[e]}),F=n&&n.__setModuleDefault||(Object.create?function(u,D){Object.defineProperty(u,"default",{enumerable:!0,value:D})}:function(u,D){u.default=D}),E=n&&n.__importStar||function(u){if(u&&u.__esModule)return u;var D={};if(null!=u)for(var e in u)"default"!==e&&Object.prototype.hasOwnProperty.call(u,e)&&C(D,u,e);return F(D,u),D},A=n&&n.__importDefault||function(u){return u&&u.__esModule?u:{default:u}};Object.defineProperty(t,"__esModule",{value:!0}),t.executeInstallPnpm=t.isPnpmInstalled=t.environmentHandler=t.checkNpmConifg=t.PNPM_VERSION=void 0;const o=r,a=E(e),c=A(D),s=E(u),B=i,d=l,f=ou;t.PNPM_VERSION="7.30.0",t.checkNpmConifg=function(){const u=s.resolve(B.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),D=s.resolve(c.default.homedir(),".npmrc");if((0,f.isFileExists)(u)||(0,f.isFileExists)(D))return;const e=(0,f.getNpmPath)(),t=(0,o.spawnSync)(e,["config","get","prefix"],{cwd:B.HVIGOR_PROJECT_ROOT_DIR});if(0!==t.status||!t.stdout)return void(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const r=s.resolve(`${t.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,f.isFileExists)(r)||(0,d.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},t.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},t.isPnpmInstalled=function(){return!!a.existsSync(B.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,f.hasNpmPackInPaths)("pnpm",[B.HVIGOR_WRAPPER_TOOLS_HOME])},t.executeInstallPnpm=function(){(0,d.logInfoPrintConsole)(`Installing pnpm@${t.PNPM_VERSION}...`);const u=(0,f.getNpmPath)();!function(){const u=s.resolve(B.HVIGOR_WRAPPER_TOOLS_HOME,B.DEFAULT_PACKAGE_JSON);try{a.existsSync(B.HVIGOR_WRAPPER_TOOLS_HOME)||a.mkdirSync(B.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const D={dependencies:{}};D.dependencies[B.PNPM]=t.PNPM_VERSION,a.writeFileSync(u,JSON.stringify(D))}catch(D){(0,d.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${u} failed.`)}}(),(0,f.executeCommand)(u,["install","pnpm"],{cwd:B.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,d.logInfoPrintConsole)("Pnpm install success.")}}(Gu),function(){Gu.checkNpmConifg(),Gu.environmentHandler(),Gu.isPnpmInstalled()||Gu.executeInstallPnpm();const D=gu();_(u.join(D,i.WORK_SPACE))}(); \ No newline at end of file diff --git a/ohos/happroject/hvigorfile.ts b/ohos/happroject/hvigorfile.ts new file mode 100755 index 0000000000..f3cb9f1a87 --- /dev/null +++ b/ohos/happroject/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/ohos/happroject/hvigorw b/ohos/happroject/hvigorw new file mode 100755 index 0000000000..4f0aa945c9 --- /dev/null +++ b/ohos/happroject/hvigorw @@ -0,0 +1,54 @@ +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME="`pwd -P`" +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +#NODE_OPTS="--max-old-space-size=4096" + +fail() { + echo "$*" + exit 1 +} + +set_executable_node() { + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + + EXECUTABLE_NODE="${NODE_HOME}/node" + if [ -x "$EXECUTABLE_NODE" ]; then + return + fi + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ]; then + set_executable_node +else + EXECUTABLE_NODE="node" + command -v ${EXECUTABLE_NODE} &> /dev/null || fail "ERROR: NODE_HOME not set and 'node' command not found" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ]; then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +if [ -z "${NODE_OPTS}" ]; then + NODE_OPTS="--" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" "${NODE_OPTS}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/happroject/hvigorw.bat b/ohos/happroject/hvigorw.bat new file mode 100755 index 0000000000..b5eecf5a15 --- /dev/null +++ b/ohos/happroject/hvigorw.bat @@ -0,0 +1,54 @@ +@rem +@rem ---------------------------------------------------------------------------- +@rem Hvigor startup script for Windows, version 1.0.0 +@rem +@rem Required ENV vars: +@rem ------------------ +@rem NODE_HOME - location of a Node home dir +@rem or +@rem Add %NODE_HOME%/bin to the PATH environment variable +@rem ---------------------------------------------------------------------------- +@rem +@echo off + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe +@rem set NODE_OPTS="--max-old-space-size=4096" + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +if not defined NODE_OPTS set NODE_OPTS="--" + +@rem Find node.exe +if defined NODE_HOME ( + set NODE_HOME=%NODE_HOME:"=% + set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% +) + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else if exist "%NODE_EXE_PATH%" ( + "%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %* +) else ( + echo. + echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. + echo. + echo Please set the NODE_HOME variable in your environment to match the + echo location of your NodeJs installation. +) + +if "%ERRORLEVEL%" == "0" ( + if "%OS%" == "Windows_NT" endlocal +) else ( + exit /b %ERRORLEVEL% +) \ No newline at end of file diff --git a/ohos/happroject/local.properties b/ohos/happroject/local.properties new file mode 100755 index 0000000000..58500aba7b --- /dev/null +++ b/ohos/happroject/local.properties @@ -0,0 +1,8 @@ +# This file is automatically generated by DevEco Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file should *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# For customization when using a Version Control System, please read the header note. +sdk.dir=/home/wshi/workspace/tools/ohos-sdk/openharmony/ \ No newline at end of file diff --git a/ohos/happroject/oh-package.json5 b/ohos/happroject/oh-package.json5 new file mode 100755 index 0000000000..b45d4df695 --- /dev/null +++ b/ohos/happroject/oh-package.json5 @@ -0,0 +1,13 @@ +{ + "name": "crdp", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.13" + } +} diff --git a/scripts/ohos/build_hap.py b/scripts/ohos/build_hap.py new file mode 100755 index 0000000000..b793476b14 --- /dev/null +++ b/scripts/ohos/build_hap.py @@ -0,0 +1,810 @@ +# -*- coding: utf-8 -*- + +#------------------------------------------------------------------------- +# drawElements Quality Program utilities +# -------------------------------------- +# +# Copyright 2017 The Ohos Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#------------------------------------------------------------------------- + +# \todo [2017-04-10 pyry] +# * Use smarter asset copy in main build +# * cmake -E copy_directory doesn't copy timestamps which will cause +# assets to be always re-packaged +# * Consider adding an option for downloading SDK & NDK + +import os +import re +import sys +import glob +import shutil +import argparse +import tempfile +import logging +import json +import xml.etree.ElementTree + +# Import from /scripts +sys.path.append(os.path.join(os.path.dirname(__file__), "..")) + +from ctsbuild.common import * +from ctsbuild.config import * +from ctsbuild.build import * + +class SDKEnv: + def __init__(self, path, desired_version): + self.path = path + self.buildToolsVersion = SDKEnv.selectBuildToolsVersion(self.path, desired_version) + + @staticmethod + def getBuildToolsVersions (path): + buildToolsPath = os.path.join(path, "version.txt") + versions = {} + logging.info("getBuildToolsVersions %s." % (buildToolsPath)) + if os.path.exists(buildToolsPath): + with open(buildToolsPath) as buildToolsFile: + for line in buildToolsFile: + keyValue = list(map(lambda x: x.strip(), line.split(":"))) + logging.info("keyValue[0] %s", keyValue[0]) + if keyValue[0] == "HarmonyOS SDK": + logging.info("keyValue[1] %s", keyValue[1].split()[0]) + versionsList = keyValue[1].split()[0].split(".") + versions[int(versionsList[0])] = (int(versionsList[0]), int(versionsList[1]), int(versionsList[2])) + return versions + + @staticmethod + def selectBuildToolsVersion (path, preferred): + logging.info("selectBuildToolsVersion %s, %d ." % (path, preferred)) + versions = SDKEnv.getBuildToolsVersions(path) + + if len(versions) == 0: + return (0,0,0) + + if preferred == -1: + return max(versions.values()) + + if preferred in versions: + return versions[preferred] + + # Pick newest + newest_version = max(versions.values()) + logging.info("Couldn't find Ohos Tool version %d, %d was selected." % (preferred, newest_version[0])) + return newest_version + + def getPlatformLibrary (self, apiVersion): + return os.path.join(self.path, "platforms", "ohos-%d" % apiVersion, "ohos.jar") + + def getHvigorPath (self): + return os.path.join(self.path, "hvigor", "bin") + + def getHapSignToolPath (self): + return os.path.join(self.path, "sdk", "default", "openharmony", "toolchains", "lib") + +class CLTEnv: + def __init__(self, path): + self.path = path + self.version = CLTEnv.detectVersion(self.path) + self.hostOsName = CLTEnv.detectHostOsName(self.path) + + @staticmethod + def getKnownAbis (): + return ["armeabi-v7a", "arm64-v8a"] + + @staticmethod + def getAbiPrebuiltsName (abiName): + prebuilts = { + "armeabi-v7a": 'ohos-arm', + "arm64-v8a": 'ohos-arm64', + "x86": 'ohos-x86', + "x86_64": 'ohos-x86_64', + } + + if not abiName in prebuilts: + raise Exception("Unknown ABI: " + abiName) + + return prebuilts[abiName] + + @staticmethod + def detectVersion (path): + propFilePath = os.path.join(path, "linux/native/oh-uni-package.json") + try: + with open(propFilePath) as propFile: + for line in propFile: + keyValue = list(map(lambda x: x.strip(), line.split(":"))) + logging.info("keyValue[0] %s", keyValue[0]) + if keyValue[0] == "\"version\"": + logging.info("keyValue[1] %s", keyValue[1]) + versionParts = keyValue[1].replace("\"", "").split(".") + return tuple(map(int, versionParts[0:2])) + except Exception as e: + raise Exception("Failed to read source prop file '%s': %s" % (propFilePath, str(e))) + except: + raise Exception("Failed to read source prop file '%s': unkown error") + + raise Exception("Failed to detect NDK version (does %s/native/oh-uni-package.json have version?)" % path) + + @staticmethod + def isHostOsSupported (hostOsName): + os = HostInfo.getOs() + bits = HostInfo.getArchBits() + hostOsParts = hostOsName.split('-') + + if len(hostOsParts) > 1: + assert(len(hostOsParts) == 2) + assert(hostOsParts[1] == "x86_64") + + if bits != 64: + return False + + if os == HostInfo.OS_WINDOWS: + return hostOsParts[0] == 'windows' + elif os == HostInfo.OS_LINUX: + return hostOsParts[0] == 'linux' + elif os == HostInfo.OS_OSX: + return hostOsParts[0] == 'darwin' + else: + raise Exception("Unhandled HostInfo.getOs() '%d'" % os) + + @staticmethod + def detectHostOsName (path): + logging.info("detectHostOsName path %s", path) + hostOsNames = [ + "linux", + "windows", + ] + + for name in hostOsNames: + if os.path.exists(os.path.join(path, name)): + return name + + raise Exception("Failed to determine NDK host OS") + +class Environment: + def __init__(self, sdk, ndk): + self.sdk = sdk + self.ndk = ndk + +class Configuration: + def __init__(self, env, buildPath, abis, nativeApi, arktsApi, minApi, nativeBuildType, verbose, layers, angle): + self.env = env + self.sourcePath = DEQP_DIR + self.buildPath = buildPath + self.abis = abis + self.nativeApi = nativeApi + self.arktsApi = arktsApi + self.minApi = minApi + self.nativeBuildType = nativeBuildType + self.verbose = verbose + self.layers = layers + self.angle = angle + self.dCompilerName = "./hvigorw" + self.cmakeGenerator = selectFirstAvailableGenerator([MAKEFILE_GENERATOR]) + + def check (self): + if self.cmakeGenerator == None: + raise Exception("Failed to find build tools for CMake") + + if not os.path.exists(self.env.ndk.path): + raise Exception("Ohos NDK not found at %s" % self.env.ndk.path) + + if not CLTEnv.isHostOsSupported(self.env.ndk.hostOsName): + raise Exception("NDK '%s' is not supported on this machine" % self.env.ndk.hostOsName) + + if self.env.ndk.version[0] < 4: + raise Exception("Ohos public sdk version %d is not supported; build requires public sdk version >= 4" % (self.env.ndk.version[0])) + + if not (self.minApi <= self.arktsApi <= self.nativeApi): + raise Exception("Requires: min-api (%d) <= arkts-api (%d) <= native-api (%d)" % (self.minApi, self.arktsApi, self.nativeApi)) + + if self.env.sdk.buildToolsVersion == (0,0,0): + raise Exception("No build tools directory found at %s" % os.path.join(self.env.sdk.path, "build-tools")) + + if not os.path.exists(os.path.join(self.env.sdk.path, "version.txt")): + raise Exception("No SDK with api version %d directory found at %s for Api" % (self.arktsApi, os.path.join(self.env.sdk.path, "platforms"))) + + # Try to find first d8 since dx was deprecated + if which(self.dCompilerName, [self.env.sdk.getHvigorPath()]) == None: + logging.info("Couldn't find %s in path %s, will try to find dx", + self.dCompilerName, self.env.sdk.getHvigorPath()) + self.dCompilerName = "hvigorw" + + ohosBuildTools = ["hvigorw.bat", "hvigorw.js", self.dCompilerName] + for tool in ohosBuildTools: + if which(tool, [self.env.sdk.getHvigorPath()]) == None: + raise Exception("Missing Ohos build tool: %s in %s" % (tool, self.env.sdk.getHvigorPath())) + + requiredToolsInPath = ["javac", "jar", "keytool"] + for tool in requiredToolsInPath: + if which(tool) == None: + raise Exception("%s not in PATH" % tool) + +def log (config, msg): + if config.verbose: + logging.info(msg) + +def executeAndLog (config, args): + if config.verbose: + logging.info(" ".join(args)) + execute(args) + +# Path components + +class ResolvablePathComponent: + def __init__ (self): + pass + +class SourceRoot (ResolvablePathComponent): + def resolve (self, config): + return config.sourcePath + +class BuildRoot (ResolvablePathComponent): + def resolve (self, config): + return config.buildPath + +class NativeBuildPath (ResolvablePathComponent): + def __init__ (self, abiName): + self.abiName = abiName + + def resolve (self, config): + return getNativeBuildPath(config, self.abiName) + +def resolvePath (config, path): + resolvedComps = [] + + for component in path: + if isinstance(component, ResolvablePathComponent): + resolvedComps.append(component.resolve(config)) + else: + resolvedComps.append(str(component)) + #log(config, "do resolvePath: %s" % (resolvedComps)) + return os.path.join(*resolvedComps) + +def resolvePaths (config, paths): + return list(map(lambda p: resolvePath(config, p), paths)) + +class BuildStep: + def __init__ (self): + pass + + def getInputs (self): + return [] + + def getOutputs (self): + return [] + + @staticmethod + def expandPathsToFiles (paths): + """ + Expand mixed list of file and directory paths into a flattened list + of files. Any non-existent input paths are preserved as is. + """ + + def getFiles (dirPath): + for root, dirs, files in os.walk(dirPath): + for file in files: + yield os.path.join(root, file) + + files = [] + for path in paths: + if os.path.isdir(path): + files += list(getFiles(path)) + else: + files.append(path) + + return files + + def isUpToDate (self, config): + inputs = resolvePaths(config, self.getInputs()) + outputs = resolvePaths(config, self.getOutputs()) + + assert len(inputs) > 0 and len(outputs) > 0 + + expandedInputs = BuildStep.expandPathsToFiles(inputs) + expandedOutputs = BuildStep.expandPathsToFiles(outputs) + + existingInputs = list(filter(os.path.exists, expandedInputs)) + existingOutputs = list(filter(os.path.exists, expandedOutputs)) + + if len(existingInputs) != len(expandedInputs): + for file in expandedInputs: + if file not in existingInputs: + logging.info("ERROR: Missing input file: %s" % file) + die("Missing input files") + + if len(existingOutputs) != len(expandedOutputs): + return False # One or more output files are missing + + lastInputChange = max(map(os.path.getmtime, existingInputs)) + firstOutputChange = min(map(os.path.getmtime, existingOutputs)) + + return lastInputChange <= firstOutputChange + + def update (config): + die("BuildStep.update() not implemented") + +def getNativeBuildPath (config, abiName): + return os.path.join(config.buildPath, "%s-%s-%d" % (abiName, config.nativeBuildType, config.nativeApi)) + +def clearCMakeCacheVariables(args): + # New value, so clear the necessary cmake variables + args.append('-UANGLE_LIBS') + args.append('-UGLES1_LIBRARY') + args.append('-UGLES2_LIBRARY') + args.append('-UEGL_LIBRARY') + +def buildNativeLibrary (config, abiName): + def makeNDKVersionString (version): + minorVersionString = (chr(ord('a') + version[1]) if version[1] > 0 else "") + return "r%d%s" % (version[0], minorVersionString) + + def getBuildArgs (config, abiName): + sdkpath = os.path.join(config.env.sdk.path, "sdk/default/openharmony/native/build/cmake/ohos.toolchain.cmake") + # log(config, "ndkpath=%s" % config.env.ndk.path) + # log(config, 'sdkpath=%s' % config.env.sdk.path) + # log(config, 'sdkjoinpath=%s' % sdkpath) + + args = ['-DDEQP_TARGET=ohos', + '-DDEQP_TARGET_TOOLCHAIN=ohos', + '-DDE_OS=DE_OS_OHOS', + '-D_XOPEN_SOURCE=600', + '-DOHOS_ARCH=%s' % abiName, + '-DOHOS_ABI=%s' % abiName, + '-DCMAKE_TOOLCHAIN_FILE=%s' % sdkpath] + + if config.angle is None: + # Find any previous builds that may have embedded ANGLE libs and clear the CMake cache + for abi in CLTEnv.getKnownAbis(): + cMakeCachePath = os.path.join(getNativeBuildPath(config, abi), "CMakeCache.txt") + try: + if 'ANGLE_LIBS' in open(cMakeCachePath).read(): + clearCMakeCacheVariables(args) + except IOError: + pass + else: + cMakeCachePath = os.path.join(getNativeBuildPath(config, abiName), "CMakeCache.txt") + angleLibsDir = os.path.join(config.angle, abiName) + # Check if the user changed where the ANGLE libs are being loaded from + try: + if angleLibsDir not in open(cMakeCachePath).read(): + clearCMakeCacheVariables(args) + except IOError: + pass + args.append('-DANGLE_LIBS=%s' % angleLibsDir) + + return args + + nativeBuildPath = getNativeBuildPath(config, abiName) + buildConfig = BuildConfig(nativeBuildPath, config.nativeBuildType, getBuildArgs(config, abiName)) + build(buildConfig, config.cmakeGenerator) + +def executeSteps (config, steps): + for step in steps: + if not step.isUpToDate(config): + step.update(config) + +def parsePackageName (manifestPath): + with open(manifestPath, 'r', encoding='utf-8') as f: + data = json.load(f) + logging.info("bundleName= %s", data['app']['bundleName']) + return data['app']['bundleName'] + +class PackageDescription: + def __init__ (self, appDirName, appName, hasResources = True): + logging.info("appDirName=%s, appName=%s", appDirName, appName) + self.appDirName = appDirName + self.hapDirName = "ohos" + self.appName = appName + self.hasResources = hasResources + + def getAppName (self): + return self.appName + + def getAppDirName (self): + return self.appDirName + + def getHapDirName (self): + return self.hapDirName + + def getPackageName (self, config): + # log(config, "getPackageName manifestPath: %s" % self.getAppJsonPath()) + manifestPath = resolvePath(config, self.getAppJsonPath()) + + return parsePackageName(manifestPath) + + def getAppJsonPath (self): + return [SourceRoot(), "ohos", self.appDirName, "AppScope/app.json5"] + + def getResPath (self): + return [SourceRoot(), "ohos", self.appDirName, "entry/src/main/resources"] + + def getSourcePaths (self): + return [ + [SourceRoot(), "ohos", self.appDirName, ""] + ] + + def getClassesHapPath (self): + return [BuildRoot(), self.appDirName, "", "happroject"] + +# Build step implementations + +class BuildNativeLibrary (BuildStep): + def __init__ (self, abi): + self.abi = abi + + def isUpToDate (self, config): + return False + + def update (self, config): + buildNativeLibrary(config, self.abi) + +class CreateKeystore (BuildStep): + def __init__ (self): + self.keystorePath = [BuildRoot(), "debug.keystore"] + + def getOutputs (self): + return [self.keystorePath] + + def isUpToDate (self, config): + return os.path.exists(resolvePath(config, self.keystorePath)) + + def update (self, config): + executeAndLog(config, [ + "keytool", + "-genkeypair", + "-keystore", resolvePath(config, self.keystorePath), + "-storepass", "ohos", + "-alias", "ohosdebugkey", + "-keypass", "ohos", + "-keyalg", "RSA", + "-keysize", "2048", + "-validity", "10000", + "-dname", "CN=, OU=, O=, L=, S=, C=", + ]) + +class BuildBaseHap (BuildStep): + def __init__ (self, package, libraries = []): + self.package = package + self.libraries = libraries + self.srcPath = [BuildRoot(), self.package.getAppDirName(), "", "happroject"] + self.dstPath = [BuildRoot(), self.package.getAppDirName(), "happroject", "autosign", "entry-default-signed.hap"] + + def getResPaths (self): + paths = [] + for pkg in [self.package] + self.libraries: + if pkg.hasResources: + paths.append(pkg.getResPath()) + return paths + + def getInputs (self): + return [self.srcPath] + + def getOutputs (self): + return [self.dstPath] + + def update (self, config): + hvigorwPath = which("hvigorw", [config.env.sdk.getHvigorPath()]) + log(config, "BuildBaseAPK hvigorwPath=%s" % hvigorwPath) + + args = [ + "./hvigorw", + "assembleHap", + "--mode", + "module", "-p", "product=default", + "-p", "buildMode=debug", "--no-daemon" + ] + workPath = resolvePath(config, self.srcPath) + pushWorkingDir(workPath) + args = [ + "./hvigorw", + "assembleHap", + "--mode", + "module", "-p", "product=default", + "-p", "buildMode=debug", "--no-daemon" + ] + executeAndLog(config, args) + popWorkingDir() + +class AddHapToBuild (BuildStep): + def __init__ (self, package): + self.package = package + self.srcPath = [SourceRoot(), "ohos", "happroject"] + self.dstPath = [BuildRoot(), self.package.getAppDirName(), "happroject"] + + def getInputs (self): + return [ + self.srcPath, + ] + + def getOutputs (self): + return [self.dstPath] + + def update (self, config): + srcPath = resolvePath(config, self.srcPath) + dstPath = resolvePath(config, self.dstPath) + + if os.path.exists(dstPath): + shutil.rmtree(dstPath) + + shutil.copytree(srcPath, dstPath) + +class AddDataToHap (BuildStep): + def __init__ (self, package, abi): + self.package = package + self.buildPath = [NativeBuildPath(abi)] + self.srcPath = [SourceRoot(), "external", "openglcts", "data", "gl_cts"] + self.dstPath = [BuildRoot(), self.package.getAppDirName(), "happroject", "entry", "src", "main", "resources", "rawfile", "gl_cts"] + self.srcDataPath = [SourceRoot(), "data"] + self.dstDataPath = [BuildRoot(), self.package.getAppDirName(), "happroject", "entry", "src", "main", "resources", "rawfile"] + + def getInputs (self): + return [ + self.srcPath, + ] + + def getOutputs (self): + return [self.dstPath] + + def update (self, config): + srcPath = resolvePath(config, self.srcPath) + dstPath = resolvePath(config, self.dstPath) + buildPath = resolvePath(config, self.buildPath) + srcDataPath = resolvePath(config, self.srcDataPath) + dstDataPath = resolvePath(config, self.dstDataPath) + + if os.path.exists(dstDataPath): + shutil.rmtree(dstDataPath) + + shutil.copytree(srcDataPath, dstDataPath) + shutil.copytree(srcPath, dstPath) + +class AddNativeLibsToHap (BuildStep): + def __init__ (self, package, abis): + self.package = package + self.abis = abis + + self.srcPath = [BuildRoot(), self.package.getAppDirName()] + self.dstPath = [BuildRoot(), self.package.getAppDirName(), "happroject", "entry", "libs"] + + + def getInputs (self): + paths = [self.srcPath] + for abi in self.abis: + paths.append([NativeBuildPath(abi), "libdeqp.so"]) + return paths + + def getOutputs (self): + return [self.dstPath] + + def update (self, config): + pkgPath = resolvePath(config, [BuildRoot(), self.package.getAppDirName(), "happroject", "entry", "libs"]) + libFiles = [] + + # Create right directory structure first + for abi in self.abis: + libSrcPath = resolvePath(config, [NativeBuildPath(abi), "libdeqp.so"]) + libRelPath = os.path.join(abi, "libdeqp.so") + libAbsPath = os.path.join(pkgPath, libRelPath) + + if not os.path.exists(os.path.dirname(libAbsPath)): + os.makedirs(os.path.dirname(libAbsPath)) + shutil.copyfile(libSrcPath, libAbsPath) + libFiles.append(libRelPath) + +class SignHap (BuildStep): + def __init__ (self, package): + self.package = package + self.srcPath = [BuildRoot(), self.package.getAppDirName(), "happroject", "autosign"] + self.dstPath = [BuildRoot(), self.package.getAppDirName(), "happroject", "autosign", "entry-default-signed.hap"] + self.keystorePath = [BuildRoot(), self.package.getAppDirName(), "", "happroject"] + + def getInputs (self): + return [self.srcPath, self.keystorePath] + + def getOutputs (self): + return [self.dstPath] + + def update (self, config): + hapSignToolPath = which("hap-sign-tool.jar", [config.env.sdk.getHapSignToolPath()]) + workPath = resolvePath(config, self.srcPath) + hapSignToolPath = resolvePath(config, [config.env.sdk.getHapSignToolPath(), "hap-sign-tool.jar"]) + + pushWorkingDir(workPath) + unsignHapPath = resolvePath(config, [BuildRoot(), self.package.getAppDirName(), + "happroject", "entry", "build", "default", "outputs", "default", "entry-default-unsigned.hap"]) + + args = [ + "java", + "-jar", hapSignToolPath, "sign-app", "-keyAlias", "oh-app1-key-v1", + "-signAlg", "SHA256withECDSA", "-mode", "localSign", "-appCertFile", + "app1.cer", "-profileFile", "app1-profile.p7b", "-inFile", unsignHapPath, + "-keystoreFile", "OpenHarmony.p12", "-outFile", "deqpCts.hap", "-keyPwd", "123456", + "-keystorePwd", "123456" + ] + + executeAndLog(config, args) + popWorkingDir() + +def getBuildRootRelativeHapPath (package): + return os.path.join(package.getAppDirName(), "happroject", "autosign", package.getAppName() + ".hap") + +def getBuildStepsForPackage (abis, package, libraries = []): + steps = [] + assert len(abis) > 0 + + # Build native code first + for abi in abis: + steps += [BuildNativeLibrary(abi)] + + steps.append(AddHapToBuild(package)) + steps.append(AddDataToHap(package, abis[0])) + steps.append(AddNativeLibsToHap(package, abis)) + steps.append(BuildBaseHap(package, libraries)) + steps.append(SignHap(package)) + + return steps + +def getPackageAndLibrariesForTarget (target): + deqpPackage = PackageDescription("", "deqpCts") + ctsPackage = PackageDescription("openglcts", "Khronos-CTS", hasResources = False) + + if target == 'deqp': + return (deqpPackage, []) + elif target == 'openglcts': + return (ctsPackage, [deqpPackage]) + else: + raise Exception("Uknown target '%s'" % target) + +def findSDK (): + ndkBuildPath = which('ndk-build') + if ndkBuildPath != None: + return os.path.dirname(ndkBuildPath) + else: + return None + +def findCLT (): + sdkBuildPath = which('ohos') + if sdkBuildPath != None: + return os.path.dirname(os.path.dirname(sdkBuildPath)) + else: + return None + +def getDefaultBuildRoot (): + return os.path.join(tempfile.gettempdir(), "deqp-ohos-build") + +def parseArgs (): + nativeBuildTypes = ['Release', 'Debug', 'MinSizeRel', 'RelWithAsserts', 'RelWithDebInfo'] + defaultSDKPath = findSDK() + defaultCLTPath = findCLT() + defaultBuildRoot = getDefaultBuildRoot() + + parser = argparse.ArgumentParser(os.path.basename(__file__), + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--native-build-type', + dest='nativeBuildType', + default="Release", + choices=nativeBuildTypes, + help="Native code build type") + parser.add_argument('--build-root', + dest='buildRoot', + default=defaultBuildRoot, + help="Root build directory") + parser.add_argument('--abis', + dest='abis', + default=",".join(CLTEnv.getKnownAbis()), + help="ABIs to build") + parser.add_argument('--native-api', + type=int, + dest='nativeApi', + default=20, + help="Ohos API level to target in native code") + parser.add_argument('--arkts-api', + type=int, + dest='arktsApi', + default=11, + help="Ohos API level to target in Arkts code") + parser.add_argument('--tool-api', + type=int, + dest='toolApi', + default=-1, + help="Ohos Tools level to target (-1 being maximum present)") + parser.add_argument('--min-api', + type=int, + dest='minApi', + default=10, + help="Minimum Ohos API level for which the APK can be installed") + parser.add_argument('--clt', + dest='cltPath', + default=defaultCLTPath, + help="HarmonyOS Command Line Tools path", + required=(True if defaultCLTPath == None else False)) + parser.add_argument('--sdk', + dest='sdkPath', + default=defaultSDKPath, + help="Ohos Public SDK path", + required=(True if defaultSDKPath == None else False)) + parser.add_argument('-v', '--verbose', + dest='verbose', + help="Verbose output", + default=True, + action='store_true') + parser.add_argument('--target', + dest='target', + help='Build target', + choices=['deqp', 'openglcts'], + default='deqp') + parser.add_argument('--layers-path', + dest='layers', + default=None, + required=False) + parser.add_argument('--angle-path', + dest='angle', + default=None, + required=False) + + args = parser.parse_args() + + def parseAbis (abisStr): + knownAbis = set(CLTEnv.getKnownAbis()) + abis = [] + + for abi in abisStr.split(','): + abi = abi.strip() + if not abi in knownAbis: + raise Exception("Unknown ABI: %s" % abi) + abis.append(abi) + + return abis + + # Custom parsing & checks + try: + args.abis = parseAbis(args.abis) + if len(args.abis) == 0: + raise Exception("--abis can't be empty") + except Exception as e: + logging.info("ERROR: %s" % str(e)) + parser.logging.info_help() + sys.exit(-1) + + return args + +if __name__ == "__main__": + logging.root.setLevel(logging.INFO) + args = parseArgs() + + ndk = CLTEnv(os.path.realpath(args.sdkPath)) + sdk = SDKEnv(os.path.realpath(args.cltPath), args.toolApi) + buildPath = os.path.realpath(args.buildRoot) + env = Environment(sdk, ndk) + config = Configuration(env, buildPath, abis=args.abis, nativeApi=args.nativeApi, arktsApi=args.arktsApi, minApi=args.minApi, nativeBuildType=args.nativeBuildType, + verbose=args.verbose, layers=args.layers, angle=args.angle) + + try: + config.check() + except Exception as e: + logging.info("ERROR: %s" % str(e)) + logging.info("") + logging.info("Please check your configuration:") + logging.info(" --sdk=%s" % args.sdkPath) + logging.info(" --ndk=%s" % args.ndkPath) + sys.exit(-1) + + pkg, libs = getPackageAndLibrariesForTarget(args.target) + steps = getBuildStepsForPackage(config.abis, pkg, libs) + + executeSteps(config, steps) + + logging.info("") + logging.info("Built %s" % os.path.join(buildPath, getBuildRootRelativeHapPath(pkg))) diff --git a/targets/ohos/install.bat b/targets/ohos/install.bat new file mode 100755 index 0000000000..da9b421ce5 --- /dev/null +++ b/targets/ohos/install.bat @@ -0,0 +1,6 @@ +@echo off +echo Removing old dEQP Ondevice Package... +hdc %* uninstall com.OpenHarmony.app.test + +echo Installing dEQP Ondevice Package... +hdc %* install -r dEQP.hap diff --git a/targets/ohos/install.sh b/targets/ohos/install.sh new file mode 100755 index 0000000000..c5cc55ff16 --- /dev/null +++ b/targets/ohos/install.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +#------------------------------------------------------------------------- +# drawElements Quality Program utilities +# -------------------------------------- +# +# Copyright 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#------------------------------------------------------------------------- + +echo "Removing old dEQP Ondevice Package..." +hdc $* uninstall com.OpenHarmony.app.test + +echo "Installing dEQP Ondevice Package..." +hdc $* install -r dEQP.hap diff --git a/targets/ohos/launch.bat b/targets/ohos/launch.bat new file mode 100755 index 0000000000..b9f34370cf --- /dev/null +++ b/targets/ohos/launch.bat @@ -0,0 +1,4 @@ +@echo off +hdc %* forward tcp:50016 tcp:50016 +hdc %* shell hilog -b d +hdc %* shell aa start -a EntryAbility -b com.OpenHarmony.app.test diff --git a/targets/ohos/ohos.cmake b/targets/ohos/ohos.cmake new file mode 100755 index 0000000000..faf090a9f2 --- /dev/null +++ b/targets/ohos/ohos.cmake @@ -0,0 +1,60 @@ +#------------------------------------------------------------------------- +# drawElements CMake utilities +# ---------------------------- +# +# Copyright 2016 The OHOS Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#------------------------------------------------------------------------- + +# OHOS +message("*** Using OHOS") +set(DEQP_TARGET_NAME "OHOS") +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +if (OHOS_ARCH STREQUAL "armeabi-v7a") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfloat-abi=softfp -D__ARM_PCS_VFP=1") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfloat-abi=softfp -D__ARM_PCS_VFP=1") +endif () + +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) + +# [wshi] TODO: +# For static linking +find_library(GLES2_LIBRARY NAMES libGLESv2 GLESv2) +find_library(EGL_LIBRARY NAMES libEGL EGL) + +find_path(GLES2_INCLUDE_PATH GLES2/gl2.h) +find_path(GLES3_INCLUDE_PATH GLES3/gl3.h) +find_path(EGL_INCLUDE_PATH EGL/egl.h) + +if (GLES2_LIBRARY AND GLES2_INCLUDE_PATH) + if (GLES_ALLOW_DIRECT_LINK) + set(DEQP_GLES2_LIBRARIES ${GLES2_LIBRARY}) + endif () + include_directories(${GLES2_INCLUDE_PATH}) +endif () + +if (GLES2_LIBRARY AND GLES3_INCLUDE_PATH AND GLES_ALLOW_DIRECT_LINK) + # Assume that GLESv2 provides ES3 symbols if GLES3/gl3.h was found + set(DEQP_GLES3_LIBRARIES ${GLES2_LIBRARY}) +endif () + +if (EGL_LIBRARY AND EGL_INCLUDE_PATH) + if (GLES_ALLOW_DIRECT_LINK) + set(DEQP_EGL_LIBRARIES ${EGL_LIBRARY}) + endif () + include_directories(${EGL_INCLUDE_PATH}) +endif ()