diff --git a/attachment/repos/bootstrap/auto_complie.py b/attachment/repos/bootstrap/auto_complie.py new file mode 100644 index 0000000000000000000000000000000000000000..325caa282c59a1036ab10f1246722a6d6082e353 --- /dev/null +++ b/attachment/repos/bootstrap/auto_complie.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2024 Hunan OpenValley 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. + +import os +import platform +import subprocess +import sys +import traceback +from obs import ObsClient, PutObjectHeader + +# 使用华为obs +# pip install esdk-obs-python --trusted-host pypi.org + +OS_NAME = platform.system().lower() +IS_WINDOWS = OS_NAME.startswith("win") +IS_MAC = OS_NAME.startswith("darwin") +FLUTTER_ENGINE_PATH = os.path.join(os.getcwd(), 'src', 'flutter') +OHOS_ENGINE_TYPE_OUT = {'ohos-arm64' : 'ohos_debug_unopt_arm64', + 'ohos-arm64-profile' : 'ohos_profile_arm64', + 'ohos-arm64-release' : 'ohos_release_arm64', + 'ohos-x64' : 'ohos_debug_unopt_x64', + 'ohos-x64-profile' : 'ohos_profile_x64', + 'ohos-x64-release' : 'ohos_release_x64', + } + +# OBS 环境变量配置key信息 +ACCESS_KEY = os.getenv("AccessKeyID") +SECRET_KEY = os.getenv("SecretAccessKey") + +# 服务器地址 华南-广州 +SERVER = "https://obs.cn-south-1.myhuaweicloud.com" + +# OBS桶 +FLUTTER_OHOS = 'flutter-ohos' + +def log(msg): + print(f'================{msg}============') + +def runGitCommand(command): + result = subprocess.run(command, capture_output=True, text=True, shell=True) + if result.returncode != 0: + raise Exception(f"Git command failed: {result.stderr}") + return result.stdout + +def runPyCommand(command): + + if IS_WINDOWS: + proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + else: + proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) + + # 获取实时输出 + for line in iter(proc.stdout.readline, b''): + print(line.decode('utf-8').strip()) + + # 等待命令执行完成 + proc.wait() + +def getRemoteTags(repoPath, remoteName='origin'): + + # 获取远程仓库的所有标签 + tagsOutput = runGitCommand(f'git -C {repoPath} ls-remote --tags {remoteName}') + + # 分割输出,每一行都是一个tag + tags = tagsOutput.split('\n') + + # 去除空行和解析tag信息 + parsedTags = [line.split()[0] for line in tags if line] + + return parsedTags + +# 在指定目录及其子目录中查找指定的文件 +def findFile(directory, filename): + for root, dirs, files in os.walk(directory): + if filename in files: + return (os.path.join(root, filename)) + +# 获取上传对象的进度 +def uploadCallback(transferredAmount, totalAmount, totalSeconds): + # 获取上传平均速率(KB/S) + speed = int(transferredAmount / totalSeconds / 1024) + # 获取上传进度百分比 + progress = int(transferredAmount * 100.0 / totalAmount) + print("\r", end="") + print("速度:{} KB/S 进度: {}%: ".format(speed, progress), "▓" * (progress // 2), end="") + sys.stdout.flush() + if progress == 100: + print("") + +# 检查TAG版本 +def checkRemoteTagsUpdates(): + # 获取远程TAG的最新提交哈希 + remoteTags = getRemoteTags(FLUTTER_ENGINE_PATH) + remoteLatestTag = remoteTags[-1] + + # 获取本地分支的最新提交哈希 + localLatestCommit = runGitCommand(f'git -C {FLUTTER_ENGINE_PATH} rev-parse HEAD') + + if remoteLatestTag != localLatestCommit: + log("Remote repository has updates.") + return True + else: + log("Local repository is up to date.") + return False + +# 检查分支更新 +def checkRemoteBranchUpdates(repoPath, remoteName='origin', branch='dev'): + # 切换到你的Git仓库目录 + os.chdir(repoPath) + + # 获取远程分支的最新提交哈希 + remoteLatestCommit = runGitCommand(f'git -C {repoPath} rev-parse {remoteName}/{branch}') + + # 获取本地分支的最新提交哈希 + localLatestCommit = runGitCommand(f'git -C {repoPath} rev-parse HEAD') + + if remoteLatestCommit != localLatestCommit: + log("Remote repository has updates.") + return True + else: + log("Local repository is up to date.") + return False + +# 更新代码 +def updateCode(): + # 调用ohos.py更新代码 + log('update source code') + runPyCommand(['python3', os.path.join(os.getcwd(), 'ohos.py'), '-b', 'dev']) + +# 执行编译 +def compileCode(): + # 调用ohhos.py编译flutter engine + log('compile flutter engine debug') + runPyCommand(['python3', os.path.join(os.getcwd(), 'ohos.py'), '-t', 'debug']) + + log('compile flutter engine profile') + runPyCommand(['python3', os.path.join(os.getcwd(), 'ohos.py'), '-t', 'profile']) + + log('compile flutter engine release') + runPyCommand(['python3', os.path.join(os.getcwd(), 'ohos.py'), '-t', 'release']) + +# 获取编译产物 +def getCompileFiles(buildType): + zipfiles = ['artifacts.zip','linux-x64.zip','windows-x64.zip','darwin-x64.zip','symbols.zip'] + + files = [] + for fileName in zipfiles: + if IS_WINDOWS and fileName != 'windows-x64.zip': + continue + if IS_MAC and fileName != 'darwin-x64.zip': + continue + + files.append(findFile(os.path.join(os.getcwd(), 'src', 'out', buildType), fileName)) + + return files + +# 上传服务器 +def uploadServer(version, buildType, filePath): + try: + log(f'upload: {filePath}') + + bucketName = FLUTTER_OHOS + obsClient = ObsClient(access_key_id=ACCESS_KEY, secret_access_key=SECRET_KEY, server=SERVER) + + # 上传对象的附加头域 + headers = PutObjectHeader() + # 【可选】待上传对象的MIME类型 + headers.contentType = 'text/plain' + + # https://storage.flutter-io.cn/flutter_infra_release/flutter/cececddab019a56da828c41d55cb54484278e880/ohos-arm64-profile/linux-x64.zip + fileName = os.path.basename(filePath) + objectKey = f'flutter_infra_release/flutter/{version}/{buildType}/{fileName}' + + # 待上传文件/文件夹的完整路径,如aa/bb.txt,或aa/ + file_path = filePath + + # 文件上传 + resp = obsClient.putFile(bucketName, objectKey, file_path, headers=headers, progressCallback=uploadCallback) + # 返回码为2xx时,接口调用成功,否则接口调用失败 + if resp.status < 300: + print('Put Content Succeeded') + print('requestId:', resp.requestId) + print('etag:', resp.body.etag) + else: + print('Put Content Failed') + print('requestId:', resp.requestId) + print('errorCode:', resp.errorCode) + print('errorMessage:', resp.errorMessage) + + except: + log('Put Content Failed') + log(traceback.format_exc()) + + +def main(): + + # if checkRemoteBranchUpdates(FLUTTER_ENGINE_PATH) : + if checkRemoteTagsUpdates() : + updateCode() + compileCode() + log("编译完成") + + engineRevision = os.path.join(FLUTTER_ENGINE_PATH, 'build', 'git_revision.py') + localVersion = subprocess.getoutput(f'python {engineRevision} --repository {FLUTTER_ENGINE_PATH}') + log(localVersion) + + # 获取编译产物 + for buildType in OHOS_ENGINE_TYPE_OUT: + zipfiles = getCompileFiles(OHOS_ENGINE_TYPE_OUT[buildType]) + for filePath in zipfiles: + if not filePath or not os.path.exists(filePath): + continue + print(filePath) + # uploadServer(localVersion, buildType, filePath) + + log('上传完成') + + else : + log("本地代码已经是最新") + +if __name__ == "__main__": + exit(main()) diff --git a/attachment/repos/bootstrap/ohos.py b/attachment/repos/bootstrap/ohos.py index e759617c1f35124113809b4842021563bcd98ad8..8b67f605b758ecd6b7464ee3a7cc0508f94b8cfe 100644 --- a/attachment/repos/bootstrap/ohos.py +++ b/attachment/repos/bootstrap/ohos.py @@ -207,7 +207,10 @@ def engineConfig(buildInfo, args): # 执行engine编译操作 def engineCompile(buildInfo): - runCommand("ninja -C %s" % os.path.join("src", "out", getOutput(buildInfo))) + command = "ninja -C %s default " % os.path.join("src", "out", getOutput(buildInfo)) + if IS_WINDOWS and buildInfo.buildType != "debug": + command += "flutter/build/archives:archive_win_gen_snapshot " + runCommand(command) # 编译har文件 diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index e5dea68e12b99484f010137f0ed7545139c56b1d..37b4164707e4056cb9ca9eb48cebc41cc9f2bbc2 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -14,7 +14,7 @@ declare_args() { impeller_enable_metal = is_ios # Whether the OpenGLES backend is enabled. - impeller_enable_opengles = is_linux || is_win || is_android || is_ohos + impeller_enable_opengles = (is_linux || is_win || is_android) && !is_ohos # Whether the Vulkan backend is enabled. impeller_enable_vulkan = (is_win || is_android || is_linux) && !is_ohos diff --git a/shell/platform/ohos/BUILD.gn b/shell/platform/ohos/BUILD.gn index e6783f1d6578b533a794a94f8bc969c358819dfb..02963b06904b8a17b370506102dd5f5bc7cdf9b8 100644 --- a/shell/platform/ohos/BUILD.gn +++ b/shell/platform/ohos/BUILD.gn @@ -105,8 +105,6 @@ source_set("flutter_ohos_sources") { "ohos_touch_processor.cpp", "ohos_main.cpp" , "ohos_logger.c" , - "ohos_context_gl_impeller.cpp", - "ohos_surface_gl_impeller.cpp", # "//flutter/impeller/toolkit/egl/display.cc", "ohos_context_gl_skia.cpp" , "ohos_egl_surface.cpp" , diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/component/XComponentStruct.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/component/XComponentStruct.ets deleted file mode 100644 index 38f9c9d8beb3baf8add36591428b1a1a36a0a91c..0000000000000000000000000000000000000000 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/component/XComponentStruct.ets +++ /dev/null @@ -1,58 +0,0 @@ -/* -* Copyright (c) 2023 Hunan OpenValley 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. -*/ -import Any from '../plugin/common/Any'; -import ApplicationInfoLoader from '../embedding/engine/loader/ApplicationInfoLoader'; - -import { BuilderParams, DVModelParameters } from '../view/DynamicView/dynamicView'; - -@Component -struct XComponentStruct { - private context: Any; - private applicationInfo = ApplicationInfoLoader.load(getContext()); - dvModelParams: DVModelParameters = new DVModelParameters(); - - build() { - // todo OS解决默认背景色后可以移除冗余重复代码,仅保留差异的backgroundColor属性条件配置 - if (this.applicationInfo.isDebugMode) { - XComponent({ - id: (this.dvModelParams as Record)["xComponentId"], - type: XComponentType.TEXTURE, - libraryname: 'flutter' - }) - .onLoad((context) => { - this.context = context; - }) - .onDestroy(() => { - }) - .backgroundColor(Color.White) - } else { - XComponent({ - id: (this.dvModelParams as Record)["xComponentId"], - type: XComponentType.TEXTURE, - libraryname: 'flutter' - }) - .onLoad((context) => { - this.context = context; - }) - .onDestroy(() => { - }) - } - } - -} - -@Builder export function BuildXComponentStruct(buildParams: BuilderParams) { - XComponentStruct({dvModelParams: buildParams.params}); -} \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/loader/FlutterLoader.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/loader/FlutterLoader.ets index 347db9b83443a00958a3e35a081716b25fcc9cbd..96589b090c499fee11173c172e07e7d7db34a0ad 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/loader/FlutterLoader.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/loader/FlutterLoader.ets @@ -144,6 +144,8 @@ export default class FlutterLoader { /** * 初始化dart虚拟机方法 + *

It does not support Impeller. Do not allow adding shellArgs "--enable-impeller". + * * @param flutterShellArgs */ ensureInitializationComplete(shellArgs: Array | null) { @@ -209,8 +211,6 @@ export default class FlutterLoader { shellArgs.push("--leak-vm=" + true); - //shellArgs.push("--enable-impeller"); - // //最终初始化操作 const costTime = Date.now() - this.initStartTimestampMillis; this.flutterNapi!.init( diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterManager.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterManager.ets index bfe5cb7eb8a16d7c24fd7e287037b1e918be6dd3..086d11979b5c04f8e1aaf48ec373c3130e935764 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterManager.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterManager.ets @@ -80,6 +80,10 @@ export default class FlutterManager { } } + /** + * It's suggested to keep 'oh_flutter_' as the prefix for xcomponent_id. + * Otherwise it might affect the performance. + */ createFlutterView(context: Context): FlutterView { let flutterView = new FlutterView(`oh_flutter_${this.flutterViewIndex++}`, context); this.putFlutterView(flutterView.getId(), flutterView); diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets index 3d5c9950208c4076cccf5381ad02e6b97adda966..f67b1d0ef7652bca31830fc344bb3076f05d4236 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterPage.ets @@ -26,7 +26,7 @@ const TAG = "FlutterPage"; @Component export struct FlutterPage { @Prop viewId: string = "" - @Prop xComponentType: XComponentType = XComponentType.TEXTURE + @Prop xComponentType: XComponentType = XComponentType.SURFACE @Builder doNothingBuilder() {} @BuilderParam splashScreenView: () => void = this.doNothingBuilder; diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets index f0fe1ae96c52edbe44db59f20800bd5e52fc3e8c..8f3689dfacce16b89dab334785f3b6119cf333f7 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -143,7 +143,7 @@ export default class PlatformViewsController implements PlatformViewsAccessibili let nodeHeightLink: SubscribedAbstractProperty = AppStorage.link('nodeHeight'); let oldNodeWidth: number = AppStorage.get('nodeWidth')! let oldNodeHeight: number = AppStorage.get('nodeHeight')! - if (oldNodeWidth == physicalWidth) { + if ((oldNodeWidth == physicalWidth) && (oldNodeHeight == physicalHeight)) { onComplete.run(new PlatformViewBufferSize(physicalWidth, physicalHeight)); return; } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets index 1f015592afa34f98d1d248bd616c63e0102ff418..bab625748a70c48e9233bc64d62ec66e1cebd035 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/FlutterView.ets @@ -228,7 +228,6 @@ export class FlutterView { let systemAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); let navigationAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR); let gestureAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); - let keyboardAvoidArea = this.mainWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); if (newArea != null) { this.viewportMetrics.physicalWidth = vp2px(newArea.width as number); @@ -247,11 +246,6 @@ export class FlutterView { this.viewportMetrics.physicalViewPaddingLeft = systemAvoidArea!.leftRect.width this.viewportMetrics.physicalViewPaddingRight = systemAvoidArea!.rightRect.width - this.viewportMetrics.physicalViewInsetTop = keyboardAvoidArea!.topRect.height - this.viewportMetrics.physicalViewInsetLeft = keyboardAvoidArea!.leftRect.width - this.viewportMetrics.physicalViewInsetBottom = keyboardAvoidArea!.bottomRect.height - this.viewportMetrics.physicalViewInsetRight = keyboardAvoidArea!.rightRect.width - this.viewportMetrics.systemGestureInsetTop = gestureAvoidArea!.topRect.height this.viewportMetrics.systemGestureInsetLeft = gestureAvoidArea!.leftRect.width this.viewportMetrics.systemGestureInsetBottom = gestureAvoidArea!.bottomRect.height diff --git a/shell/platform/ohos/ohos_egl_surface.cpp b/shell/platform/ohos/ohos_egl_surface.cpp index e7ee3d9a8f426f7e27c216da81be5ab2afd384ec..ac0ce2928a89ec2e4c59e50341ebe2226e558855 100755 --- a/shell/platform/ohos/ohos_egl_surface.cpp +++ b/shell/platform/ohos/ohos_egl_surface.cpp @@ -78,13 +78,17 @@ class OhosEGLSurfaceDamage { void init(EGLDisplay display, EGLContext context) { const char* extensions = eglQueryString(display, EGL_EXTENSIONS); if (HasExtension(extensions, "EGL_KHR_partial_update")) { - set_damage_region_ = reinterpret_cast( - eglGetProcAddress("eglSetDamageRegionKHR")); + set_damage_region_ = reinterpret_cast( + glGetProcAddress("eglSetDamageRegionKHR")); + } + + if (HasExtension(extensions, "EGL_EXT_swap_buffers_with_damage")) { + swap_buffers_with_damage_ = reinterpret_cast( + eglGetProcAddress("eglSwapBuffersWithDamageEXT")); + } else if (HasExtension(extensions, "EGL_KHR_swap_buffers_with_damage")) { + swap_buffers_with_damage_ = reinterpret_cast( + eglGetProcAddress("eglSwapBuffersWithDamageKHR")); } - // ohos 暂没公开拓展,但支持接口调用 - swap_buffers_with_damage_ = - reinterpret_cast( - eglGetProcAddress("eglSwapBuffersWithDamageKHR")); partial_redraw_supported_ = set_damage_region_ != nullptr && swap_buffers_with_damage_ != nullptr; diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index bf65b2252ee32a708afe16d495c2a0f3c989d361..11adce38020cbd629613ea03d9aa4073523d4749 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -23,8 +23,6 @@ #include "flutter/shell/platform/ohos/ohos_surface_software.h" #include "flutter/shell/platform/ohos/platform_message_response_ohos.h" #include "napi_common.h" -#include "ohos_context_gl_impeller.h" -#include "ohos_surface_gl_impeller.h" #include "ohos_external_texture_gl.h" #include @@ -44,7 +42,8 @@ std::unique_ptr OhosSurfaceFactoryImpl::CreateSurface() { return std::make_unique(ohos_context_); case OHOSRenderingAPI::kOpenGLES: if (enable_impeller_) { - return std::make_unique(ohos_context_); + FML_LOG(ERROR) << "It does not support Impeller."; + return nullptr; } else { FML_LOG(INFO) << "OhosSurfaceFactoryImpl::OhosSurfaceGLSkia "; return std::make_unique(ohos_context_); @@ -64,7 +63,8 @@ std::unique_ptr CreateOHOSContext( return std::make_unique(OHOSRenderingAPI::kSoftware); } if (enable_impeller) { - return std::make_unique(); + FML_LOG(ERROR) << "It does not support Impeller."; + return nullptr; } return std::make_unique(