From 584ade22a010b87fbfc626614584572981bb4918 Mon Sep 17 00:00:00 2001 From: 18719058668 <718092089@qq.com> Date: Mon, 26 Feb 2024 15:35:14 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=A4=96=E6=8E=A5=E7=BA=B9=E7=90=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BDets=E5=B1=82=E5=90=88=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 18719058668 <718092089@qq.com> --- .../src/main/cpp/types/libflutter/index.d.ets | 10 +- .../ets/embedding/engine/FlutterEngine.ets | 15 +- .../FlutterEngineConnectionRegistry.ets | 2 +- .../main/ets/embedding/engine/FlutterNapi.ets | 20 +++ .../embedding/engine/loader/FlutterLoader.ets | 6 +- .../engine/plugins/FlutterPlugin.ets | 9 +- .../engine/renderer/FlutterRenderer.ets | 138 ++++++++++++++++++ .../engine/renderer/SurfaceTextureWrapper.ets | 30 ++++ .../ets/embedding/ohos/FlutterAbility.ets | 4 + .../ohos/FlutterAbilityAndEntryDelegate.ets | 4 + .../plugin/common/StandardMessageCodec.ets | 2 +- .../src/main/ets/view/TextureRegistry.ets | 20 ++- 12 files changed, 248 insertions(+), 12 deletions(-) create mode 100644 shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/FlutterRenderer.ets create mode 100644 shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/SurfaceTextureWrapper.ets diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets index c53957c7aa..6cb09bd9f0 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets @@ -99,4 +99,12 @@ export const nativeXComponentDetachFlutterEngine: (xcomponentId: number, nativeS */ export const nativeDestroy: ( nativeShellHolderId: number -) => void; \ No newline at end of file +) => void; + +export const nativeInitNativeImage: (nativeShellHolderId: number, textureId: number, aImage: image.Image) => void; + +export const nativeUnregisterTexture: (nativeShellHolderId: number, textureId: number) => void; + +export const nativeRegisterPixelMap: (nativeShellHolderId: number, textureId: number, pixelMap: PixelMap) => void; + +export const nativeRegisterTexture: (nativeShellHolderId: number, textureId: number) => number; \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets index 880e9bc785..b99be906f1 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets @@ -42,7 +42,7 @@ import PlatformViewsController from '../../plugin/platform/PlatformViewsControll import { FlutterPlugin } from './plugins/FlutterPlugin'; import List from '@ohos.util.List'; import GeneratedPluginRegister from './plugins/util/GeneratedPluginRegister'; - +import { FlutterRenderer } from './renderer/FlutterRenderer'; const TAG = "FlutterEngine"; @@ -68,6 +68,7 @@ export default class FlutterEngine implements EngineLifecycleListener{ private accessibilityChannel: AccessibilityChannel | null = null; private localeChannel: LocalizationChannel | null = null; private flutterNapi: FlutterNapi; + private renderer: FlutterRenderer; private pluginRegistry: FlutterEngineConnectionRegistry | null = null; private textInputPlugin: TextInputPlugin | null = null; private localizationPlugin: LocalizationPlugin | null = null; @@ -99,6 +100,8 @@ export default class FlutterEngine implements EngineLifecycleListener{ } this.flutterLoader = flutterLoader; + this.renderer = new FlutterRenderer(this.flutterNapi); + if(platformViewsController == null) { platformViewsController = new PlatformViewsController(); } @@ -141,6 +144,8 @@ export default class FlutterEngine implements EngineLifecycleListener{ if (automaticallyRegisterPlugins && plugins) { GeneratedPluginRegister.registerGeneratedPlugins(this, plugins); } + + Log.d(TAG, "Call init finished.") } private attachToNapi(): void { @@ -218,6 +223,10 @@ export default class FlutterEngine implements EngineLifecycleListener{ return this.flutterNapi; } + getFlutterRenderer(): FlutterRenderer { + return this.renderer; + } + getDartExecutor(): DartExecutor { return this.dartExecutor } @@ -234,6 +243,10 @@ export default class FlutterEngine implements EngineLifecycleListener{ return this.settingsChannel; } + getFlutterLoader() { + return this.flutterLoader; + } + onPreEngineRestart(): void { } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets index be25395a31..90044b0dfc 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets @@ -55,7 +55,7 @@ export default class FlutterEngineConnectionRegistry implements PluginRegistry, constructor(appContext: common.Context, flutterEngine: FlutterEngine, flutterLoader: FlutterLoader) { this.flutterEngine = flutterEngine; - this.pluginBinding = new FlutterPluginBinding(appContext, flutterEngine, flutterEngine.getDartExecutor(), new DefaultFlutterAssets(flutterLoader), flutterEngine.getPlatformViewsController()?.getRegistry()); + this.pluginBinding = new FlutterPluginBinding(appContext, flutterEngine, flutterEngine.getDartExecutor(), new DefaultFlutterAssets(flutterLoader), flutterEngine.getFlutterRenderer(), flutterEngine.getPlatformViewsController()?.getRegistry()); } add(plugin: FlutterPlugin): void { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets index 4b8d9a3a54..271ec23e6e 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets @@ -373,6 +373,26 @@ export default class FlutterNapi { detachFromNativeAndReleaseResources() { flutter.nativeDestroy(this.nativeShellHolderId!!); } + + initNativeImage(textureId: number, aImage: image.Image) { + Log.d(TAG, "called initNativeImage "); + flutter.nativeInitNativeImage(this.nativeShellHolderId!, textureId, aImage); + } + + unregisterTexture(textureId: number): void { + Log.d(TAG, "called unregisterTexture "); + flutter.nativeUnregisterTexture(this.nativeShellHolderId!, textureId); + } + + registerPixelMap(textureId: number, pixelMap: PixelMap): void { + Log.d(TAG, "called registerPixelMap "); + flutter.nativeRegisterPixelMap(this.nativeShellHolderId!, textureId, pixelMap); + } + + registerTexture(textureId: number): number { + Log.d(TAG, "called unregisterTexture "); + return flutter.nativeRegisterTexture(this.nativeShellHolderId!, textureId); + } } export interface AccessibilityDelegate { 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 89e7cf3264..2317af9f61 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 @@ -170,7 +170,6 @@ export default class FlutterLoader { if (this.initialized) { return; } - Log.d(TAG, "ensureInitializationComplete") if (shellArgs == null) { shellArgs = new Array(); } @@ -231,6 +230,7 @@ export default class FlutterLoader { costTime ); this.initialized = true; + Log.d(TAG, "ensureInitializationComplete") } findAppBundlePath(): string { @@ -274,6 +274,10 @@ export default class FlutterLoader { }) : new Array(); } + isInitialized(): boolean { + return this.initialized; + } + } class InitResult { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets index 1b8ea40a05..92e08f8dd9 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets @@ -17,6 +17,7 @@ import common from '@ohos.app.ability.common'; import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; import PlatformViewFactory from '../../../plugin/platform/PlatformViewFactory'; import PlatformViewRegistry from '../../../plugin/platform/PlatformViewRegistry'; +import { TextureRegistry } from '../../../view/TextureRegistry'; import FlutterEngine from '../FlutterEngine'; export interface FlutterPlugin { @@ -52,13 +53,15 @@ export class FlutterPluginBinding { private flutterEngine: FlutterEngine; private binaryMessenger: BinaryMessenger; private flutterAssets: FlutterAssets; + private textureRegistry: TextureRegistry; private platformViewRegistry: PlatformViewRegistry; - constructor(applicationContext: common.Context, flutterEngine: FlutterEngine, binaryMessenger: BinaryMessenger, flutterAssets: FlutterAssets, platformViewRegistry?: PlatformViewRegistry) { + constructor(applicationContext: common.Context, flutterEngine: FlutterEngine, binaryMessenger: BinaryMessenger, flutterAssets: FlutterAssets, textureRegistry: TextureRegistry, platformViewRegistry?: PlatformViewRegistry) { this.applicationContext = applicationContext; this.flutterEngine = flutterEngine; this.binaryMessenger = binaryMessenger; this.flutterAssets = flutterAssets; + this.textureRegistry = textureRegistry; this.platformViewRegistry = platformViewRegistry ?? new EmptyPlatformViewRegistry(); } @@ -78,6 +81,10 @@ export class FlutterPluginBinding { return this.flutterAssets; } + getTextureRegistry(): TextureRegistry { + return this.textureRegistry; + } + public getPlatformViewRegistry(): PlatformViewRegistry { return this.platformViewRegistry; } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/FlutterRenderer.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/FlutterRenderer.ets new file mode 100644 index 0000000000..e31ee486f5 --- /dev/null +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/FlutterRenderer.ets @@ -0,0 +1,138 @@ +/* +* 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 image from '@ohos.multimedia.image'; +import { BusinessError } from '@ohos.base'; +import { SurfaceTextureEntry, TextureRegistry } from '../../../view/TextureRegistry'; +import { FlutterAbility } from '../../ohos/FlutterAbility'; +import FlutterNapi from '../FlutterNapi'; +import { SurfaceTextureWrapper } from './SurfaceTextureWrapper'; +import Log from '../../../util/Log'; + +const TAG = "FlutterRenderer" +export class FlutterRenderer implements TextureRegistry { + private nextTextureId: number = 0; + private flutterNapi: FlutterNapi; + + constructor(flutterNapi: FlutterNapi) { + this.flutterNapi = flutterNapi; + } + createSurfaceTexture(): SurfaceTextureEntry { + let receiver: image.ImageReceiver = this.getImageReceiver(); + return this.registerSurfaceTexture(receiver); + } + + getTextureId(): number { + this.nextTextureId = this.nextTextureId + 1; + Log.i(TAG, "getTextureId: ", this.nextTextureId ) + return this.nextTextureId; + } + + registerTexture(textureId: number): SurfaceTextureEntry { + let surfaceTextureRegistryEntry = new SurfaceTextureRegistryEntry(this.nextTextureId); + let surfaceId = this.flutterNapi.registerTexture(textureId); + Log.i(TAG, "registerTexture, surfaceId=" + surfaceId); + surfaceTextureRegistryEntry.setSurfaceId(surfaceId); + return surfaceTextureRegistryEntry; + } + + registerSurfaceTexture(receiver: image.ImageReceiver): SurfaceTextureEntry { + this.nextTextureId = this.nextTextureId + 1; + let surfaceTextureRegistryEntry = new SurfaceTextureRegistryEntry(this.nextTextureId); + surfaceTextureRegistryEntry.setImageReceiver(receiver); + this.registerImage(surfaceTextureRegistryEntry.getTextureId(), surfaceTextureRegistryEntry.textureWrapper()); + return surfaceTextureRegistryEntry; + } + + registerPixelMap(pixelMap: PixelMap): number { + let textureId = this.nextTextureId + 1; + this.flutterNapi.registerPixelMap(textureId, pixelMap); + return textureId; + } + + unregisterTexture(textureId: number): void { + this.flutterNapi.unregisterTexture(textureId); + } + onTrimMemory(level: number) { + throw new Error('Method not implemented.'); + } + + private getImageReceiver(): image.ImageReceiver { + let receiver: image.ImageReceiver = image.createImageReceiver(640, 480, 4, 8); + if (receiver !== undefined) { + console.info('[camera test] ImageReceiver is ok'); + } else { + console.info('[camera test] ImageReceiver is not ok'); + } + return receiver; + } + private registerImage(textureId: number, surfaceTextureWrapper: SurfaceTextureWrapper): void { + let receiver = surfaceTextureWrapper.getImageReceiver(); + receiver.on('imageArrival', () => { + receiver.readNextImage((err: BusinessError, nextImage: image.Image) => { + if (err || nextImage === undefined) { + return; + } + this.flutterNapi.initNativeImage(textureId, nextImage); + console.log("[camera test] format: " + nextImage.format); + nextImage.release((err : BusinessError) =>{ + if (err != undefined) { + console.log('Failed to release the image source instance.'); + } else { + console.log('Succeeded in releasing the image source instance.'); + } + }); + }) + }) + } +} + +export class SurfaceTextureRegistryEntry implements SurfaceTextureEntry { + private textureId: number = 0; + private surfaceId: number = 0; + private surfaceTextureWrapper: SurfaceTextureWrapper | null = null; + private released: boolean = false; + + constructor(id: number) { + this.textureId = id; + } + + getImageReceiver(): image.ImageReceiver { + return this.surfaceTextureWrapper!.getImageReceiver(); + } + + setImageReceiver(receiver: image.ImageReceiver): void { + this.surfaceTextureWrapper = new SurfaceTextureWrapper(receiver); + } + + getTextureId(): number { + return this.textureId; + } + + getSurfaceId(): number { + return this.surfaceId; + } + + setSurfaceId(surfaceId: number): void { + this.surfaceId = surfaceId; + } + + textureWrapper(): SurfaceTextureWrapper { + return this.surfaceTextureWrapper!; + } + release() { + throw new Error('Method not implemented.'); + } +} \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/SurfaceTextureWrapper.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/SurfaceTextureWrapper.ets new file mode 100644 index 0000000000..b1da18061b --- /dev/null +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/renderer/SurfaceTextureWrapper.ets @@ -0,0 +1,30 @@ +/* + * 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 image from '@ohos.multimedia.image'; + +export class SurfaceTextureWrapper { + private receiver: image.ImageReceiver; + private released: boolean = false; + private attached: boolean = false; + + constructor(receiver: image.ImageReceiver) { + this.receiver = receiver; + } + + getImageReceiver(): image.ImageReceiver { + return this.receiver; + } +} \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets index a5869a3cbf..7c63ef9873 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -208,6 +208,10 @@ export class FlutterAbility extends UIAbility implements Host { return this; } + getFlutterAbilityAndEntryDelegate(): FlutterAbilityAndEntryDelegate | null{ + return this.delegate ?? null; + } + shouldDispatchAppLifecycleState(): boolean { return true; } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets index df276bd2e5..baf4d2e3da 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityAndEntryDelegate.ets @@ -403,6 +403,10 @@ class FlutterAbilityAndEntryDelegate implements ExclusiveAppComponent return this.flutterEngine?.getFlutterNapi() ?? null } + getFlutterEngine(): FlutterEngine | null { + return this.flutterEngine ?? null; + } + detachFromFlutterEngine() { if (this.host?.shouldDestroyEngineWithHost()) { // The host owns the engine and should never have its engine taken by another exclusive diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/common/StandardMessageCodec.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/common/StandardMessageCodec.ets index df27a12328..8e740f95fd 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/common/StandardMessageCodec.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/plugin/common/StandardMessageCodec.ets @@ -339,7 +339,7 @@ export default class StandardMessageCodec implements MessageCodec { break; } default: - throw new Error("Message corrupted"); + throw new Error("Message corrupted, type=" + type); } return result; } diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/TextureRegistry.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/TextureRegistry.ets index a37ab971b7..fa79eb238c 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/TextureRegistry.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/view/TextureRegistry.ets @@ -12,25 +12,33 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import image from '@ohos.multimedia.image'; export interface TextureRegistry { createSurfaceTexture(): SurfaceTextureEntry; - registerSurfaceTexture(): SurfaceTextureEntry; - + getTextureId(): number; + registerTexture(textureId: number): SurfaceTextureEntry; + registerSurfaceTexture(receiver: image.ImageReceiver): SurfaceTextureEntry; + registerPixelMap(pixelMap: PixelMap): number; + unregisterTexture(textureId: number): void; onTrimMemory(level: number) : void; } -interface SurfaceTextureEntry { - id(): number; +export interface SurfaceTextureEntry { + getTextureId(): number; + + getSurfaceId(): number; + + getImageReceiver(): image.ImageReceiver; release(): void; } -interface OnFrameConsumedListener { +export interface OnFrameConsumedListener { onFrameConsumed(): void; } -interface OnTrimMemoryListener { +export interface OnTrimMemoryListener { onTrimMemory(level: number) : void; } \ No newline at end of file -- Gitee From 775833ff9fcae8184e682b057411ad193557caf5 Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Mon, 26 Feb 2024 15:17:37 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=A4=96=E6=8E=A5=E7=BA=B9=E7=90=86engine?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- shell/platform/ohos/BUILD.gn | 3 + shell/platform/ohos/library_loader.cpp | 17 ++ .../ohos/napi/platform_view_ohos_napi.cpp | 79 +++++- .../ohos/napi/platform_view_ohos_napi.h | 15 ++ .../ohos/ohos_external_texture_gl.cpp | 228 ++++++++++++++++-- .../platform/ohos/ohos_external_texture_gl.h | 45 +++- shell/platform/ohos/ohos_unified_surface.cpp | 22 ++ shell/platform/ohos/ohos_unified_surface.h | 80 ++++++ shell/platform/ohos/platform_view_ohos.cpp | 96 ++++++++ shell/platform/ohos/platform_view_ohos.h | 30 +++ 10 files changed, 596 insertions(+), 19 deletions(-) create mode 100644 shell/platform/ohos/ohos_unified_surface.cpp create mode 100644 shell/platform/ohos/ohos_unified_surface.h diff --git a/shell/platform/ohos/BUILD.gn b/shell/platform/ohos/BUILD.gn index f60b29c347..7b888c0d6e 100644 --- a/shell/platform/ohos/BUILD.gn +++ b/shell/platform/ohos/BUILD.gn @@ -225,6 +225,9 @@ shared_library("flutter_shell_native") { ldflags += ["-lrawfile.z"] ldflags += ["-lEGL"] ldflags += ["-lGLESv3"] + # ldflags += ["-lGLESv2"] + ldflags += ["-limage_ndk.z"] + ldflags += ["-lnative_image"] ldflags += ["-lc++_shared"] ldflags += ["-lm"] diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index 6e38f769bc..f6c52a6aff 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -107,8 +107,25 @@ static napi_value Init(napi_env env, napi_value exports) { DECLARE_NAPI_FUNCTION( "nativeXComponentDetachFlutterEngine", flutter::PlatformViewOHOSNapi::nativeXComponentDetachFlutterEngine), + DECLARE_NAPI_FUNCTION( + "nativeInitNativeImage", + flutter::PlatformViewOHOSNapi::nativeInitNativeImage), + DECLARE_NAPI_FUNCTION( + "nativeRegisterTexture", + flutter::PlatformViewOHOSNapi::nativeRegisterTexture), + DECLARE_NAPI_FUNCTION( + "nativeUnregisterTexture", + flutter::PlatformViewOHOSNapi::nativeUnregisterTexture), + DECLARE_NAPI_FUNCTION( + "nativeMarkTextureFrameAvailable", + flutter::PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable), + DECLARE_NAPI_FUNCTION( + "nativeRegisterPixelMap", + flutter::PlatformViewOHOSNapi::nativeRegisterPixelMap), }; + + FML_DLOG(INFO) << "Init NAPI size=" << sizeof(desc) / sizeof(desc[0]); napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); bool ret = flutter::XComponentAdapter::GetInstance()->Export(env, exports); if (!ret) { diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 3572bee972..848ac957d7 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -27,6 +27,9 @@ #include "flutter/shell/platform/ohos/surface/ohos_native_window.h" #include "unicode/uchar.h" #include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" +#include +#include +#include #define OHOS_SHELL_HOLDER (reinterpret_cast(shell_holder)) namespace flutter { @@ -303,7 +306,7 @@ void PlatformViewOHOSNapi::FlutterViewHandlePlatformMessage( FML_DLOG(ERROR) << "napi_create_string_utf8 err " << status; return; } - + FML_DLOG(INFO) << "FlutterViewHandlePlatformMessage mapData= " << mapData; if (mapData) { delete mapData; } @@ -1419,6 +1422,80 @@ napi_value PlatformViewOHOSNapi::nativeGetSystemLanguages( return nullptr; } +napi_value PlatformViewOHOSNapi::nativeInitNativeImage( + napi_env env, + napi_callback_info info) { + FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeInitNativeImage"; + size_t argc = 3; + napi_value args[3] = {nullptr}; + int64_t shell_holder, textureId; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); + NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); + ImageNative *imageNative = OH_Image_InitImageNative(env, args[2]); + // std::unique_ptr uImage; + OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTextureByImage(textureId, imageNative); + return nullptr; +} + +napi_value PlatformViewOHOSNapi::nativeRegisterTexture(napi_env env, + napi_callback_info info) +{ + FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterTexture"; + size_t argc = 2; + napi_value args[2] = {nullptr}; + int64_t shell_holder, textureId; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); + NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); + int64_t surfaceId = OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTexture(textureId); + napi_value res; + napi_create_int64(env, surfaceId, &res); + return res; +} + +napi_value PlatformViewOHOSNapi::nativeUnregisterTexture( + napi_env env, napi_callback_info info) +{ + FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeUnregisterTexture"; + size_t argc = 2; + napi_value args[2] = {nullptr}; + int64_t shell_holder, textureId; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); + NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); + OHOS_SHELL_HOLDER->GetPlatformView()->UnRegisterExternalTexture(textureId); + return nullptr; +} + +napi_value PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable( + napi_env env, napi_callback_info info) +{ + size_t argc = 2; + napi_value args[2] = {nullptr}; + int64_t shell_holder, textureId; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); + NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); + OHOS_SHELL_HOLDER->GetPlatformView()->MarkTextureFrameAvailable(textureId); + return nullptr; +} + +napi_value PlatformViewOHOSNapi::nativeRegisterPixelMap(napi_env env, + napi_callback_info info) +{ + FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterPixelMap"; + size_t argc = 3; + napi_value args[3] = {nullptr}; + int64_t shell_holder, textureId; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); + NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); + NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); + NativePixelMap *nativePixelMap = OH_PixelMap_InitNativePixelMap(env, args[2]); + OHOS_SHELL_HOLDER->GetPlatformView()->RegisterExternalTextureByPixelMap(textureId, nativePixelMap); + return nullptr; +} + void PlatformViewOHOSNapi::SurfaceCreated(int64_t shell_holder, void* window) { auto native_window = fml::MakeRefCounted( static_cast(window)); diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index 1e83a43017..8339308b00 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -143,6 +143,21 @@ class PlatformViewOHOSNapi { napi_env env, napi_callback_info info); // 应用下发系统语言设置 + static napi_value nativeInitNativeImage(napi_env env, + napi_callback_info info); + + static napi_value nativeUnregisterTexture(napi_env env, + napi_callback_info info); + + static napi_value nativeMarkTextureFrameAvailable(napi_env env, + napi_callback_info info); + + static napi_value nativeRegisterPixelMap(napi_env env, + napi_callback_info info); + + static napi_value nativeRegisterTexture(napi_env env, + napi_callback_info info); + // Surface相关,XComponent调用 static void SurfaceCreated(int64_t shell_holder, void* window); static void SurfaceChanged(int64_t shell_holder, diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index f2ffccbaa8..7533b43364 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -14,7 +14,6 @@ */ #include "ohos_external_texture_gl.h" -#include #include @@ -25,13 +24,33 @@ #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" +#include +#include + +#define EGL_PLATFORM_OHOS_KHR 0x34E0 + namespace flutter { +using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC; +constexpr char CHARACTER_WHITESPACE = ' '; +constexpr const char *CHARACTER_STRING_WHITESPACE = " "; +constexpr const char *EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland"; +constexpr const char *EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland"; +constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT"; -OHOSExternalTextureGL::OHOSExternalTextureGL(int id) - : Texture(id), transform(SkMatrix::I()) {} +OHOSExternalTextureGL::OHOSExternalTextureGL(int64_t id, const std::shared_ptr& ohos_surface) + : Texture(id), ohos_surface_(std::move(ohos_surface)), transform(SkMatrix::I()) { + nativeImage_ = nullptr; + nativeWindow_ = nullptr; + eglContext_ = EGL_NO_CONTEXT; + eglDisplay_ = EGL_NO_DISPLAY; + buffer_ = nullptr; + pixelMap_ = nullptr; + lastImage_ = nullptr; +} OHOSExternalTextureGL::~OHOSExternalTextureGL() { if (state_ == AttachmentState::attached) { + glDeleteTextures(1, &texture_name_); } } @@ -40,17 +59,46 @@ void OHOSExternalTextureGL::Paint(PaintContext& context, bool freeze, const SkSamplingOptions& sampling) { if (state_ == AttachmentState::detached) { + FML_DLOG(ERROR) << "OHOSExternalTextureGL::Paint"; return; } if (state_ == AttachmentState::uninitialized) { - Attach(static_cast(texture_name_)); - state_ = AttachmentState::attached; + OHOSSurface* ohos_surface_ptr = ohos_surface_.get(); + OhosSurfaceGLSkia* ohosSurfaceGLSkia_ = (OhosSurfaceGLSkia*)ohos_surface_ptr; + auto result = ohosSurfaceGLSkia_->GLContextMakeCurrent(); + if (result->GetResult()) { + FML_DLOG(INFO)<<"ResourceContextMakeCurrent successed"; + glGenTextures(1, &texture_name_); + FML_DLOG(INFO) << "OHOSExternalTextureGL::Paint, glGenTextures texture_name_=" << texture_name_; + if (nativeImage_ == nullptr) { + nativeImage_ = OH_NativeImage_Create(texture_name_, GL_TEXTURE_EXTERNAL_OES); + if (nativeImage_ == nullptr) { + FML_DLOG(ERROR) << "Error with OH_NativeImage_Create"; + return; + } + nativeWindow_ = OH_NativeImage_AcquireNativeWindow(nativeImage_); + if (nativeWindow_ == nullptr) { + FML_DLOG(ERROR) << "Error with OH_NativeImage_AcquireNativeWindow"; + return; + } + } + + int32_t ret = OH_NativeImage_AttachContext(nativeImage_, texture_name_); + if(ret != 0) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeImage_AttachContext err code:"<< ret; + } + state_ = AttachmentState::attached; + } else { + FML_DLOG(FATAL)<<"ResourceContextMakeCurrent failed"; + } } if (!freeze && new_frame_ready_) { Update(); new_frame_ready_ = false; } - GrGLTextureInfo textureInfo = {0, texture_name_, GL_RGBA8_OES}; + + GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_, + GL_RGBA8_OES}; GrBackendTexture backendTexture(1, 1, GrMipMapped::kNo, textureInfo); sk_sp image = SkImage::MakeFromTexture( context.gr_context, backendTexture, kTopLeft_GrSurfaceOrigin, @@ -61,8 +109,8 @@ void OHOSExternalTextureGL::Paint(PaintContext& context, // The incoming texture is vertically flipped, so we flip it // back. OpenGL's coordinate system has Positive Y equivalent to up, while // Skia's coordinate system has Negative Y equvalent to up. - context.canvas->translate(bounds.x(), bounds.y() + bounds.height()); - context.canvas->scale(bounds.width(), -bounds.height()); + context.canvas->translate(bounds.x(), bounds.y()); + context.canvas->scale(bounds.width(), bounds.height()); if (!transform.isIdentity()) { sk_sp shader = image->makeShader( @@ -81,41 +129,193 @@ void OHOSExternalTextureGL::Paint(PaintContext& context, } void OHOSExternalTextureGL::OnGrContextCreated() { + FML_DLOG(INFO)<<" OHOSExternalTextureGL::OnGrContextCreated"; state_ = AttachmentState::uninitialized; } void OHOSExternalTextureGL::OnGrContextDestroyed() { + FML_DLOG(INFO)<<" OHOSExternalTextureGL::OnGrContextDestroyed"; if (state_ == AttachmentState::attached) { Detach(); + glDeleteTextures(1, &texture_name_); + OH_NativeImage_Destroy(&nativeImage_); } state_ = AttachmentState::detached; } void OHOSExternalTextureGL::MarkNewFrameAvailable() { + FML_DLOG(INFO)<<" OHOSExternalTextureGL::MarkNewFrameAvailable"; new_frame_ready_ = true; } void OHOSExternalTextureGL::OnTextureUnregistered() { - // do nothing -} - -void OHOSExternalTextureGL::Attach(int textureName) { + FML_DLOG(INFO)<<" OHOSExternalTextureGL::OnTextureUnregistered"; // do nothing } void OHOSExternalTextureGL::Update() { + ProducePixelMapToNativeImage(); + int32_t ret = OH_NativeImage_UpdateSurfaceImage(nativeImage_); + if (ret != 0) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeImage_UpdateSurfaceImage err code:"<< ret; + } UpdateTransform(); } void OHOSExternalTextureGL::Detach() { - // do nothing + OH_NativeImage_DetachContext(nativeImage_); + OH_NativeWindow_DestroyNativeWindow(nativeWindow_); } void OHOSExternalTextureGL::UpdateTransform() { + float m[16] = { 0.0f }; + int32_t ret = OH_NativeImage_GetTransformMatrix(nativeImage_, m); + if(ret != 0) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeImage_GetTransformMatrix err code:"<< ret; + } + // transform ohos 4x4 matrix to skia 3x3 matrix + FML_DLOG(INFO)<<"OHOSExternalTextureGL::UpdateTransform "<virAddr, handle->size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0); + if (mappedAddr == MAP_FAILED) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL mmap failed"; + return; + } + + void *pixelAddr = nullptr; + ret = OH_PixelMap_AccessPixels(pixelMap_, &pixelAddr); + if (ret != IMAGE_RESULT_SUCCESS) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_PixelMap_AccessPixels err:"<< ret; + return; + } + + uint32_t *value = static_cast(pixelAddr); + uint32_t *pixel = static_cast(mappedAddr); + uint32_t rowDataSize = 256; // DMA内存会自动补齐,分配内存时是 256 的整数倍 + while (rowDataSize < pixelMapInfo.rowSize) { + rowDataSize += 256; + } + + FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo w:" << pixelMapInfo.width << " h:" << pixelMapInfo.height; + FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo rowSize:" << pixelMapInfo.rowSize << " format:" << pixelMapInfo.pixelFormat; + FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo rowDataSize:" << rowDataSize; + + // 复制图片纹理数据到内存中,需要处理DMA内存补齐相关的逻辑 + for (uint32_t i = 0; i < pixelMapInfo.height; i++) { + memcpy(pixel, value, rowDataSize); + pixel += rowDataSize / 4; + value += pixelMapInfo.width; + } + + OH_PixelMap_UnAccessPixels(pixelMap_); + //munmap after use + ret = munmap(mappedAddr, handle->size); + if (ret == -1) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL munmap failed"; + return; + } + Region region{nullptr, 0}; + ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer_, fenceFd, region); + if(ret != 0) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeWindow_NativeWindowFlushBuffer err:"<< ret; + } +} + +EGLDisplay OHOSExternalTextureGL::GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list) +{ + GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL; + + if (!eglGetPlatformDisplayExt) { + const char* extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if (extensions && + (CheckEglExtension(extensions, EGL_EXT_PLATFORM_WAYLAND) || + CheckEglExtension(extensions, EGL_KHR_PLATFORM_WAYLAND))) { + eglGetPlatformDisplayExt = (GetPlatformDisplayExt)eglGetProcAddress(EGL_GET_PLATFORM_DISPLAY_EXT); + } + } + + if (eglGetPlatformDisplayExt) { + return eglGetPlatformDisplayExt(platform, native_display, attrib_list); + } + + return eglGetDisplay((EGLNativeDisplayType)native_display); +} + +bool OHOSExternalTextureGL::CheckEglExtension(const char *extensions, const char *extension) +{ + size_t extlen = strlen(extension); + const char *end = extensions + strlen(extensions); + while (extensions < end) { + size_t n = 0; + if (*extensions == CHARACTER_WHITESPACE) { + extensions++; + continue; + } + n = strcspn(extensions, CHARACTER_STRING_WHITESPACE); + if (n == extlen && strncmp(extension, extensions, n) == 0) { + return true; + } + extensions += n; + } + return false; +} + +void OHOSExternalTextureGL::DispatchPixelMap(NativePixelMap* pixelMap) +{ + if(pixelMap != nullptr) { + pixelMap_ = pixelMap; + } +} + } // namespace flutter \ No newline at end of file diff --git a/shell/platform/ohos/ohos_external_texture_gl.h b/shell/platform/ohos/ohos_external_texture_gl.h index aa08880048..0e900e60a4 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.h +++ b/shell/platform/ohos/ohos_external_texture_gl.h @@ -15,20 +15,32 @@ #ifndef OHOS_EXTERNAL_TEXTURE_GL_H #define OHOS_EXTERNAL_TEXTURE_GL_H -#include + +#include +#include +#include #include "flutter/common/graphics/texture.h" +#include "flutter/shell/platform/ohos/surface/ohos_surface.h" +#include "flutter/shell/platform/ohos/ohos_surface_gl_skia.h" #include "napi/platform_view_ohos_napi.h" +#include +#include +#include +#include +#include // maybe now unused namespace flutter { class OHOSExternalTextureGL : public flutter::Texture { public: - explicit OHOSExternalTextureGL(int id); + explicit OHOSExternalTextureGL(int64_t id, const std::shared_ptr& ohos_surface); ~OHOSExternalTextureGL() override; + OH_NativeImage *nativeImage_; + void Paint(PaintContext& context, const SkRect& bounds, bool freeze, @@ -42,15 +54,23 @@ class OHOSExternalTextureGL : public flutter::Texture { void OnTextureUnregistered() override; - private: - void Attach(int textureName); + void DispatchImage(ImageNative* image); + + void DispatchPixelMap(NativePixelMap* pixelMap); + private: void Update(); void Detach(); void UpdateTransform(); + EGLDisplay GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list); + + bool CheckEglExtension(const char *extensions, const char *extension); + + void ProducePixelMapToNativeImage(); + enum class AttachmentState { uninitialized, attached, detached }; AttachmentState state_ = AttachmentState::uninitialized; @@ -59,8 +79,25 @@ class OHOSExternalTextureGL : public flutter::Texture { GLuint texture_name_ = 0; + std::shared_ptr ohos_surface_; + SkMatrix transform; + OHNativeWindow *nativeWindow_; + + OHNativeWindowBuffer *buffer_; + + NativePixelMap* pixelMap_; + + ImageNative* lastImage_; + + OhosPixelMapInfos pixelMapInfo; + + int fenceFd = -1; + + EGLContext eglContext_; + EGLDisplay eglDisplay_; + FML_DISALLOW_COPY_AND_ASSIGN(OHOSExternalTextureGL); }; } // namespace flutter diff --git a/shell/platform/ohos/ohos_unified_surface.cpp b/shell/platform/ohos/ohos_unified_surface.cpp new file mode 100644 index 0000000000..73c3a0c954 --- /dev/null +++ b/shell/platform/ohos/ohos_unified_surface.cpp @@ -0,0 +1,22 @@ +/* + * 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. + */ + +#include "flutter/shell/platform/ohos/ohos_unified_surface.h" +namespace flutter { + +OHOSUnifiedSurface::OHOSUnifiedSurface() {} + + +} // namespace flutter \ No newline at end of file diff --git a/shell/platform/ohos/ohos_unified_surface.h b/shell/platform/ohos/ohos_unified_surface.h new file mode 100644 index 0000000000..49aa35a3d6 --- /dev/null +++ b/shell/platform/ohos/ohos_unified_surface.h @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#ifndef OHOS_UNIFIED_SURFACE_H +#define OHOS_UNIFIED_SURFACE_H + +#include +#include "flutter/flow/surface.h" +#include "flutter/shell/platform/ohos/context/ohos_context.h" +#include "flutter/shell/platform/ohos/surface/ohos_native_window.h" +#include "flutter/shell/platform/ohos/surface/ohos_surface.h" +#include "flutter/shell/platform/ohos/ohos_surface_gl_skia.h" +#include "third_party/skia/include/core/SkSize.h" + +namespace flutter { + +class OHOSUnifiedSurface : public GPUSurfaceGLDelegate, + public OHOSSurface { + public: + ~OHOSUnifiedSurface() {} + bool IsValid() {} + void TeardownOnScreenContext() {} + + bool OnScreenSurfaceResize(const SkISize& size) {} + + bool ResourceContextMakeCurrent() {} + + bool ResourceContextClearCurrent() {} + + bool SetNativeWindow(fml::RefPtr window) {} + + std::unique_ptr CreateSnapshotSurface() + + std::unique_ptr CreateGPUSurface( + GrDirectContext* gr_context = nullptr) {} + + std::shared_ptr GetImpellerContext() {} + + std::unique_ptr GLContextMakeCurrent() {} + + bool GLContextClearCurrent() {} + + void GLContextSetDamageRegion(const std::optional& region) {} + + bool GLContextPresent(const GLPresentInfo& present_info) {} + + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) {} + + bool GLContextFBOResetAfterPresent() {} + + SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() {} + + SkMatrix GLContextSurfaceTransformation() {} + + sk_sp GetGLInterface() {} + + static sk_sp GetDefaultPlatformGLInterface() {} + + using GLProcResolver = + std::function; + + GLProcResolver GetGLProcResolver() {} + + bool AllowsDrawingWhenGpuDisabled() {} +}; +} // namespace flutter + +#endif \ No newline at end of file diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index b0a382254a..19f45611cf 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -25,6 +25,9 @@ #include "napi_common.h" #include "ohos_context_gl_impeller.h" #include "ohos_surface_gl_impeller.h" +#include "ohos_external_texture_gl.h" + +#include namespace flutter { @@ -387,4 +390,97 @@ void PlatformViewOHOS::FireFirstFrameCallback() { napi_facade_->FlutterViewOnFirstFrame(); } +void PlatformViewOHOS::RegisterExternalTextureByImage( + int64_t texture_id, + ImageNative* image) { + if(ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { + auto iter = external_texture_gl_.find(texture_id); + if(iter != external_texture_gl_.end()) { + iter->second->DispatchImage(image); + } else { + std::shared_ptr ohos_external_gl = std::make_shared(texture_id, ohos_surface_); + external_texture_gl_[texture_id] = ohos_external_gl; + RegisterTexture(ohos_external_gl); + ohos_external_gl->DispatchImage(image); + } + } +} + +uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) { + uint64_t surface_id = 0; + int ret = -1; + if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { + std::shared_ptr ohos_external_gl = std::make_shared(texture_id, ohos_surface_); + ohos_external_gl->nativeImage_ = OH_NativeImage_Create(texture_id, GL_TEXTURE_EXTERNAL_OES); + if (ohos_external_gl->nativeImage_ == nullptr) { + FML_DLOG(ERROR) << "Error with OH_NativeImage_Create"; + return surface_id; + } + void* contextData = new OhosImageFrameData(this, texture_id); + nativeImageFrameAvailableListener_.context = contextData; + nativeImageFrameAvailableListener_.onFrameAvailable = &PlatformViewOHOS::OnNativeImageFrameAvailable; + ret = OH_NativeImage_SetOnFrameAvailableListener(ohos_external_gl->nativeImage_, nativeImageFrameAvailableListener_); + if (ret != 0) { + FML_DLOG(ERROR) << "Error with OH_NativeImage_SetOnFrameAvailableListener"; + return surface_id; + } + ret = OH_NativeImage_GetSurfaceId(ohos_external_gl->nativeImage_, &surface_id); + if (ret != 0) { + FML_DLOG(ERROR) << "Error with OH_NativeImage_GetSurfaceId"; + return surface_id; + } + RegisterTexture(ohos_external_gl); + } + return surface_id; +} + +void PlatformViewOHOS::OnNativeImageFrameAvailable(void *data) { + auto frameData = reinterpret_cast(data); + if (frameData == nullptr || frameData->context_ == nullptr) { + FML_DLOG(ERROR) << "OnNativeImageFrameAvailable, frameData or context_ is null."; + return; + } + std::shared_ptr ohos_surface = frameData->context_->ohos_surface_; + const TaskRunners task_runners = frameData->context_->task_runners_;; + if (ohos_surface) { + fml::AutoResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + task_runners.GetPlatformTaskRunner(), + [&latch, surface = ohos_surface.get(), frameData]() { + frameData->context_->MarkTextureFrameAvailable(frameData->texture_id_); + latch.Signal(); + }); + latch.Wait(); + } +} + +void PlatformViewOHOS::UnRegisterExternalTexture(int64_t texture_id) +{ + external_texture_gl_.erase(texture_id); + UnregisterTexture(texture_id); +} + +void PlatformViewOHOS::RegisterExternalTextureByPixelMap(int64_t texture_id, NativePixelMap* pixelMap) +{ + if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { + auto iter = external_texture_gl_.find(texture_id); + if (iter != external_texture_gl_.end()) { + iter->second->DispatchPixelMap(pixelMap); + } else { + std::shared_ptr ohos_external_gl = std::make_shared(texture_id, ohos_surface_); + external_texture_gl_[texture_id] = ohos_external_gl; + RegisterTexture(ohos_external_gl); + ohos_external_gl->DispatchPixelMap(pixelMap); + } + MarkTextureFrameAvailable(texture_id); + } +} + +OhosImageFrameData::OhosImageFrameData( + PlatformViewOHOS* context, + int64_t texture_id) + : context_(context), texture_id_(texture_id) {} + +OhosImageFrameData::~OhosImageFrameData() = default; + } // namespace flutter diff --git a/shell/platform/ohos/platform_view_ohos.h b/shell/platform/ohos/platform_view_ohos.h index a1b863ed34..387022cc08 100644 --- a/shell/platform/ohos/platform_view_ohos.h +++ b/shell/platform/ohos/platform_view_ohos.h @@ -31,6 +31,9 @@ #include "flutter/shell/platform/ohos/surface/ohos_snapshot_surface_producer.h" #include "flutter/shell/platform/ohos/surface/ohos_surface.h" #include "flutter/shell/platform/ohos/vsync_waiter_ohos.h" +#include +#include "ohos_external_texture_gl.h" +#include namespace flutter { @@ -84,6 +87,15 @@ class PlatformViewOHOS final : public PlatformView { int action, void* actionData, int actionDataLenth); + void RegisterExternalTextureByImage( + int64_t texture_id, + ImageNative* image); + + uint64_t RegisterExternalTexture(int64_t texture_id); + + void RegisterExternalTextureByPixelMap(int64_t texture_id, NativePixelMap* pixelMap); + + void UnRegisterExternalTexture(int64_t texture_id); // |PlatformView| void LoadDartDeferredLibrary( @@ -117,6 +129,7 @@ class PlatformViewOHOS final : public PlatformView { std::shared_ptr platform_message_handler_; std::shared_ptr surface_factory_; + std::map> external_texture_gl_; // |PlatformView| void UpdateSemantics( @@ -164,6 +177,23 @@ class PlatformViewOHOS final : public PlatformView { void FireFirstFrameCallback(); FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewOHOS); + + OH_OnFrameAvailableListener nativeImageFrameAvailableListener_{}; + + static void OnNativeImageFrameAvailable(void *data); +}; + +class OhosImageFrameData { + public: + OhosImageFrameData(PlatformViewOHOS* context, + int64_t texture_id); + + ~OhosImageFrameData(); + + PlatformViewOHOS* context_; + + int64_t texture_id_; }; + } // namespace flutter #endif -- Gitee From df2e5f20b8ad8cfb7c8235b7595ef908881cf83d Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Mon, 26 Feb 2024 20:23:45 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=A8=E7=A6=81?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E7=9A=84=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- shell/platform/ohos/library_loader.cpp | 2 +- .../ohos/napi/platform_view_ohos_napi.cpp | 47 +++-- .../ohos/napi/platform_view_ohos_napi.h | 26 ++- .../ohos/ohos_external_texture_gl.cpp | 191 ++++++++++-------- .../platform/ohos/ohos_external_texture_gl.h | 17 +- shell/platform/ohos/ohos_unified_surface.h | 2 +- shell/platform/ohos/platform_view_ohos.cpp | 32 +-- shell/platform/ohos/platform_view_ohos.h | 9 +- 8 files changed, 185 insertions(+), 141 deletions(-) diff --git a/shell/platform/ohos/library_loader.cpp b/shell/platform/ohos/library_loader.cpp index f6c52a6aff..415bf46a65 100644 --- a/shell/platform/ohos/library_loader.cpp +++ b/shell/platform/ohos/library_loader.cpp @@ -112,7 +112,7 @@ static napi_value Init(napi_env env, napi_value exports) { flutter::PlatformViewOHOSNapi::nativeInitNativeImage), DECLARE_NAPI_FUNCTION( "nativeRegisterTexture", - flutter::PlatformViewOHOSNapi::nativeRegisterTexture), + flutter::PlatformViewOHOSNapi::nativeRegisterTexture), DECLARE_NAPI_FUNCTION( "nativeUnregisterTexture", flutter::PlatformViewOHOSNapi::nativeUnregisterTexture), diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 848ac957d7..6c927d8bc2 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -16,20 +16,21 @@ #include "platform_view_ohos_napi.h" #include #include +#include +#include +#include #include #include #include -#include "../types.h" + #include "flutter/fml/make_copyable.h" #include "flutter/fml/platform/ohos/napi_util.h" #include "flutter/shell/platform/ohos/ohos_main.h" #include "flutter/shell/platform/ohos/ohos_shell_holder.h" #include "flutter/shell/platform/ohos/surface/ohos_native_window.h" +#include "flutter/shell/platform/ohos/types.h" #include "unicode/uchar.h" #include "flutter/shell/platform/ohos/ohos_xcomponent_adapter.h" -#include -#include -#include #define OHOS_SHELL_HOLDER (reinterpret_cast(shell_holder)) namespace flutter { @@ -1424,11 +1425,13 @@ napi_value PlatformViewOHOSNapi::nativeGetSystemLanguages( napi_value PlatformViewOHOSNapi::nativeInitNativeImage( napi_env env, - napi_callback_info info) { + napi_callback_info info) +{ FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeInitNativeImage"; size_t argc = 3; napi_value args[3] = {nullptr}; - int64_t shell_holder, textureId; + int64_t shell_holder; + int64_t textureId; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); @@ -1438,13 +1441,14 @@ napi_value PlatformViewOHOSNapi::nativeInitNativeImage( return nullptr; } -napi_value PlatformViewOHOSNapi::nativeRegisterTexture(napi_env env, - napi_callback_info info) -{ +napi_value PlatformViewOHOSNapi::nativeRegisterTexture( + napi_env env, + napi_callback_info info) { FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterTexture"; size_t argc = 2; napi_value args[2] = {nullptr}; - int64_t shell_holder, textureId; + int64_t shell_holder; + int64_t textureId; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); @@ -1455,12 +1459,13 @@ napi_value PlatformViewOHOSNapi::nativeRegisterTexture(napi_env env, } napi_value PlatformViewOHOSNapi::nativeUnregisterTexture( - napi_env env, napi_callback_info info) -{ + napi_env env, + napi_callback_info info) { FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeUnregisterTexture"; size_t argc = 2; napi_value args[2] = {nullptr}; - int64_t shell_holder, textureId; + int64_t shell_holder; + int64_t textureId; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); @@ -1469,11 +1474,12 @@ napi_value PlatformViewOHOSNapi::nativeUnregisterTexture( } napi_value PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable( - napi_env env, napi_callback_info info) -{ + napi_env env, + napi_callback_info info) { size_t argc = 2; napi_value args[2] = {nullptr}; - int64_t shell_holder, textureId; + int64_t shell_holder; + int64_t textureId; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); @@ -1481,13 +1487,14 @@ napi_value PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable( return nullptr; } -napi_value PlatformViewOHOSNapi::nativeRegisterPixelMap(napi_env env, - napi_callback_info info) -{ +napi_value PlatformViewOHOSNapi::nativeRegisterPixelMap( + napi_env env, + napi_callback_info info) { FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterPixelMap"; size_t argc = 3; napi_value args[3] = {nullptr}; - int64_t shell_holder, textureId; + int64_t shell_holder; + int64_t textureId; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr)); NAPI_CALL(env, napi_get_value_int64(env, args[0], &shell_holder)); NAPI_CALL(env, napi_get_value_int64(env, args[1], &textureId)); diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.h b/shell/platform/ohos/napi/platform_view_ohos_napi.h index 8339308b00..f998fbf553 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.h +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.h @@ -16,7 +16,6 @@ #ifndef PLATFORM_VIEW_OHOS_NAPI_H #define PLATFORM_VIEW_OHOS_NAPI_H #include -#include "../napi_common.h" #include "flutter/assets/directory_asset_bundle.h" #include "flutter/common/settings.h" #include "flutter/fml/file.h" @@ -27,6 +26,7 @@ #include "flutter/lib/ui/plugins/callback_cache.h" #include "flutter/runtime/dart_service_isolate.h" #include "flutter/shell/common/run_configuration.h" +#include "flutter/shell/platform/ohos/napi_common.h" #include "napi/native_api.h" // class for all c++ to call js function namespace flutter { @@ -143,26 +143,34 @@ class PlatformViewOHOSNapi { napi_env env, napi_callback_info info); // 应用下发系统语言设置 - static napi_value nativeInitNativeImage(napi_env env, + static napi_value nativeInitNativeImage( + napi_env env, napi_callback_info info); - static napi_value nativeUnregisterTexture(napi_env env, + static napi_value nativeUnregisterTexture( + napi_env env, napi_callback_info info); - static napi_value nativeMarkTextureFrameAvailable(napi_env env, + static napi_value nativeMarkTextureFrameAvailable( + napi_env env, napi_callback_info info); - static napi_value nativeRegisterPixelMap(napi_env env, + static napi_value nativeRegisterPixelMap( + napi_env env, napi_callback_info info); - static napi_value nativeRegisterTexture(napi_env env, + static napi_value nativeRegisterTexture( + napi_env env, napi_callback_info info); // Surface相关,XComponent调用 static void SurfaceCreated(int64_t shell_holder, void* window); - static void SurfaceChanged(int64_t shell_holder, - int32_t width, - int32_t height); + + static void SurfaceChanged( + int64_t shell_holder, + int32_t width, + int32_t height); + static void SurfaceDestroyed(int64_t shell_holder); static int64_t GetShellHolder(); static napi_value nativeXComponentAttachFlutterEngine( diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index 7533b43364..5047168738 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -15,6 +15,8 @@ #include "ohos_external_texture_gl.h" +#include +#include #include #include "third_party/skia/include/core/SkAlphaType.h" @@ -24,10 +26,9 @@ #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" -#include -#include - #define EGL_PLATFORM_OHOS_KHR 0x34E0 +#define DMA_SIZE 256 // DMA内存分配的分块大小 +#define PIXEL_SIZE 4 // 像素点占用4个字节 namespace flutter { using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC; @@ -38,7 +39,8 @@ constexpr const char *EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland"; constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT"; OHOSExternalTextureGL::OHOSExternalTextureGL(int64_t id, const std::shared_ptr& ohos_surface) - : Texture(id), ohos_surface_(std::move(ohos_surface)), transform(SkMatrix::I()) { + : Texture(id), ohos_surface_(std::move(ohos_surface)), transform(SkMatrix::I()) +{ nativeImage_ = nullptr; nativeWindow_ = nullptr; eglContext_ = EGL_NO_CONTEXT; @@ -48,57 +50,63 @@ OHOSExternalTextureGL::OHOSExternalTextureGL(int64_t id, const std::shared_ptrGLContextMakeCurrent(); + if (result->GetResult()) { + FML_DLOG(INFO)<<"ResourceContextMakeCurrent successed"; + glGenTextures(1, &texture_name_); + FML_DLOG(INFO) << "OHOSExternalTextureGL::Paint, glGenTextures texture_name_=" << texture_name_; + if (nativeImage_ == nullptr) { + nativeImage_ = OH_NativeImage_Create(texture_name_, GL_TEXTURE_EXTERNAL_OES); + if (nativeImage_ == nullptr) { + FML_DLOG(ERROR) << "Error with OH_NativeImage_Create"; + return; + } + nativeWindow_ = OH_NativeImage_AcquireNativeWindow(nativeImage_); + if (nativeWindow_ == nullptr) { + FML_DLOG(ERROR) << "Error with OH_NativeImage_AcquireNativeWindow"; + return; + } + } + + int32_t ret = OH_NativeImage_AttachContext(nativeImage_, texture_name_); + if (ret != 0) { + FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeImage_AttachContext err code:"<< ret; + } + state_ = AttachmentState::attached; + } else { + FML_DLOG(FATAL)<<"ResourceContextMakeCurrent failed"; + } +} + void OHOSExternalTextureGL::Paint(PaintContext& context, const SkRect& bounds, bool freeze, - const SkSamplingOptions& sampling) { + const SkSamplingOptions& sampling) +{ if (state_ == AttachmentState::detached) { FML_DLOG(ERROR) << "OHOSExternalTextureGL::Paint"; return; } if (state_ == AttachmentState::uninitialized) { - OHOSSurface* ohos_surface_ptr = ohos_surface_.get(); - OhosSurfaceGLSkia* ohosSurfaceGLSkia_ = (OhosSurfaceGLSkia*)ohos_surface_ptr; - auto result = ohosSurfaceGLSkia_->GLContextMakeCurrent(); - if (result->GetResult()) { - FML_DLOG(INFO)<<"ResourceContextMakeCurrent successed"; - glGenTextures(1, &texture_name_); - FML_DLOG(INFO) << "OHOSExternalTextureGL::Paint, glGenTextures texture_name_=" << texture_name_; - if (nativeImage_ == nullptr) { - nativeImage_ = OH_NativeImage_Create(texture_name_, GL_TEXTURE_EXTERNAL_OES); - if (nativeImage_ == nullptr) { - FML_DLOG(ERROR) << "Error with OH_NativeImage_Create"; - return; - } - nativeWindow_ = OH_NativeImage_AcquireNativeWindow(nativeImage_); - if (nativeWindow_ == nullptr) { - FML_DLOG(ERROR) << "Error with OH_NativeImage_AcquireNativeWindow"; - return; - } - } - - int32_t ret = OH_NativeImage_AttachContext(nativeImage_, texture_name_); - if(ret != 0) { - FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeImage_AttachContext err code:"<< ret; - } - state_ = AttachmentState::attached; - } else { - FML_DLOG(FATAL)<<"ResourceContextMakeCurrent failed"; - } + Attach(); } if (!freeze && new_frame_ready_) { Update(); new_frame_ready_ = false; } - GrGLTextureInfo textureInfo = {GL_TEXTURE_EXTERNAL_OES, texture_name_, - GL_RGBA8_OES}; + GrGLTextureInfo textureInfo = { + GL_TEXTURE_EXTERNAL_OES, texture_name_, GL_RGBA8_OES}; GrBackendTexture backendTexture(1, 1, GrMipMapped::kNo, textureInfo); sk_sp image = SkImage::MakeFromTexture( context.gr_context, backendTexture, kTopLeft_GrSurfaceOrigin, @@ -128,7 +136,8 @@ void OHOSExternalTextureGL::Paint(PaintContext& context, } } -void OHOSExternalTextureGL::OnGrContextCreated() { +void OHOSExternalTextureGL::OnGrContextCreated() +{ FML_DLOG(INFO)<<" OHOSExternalTextureGL::OnGrContextCreated"; state_ = AttachmentState::uninitialized; } @@ -143,17 +152,20 @@ void OHOSExternalTextureGL::OnGrContextDestroyed() { state_ = AttachmentState::detached; } -void OHOSExternalTextureGL::MarkNewFrameAvailable() { +void OHOSExternalTextureGL::MarkNewFrameAvailable() +{ FML_DLOG(INFO)<<" OHOSExternalTextureGL::MarkNewFrameAvailable"; new_frame_ready_ = true; } -void OHOSExternalTextureGL::OnTextureUnregistered() { +void OHOSExternalTextureGL::OnTextureUnregistered() +{ FML_DLOG(INFO)<<" OHOSExternalTextureGL::OnTextureUnregistered"; // do nothing } -void OHOSExternalTextureGL::Update() { +void OHOSExternalTextureGL::Update() +{ ProducePixelMapToNativeImage(); int32_t ret = OH_NativeImage_UpdateSurfaceImage(nativeImage_); if (ret != 0) { @@ -162,21 +174,20 @@ void OHOSExternalTextureGL::Update() { UpdateTransform(); } -void OHOSExternalTextureGL::Detach() { +void OHOSExternalTextureGL::Detach() +{ OH_NativeImage_DetachContext(nativeImage_); OH_NativeWindow_DestroyNativeWindow(nativeWindow_); } -void OHOSExternalTextureGL::UpdateTransform() { +void OHOSExternalTextureGL::UpdateTransform() +{ float m[16] = { 0.0f }; int32_t ret = OH_NativeImage_GetTransformMatrix(nativeImage_, m); - if(ret != 0) { + if (ret != 0) { FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeImage_GetTransformMatrix err code:"<< ret; } // transform ohos 4x4 matrix to skia 3x3 matrix - FML_DLOG(INFO)<<"OHOSExternalTextureGL::UpdateTransform "<virAddr, handle->size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0); @@ -234,7 +216,7 @@ void OHOSExternalTextureGL::ProducePixelMapToNativeImage() } void *pixelAddr = nullptr; - ret = OH_PixelMap_AccessPixels(pixelMap_, &pixelAddr); + int64_t ret = OH_PixelMap_AccessPixels(pixelMap_, &pixelAddr); if (ret != IMAGE_RESULT_SUCCESS) { FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_PixelMap_AccessPixels err:"<< ret; return; @@ -242,21 +224,23 @@ void OHOSExternalTextureGL::ProducePixelMapToNativeImage() uint32_t *value = static_cast(pixelAddr); uint32_t *pixel = static_cast(mappedAddr); - uint32_t rowDataSize = 256; // DMA内存会自动补齐,分配内存时是 256 的整数倍 + uint32_t rowDataSize = DMA_SIZE; // DMA内存会自动补齐,分配内存时是 256 的整数倍 while (rowDataSize < pixelMapInfo.rowSize) { - rowDataSize += 256; + rowDataSize += DMA_SIZE; } - FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo w:" << pixelMapInfo.width << " h:" << pixelMapInfo.height; - FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo rowSize:" << pixelMapInfo.rowSize << " format:" << pixelMapInfo.pixelFormat; + FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo w:" << pixelMapInfo.width + << " h:" << pixelMapInfo.height; + FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo rowSize:" << pixelMapInfo.rowSize + << " format:" << pixelMapInfo.pixelFormat; FML_DLOG(INFO) << "OHOSExternalTextureGL pixelMapInfo rowDataSize:" << rowDataSize; // 复制图片纹理数据到内存中,需要处理DMA内存补齐相关的逻辑 for (uint32_t i = 0; i < pixelMapInfo.height; i++) { memcpy(pixel, value, rowDataSize); - pixel += rowDataSize / 4; + pixel += rowDataSize / PIXEL_SIZE; value += pixelMapInfo.width; - } + } OH_PixelMap_UnAccessPixels(pixelMap_); //munmap after use @@ -265,15 +249,48 @@ void OHOSExternalTextureGL::ProducePixelMapToNativeImage() FML_DLOG(FATAL)<<"OHOSExternalTextureGL munmap failed"; return; } +} + +void OHOSExternalTextureGL::ProducePixelMapToNativeImage() +{ + if (pixelMap_ == nullptr) { + FML_DLOG(ERROR) << "OHOSExternalTextureGL pixelMap in null"; + return; + } + if (state_ == AttachmentState::detached) { + FML_DLOG(ERROR) << "OHOSExternalTextureGL AttachmentState err"; + return; + } + int32_t ret = -1; + ret = OH_PixelMap_GetImageInfo(pixelMap_, &pixelMapInfo); + if (ret != 0) { + FML_DLOG(ERROR) << "OHOSExternalTextureGL OH_PixelMap_GetImageInfo err:" << ret; + } + + int code = SET_BUFFER_GEOMETRY; + ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, pixelMapInfo.width, pixelMapInfo.height); + if (ret != 0) { + FML_DLOG(ERROR) << "OHOSExternalTextureGL OH_NativeWindow_NativeWindowHandleOpt err:" << ret; + } + + if (buffer_ != nullptr) { + OH_NativeWindow_NativeWindowAbortBuffer(nativeWindow_, buffer_); + buffer_ = nullptr; + } + ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer_, &fenceFd); + if (ret != 0) { + FML_DLOG(ERROR) << "OHOSExternalTextureGL OH_NativeWindow_NativeWindowRequestBuffer err:" << ret; + } + HandlePixelMapBuffer(); Region region{nullptr, 0}; ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer_, fenceFd, region); - if(ret != 0) { + if (ret != 0) { FML_DLOG(FATAL)<<"OHOSExternalTextureGL OH_NativeWindow_NativeWindowFlushBuffer err:"<< ret; } } -EGLDisplay OHOSExternalTextureGL::GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list) -{ +EGLDisplay OHOSExternalTextureGL::GetPlatformEglDisplay(EGLenum platform, void *native_display, + const EGLint *attrib_list) { GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL; if (!eglGetPlatformDisplayExt) { @@ -313,7 +330,7 @@ bool OHOSExternalTextureGL::CheckEglExtension(const char *extensions, const char void OHOSExternalTextureGL::DispatchPixelMap(NativePixelMap* pixelMap) { - if(pixelMap != nullptr) { + if (pixelMap != nullptr) { pixelMap_ = pixelMap; } } diff --git a/shell/platform/ohos/ohos_external_texture_gl.h b/shell/platform/ohos/ohos_external_texture_gl.h index 0e900e60a4..88949d3dbd 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.h +++ b/shell/platform/ohos/ohos_external_texture_gl.h @@ -20,15 +20,16 @@ #include #include -#include "flutter/common/graphics/texture.h" -#include "flutter/shell/platform/ohos/surface/ohos_surface.h" -#include "flutter/shell/platform/ohos/ohos_surface_gl_skia.h" -#include "napi/platform_view_ohos_napi.h" #include -#include -#include #include #include +#include +#include + +#include "flutter/common/graphics/texture.h" +#include "flutter/shell/platform/ohos/napi/platform_view_ohos_napi.h" +#include "flutter/shell/platform/ohos/ohos_surface_gl_skia.h" +#include "flutter/shell/platform/ohos/surface/ohos_surface.h" // maybe now unused namespace flutter { @@ -59,6 +60,8 @@ class OHOSExternalTextureGL : public flutter::Texture { void DispatchPixelMap(NativePixelMap* pixelMap); private: + void Attach(); + void Update(); void Detach(); @@ -69,6 +72,8 @@ class OHOSExternalTextureGL : public flutter::Texture { bool CheckEglExtension(const char *extensions, const char *extension); + void HandlePixelMapBuffer(); + void ProducePixelMapToNativeImage(); enum class AttachmentState { uninitialized, attached, detached }; diff --git a/shell/platform/ohos/ohos_unified_surface.h b/shell/platform/ohos/ohos_unified_surface.h index 49aa35a3d6..591ba0dddf 100644 --- a/shell/platform/ohos/ohos_unified_surface.h +++ b/shell/platform/ohos/ohos_unified_surface.h @@ -41,7 +41,7 @@ class OHOSUnifiedSurface : public GPUSurfaceGLDelegate, bool SetNativeWindow(fml::RefPtr window) {} - std::unique_ptr CreateSnapshotSurface() + std::unique_ptr CreateSnapshotSurface() std::unique_ptr CreateGPUSurface( GrDirectContext* gr_context = nullptr) {} diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 19f45611cf..85919a1f1a 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -170,7 +170,8 @@ void PlatformViewOHOS::NotifyChanged(const SkISize& size) { } // |PlatformView| -void PlatformViewOHOS::NotifyDestroyed() { +void PlatformViewOHOS::NotifyDestroyed() +{ LOGI("PlatformViewOHOS NotifyDestroyed enter"); PlatformView::NotifyDestroyed(); if (ohos_surface_) { @@ -392,13 +393,15 @@ void PlatformViewOHOS::FireFirstFrameCallback() { void PlatformViewOHOS::RegisterExternalTextureByImage( int64_t texture_id, - ImageNative* image) { - if(ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { + ImageNative* image) +{ + if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { auto iter = external_texture_gl_.find(texture_id); - if(iter != external_texture_gl_.end()) { + if (iter != external_texture_gl_.end()) { iter->second->DispatchImage(image); } else { - std::shared_ptr ohos_external_gl = std::make_shared(texture_id, ohos_surface_); + std::shared_ptr ohos_external_gl = + std::make_shared(texture_id, ohos_surface_); external_texture_gl_[texture_id] = ohos_external_gl; RegisterTexture(ohos_external_gl); ohos_external_gl->DispatchImage(image); @@ -406,20 +409,23 @@ void PlatformViewOHOS::RegisterExternalTextureByImage( } } -uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) { +uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) +{ uint64_t surface_id = 0; int ret = -1; if (ohos_context_->RenderingApi() == OHOSRenderingAPI::kOpenGLES) { - std::shared_ptr ohos_external_gl = std::make_shared(texture_id, ohos_surface_); + std::shared_ptr ohos_external_gl = + std::make_shared(texture_id, ohos_surface_); ohos_external_gl->nativeImage_ = OH_NativeImage_Create(texture_id, GL_TEXTURE_EXTERNAL_OES); if (ohos_external_gl->nativeImage_ == nullptr) { FML_DLOG(ERROR) << "Error with OH_NativeImage_Create"; return surface_id; } void* contextData = new OhosImageFrameData(this, texture_id); - nativeImageFrameAvailableListener_.context = contextData; - nativeImageFrameAvailableListener_.onFrameAvailable = &PlatformViewOHOS::OnNativeImageFrameAvailable; - ret = OH_NativeImage_SetOnFrameAvailableListener(ohos_external_gl->nativeImage_, nativeImageFrameAvailableListener_); + OH_OnFrameAvailableListener listener; + listener.context = contextData; + listener.onFrameAvailable = &PlatformViewOHOS::OnNativeImageFrameAvailable; + ret = OH_NativeImage_SetOnFrameAvailableListener(ohos_external_gl->nativeImage_, listener); if (ret != 0) { FML_DLOG(ERROR) << "Error with OH_NativeImage_SetOnFrameAvailableListener"; return surface_id; @@ -434,7 +440,8 @@ uint64_t PlatformViewOHOS::RegisterExternalTexture(int64_t texture_id) { return surface_id; } -void PlatformViewOHOS::OnNativeImageFrameAvailable(void *data) { +void PlatformViewOHOS::OnNativeImageFrameAvailable(void *data) +{ auto frameData = reinterpret_cast(data); if (frameData == nullptr || frameData->context_ == nullptr) { FML_DLOG(ERROR) << "OnNativeImageFrameAvailable, frameData or context_ is null."; @@ -467,7 +474,8 @@ void PlatformViewOHOS::RegisterExternalTextureByPixelMap(int64_t texture_id, Nat if (iter != external_texture_gl_.end()) { iter->second->DispatchPixelMap(pixelMap); } else { - std::shared_ptr ohos_external_gl = std::make_shared(texture_id, ohos_surface_); + std::shared_ptr ohos_external_gl = + std::make_shared(texture_id, ohos_surface_); external_texture_gl_[texture_id] = ohos_external_gl; RegisterTexture(ohos_external_gl); ohos_external_gl->DispatchPixelMap(pixelMap); diff --git a/shell/platform/ohos/platform_view_ohos.h b/shell/platform/ohos/platform_view_ohos.h index 387022cc08..a9793dd73a 100644 --- a/shell/platform/ohos/platform_view_ohos.h +++ b/shell/platform/ohos/platform_view_ohos.h @@ -21,19 +21,20 @@ #include #include +#include +#include + #include "flutter/fml/memory/weak_ptr.h" #include "flutter/lib/ui/window/platform_message.h" #include "flutter/shell/common/platform_view.h" #include "flutter/shell/platform/ohos/context/ohos_context.h" #include "flutter/shell/platform/ohos/napi/platform_view_ohos_napi.h" +#include "flutter/shell/platform/ohos/ohos_external_texture_gl.h" #include "flutter/shell/platform/ohos/platform_message_handler_ohos.h" #include "flutter/shell/platform/ohos/surface/ohos_native_window.h" #include "flutter/shell/platform/ohos/surface/ohos_snapshot_surface_producer.h" #include "flutter/shell/platform/ohos/surface/ohos_surface.h" #include "flutter/shell/platform/ohos/vsync_waiter_ohos.h" -#include -#include "ohos_external_texture_gl.h" -#include namespace flutter { @@ -178,8 +179,6 @@ class PlatformViewOHOS final : public PlatformView { FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewOHOS); - OH_OnFrameAvailableListener nativeImageFrameAvailableListener_{}; - static void OnNativeImageFrameAvailable(void *data); }; -- Gitee From b88e455ab4483cf533bd2009eecb01589d50157b Mon Sep 17 00:00:00 2001 From: hezhengyi Date: Mon, 26 Feb 2024 22:25:25 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=97=A8=E7=A6=81?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E7=9A=84=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hezhengyi --- .../ohos/napi/platform_view_ohos_napi.cpp | 12 ++++++++---- .../ohos/ohos_external_texture_gl.cpp | 19 ++++++++++++------- shell/platform/ohos/platform_view_ohos.cpp | 4 ++-- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp index 6c927d8bc2..69bd07dcee 100644 --- a/shell/platform/ohos/napi/platform_view_ohos_napi.cpp +++ b/shell/platform/ohos/napi/platform_view_ohos_napi.cpp @@ -1443,7 +1443,8 @@ napi_value PlatformViewOHOSNapi::nativeInitNativeImage( napi_value PlatformViewOHOSNapi::nativeRegisterTexture( napi_env env, - napi_callback_info info) { + napi_callback_info info) +{ FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterTexture"; size_t argc = 2; napi_value args[2] = {nullptr}; @@ -1460,7 +1461,8 @@ napi_value PlatformViewOHOSNapi::nativeRegisterTexture( napi_value PlatformViewOHOSNapi::nativeUnregisterTexture( napi_env env, - napi_callback_info info) { + napi_callback_info info) +{ FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeUnregisterTexture"; size_t argc = 2; napi_value args[2] = {nullptr}; @@ -1475,7 +1477,8 @@ napi_value PlatformViewOHOSNapi::nativeUnregisterTexture( napi_value PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable( napi_env env, - napi_callback_info info) { + napi_callback_info info) +{ size_t argc = 2; napi_value args[2] = {nullptr}; int64_t shell_holder; @@ -1489,7 +1492,8 @@ napi_value PlatformViewOHOSNapi::nativeMarkTextureFrameAvailable( napi_value PlatformViewOHOSNapi::nativeRegisterPixelMap( napi_env env, - napi_callback_info info) { + napi_callback_info info) +{ FML_DLOG(INFO)<<"PlatformViewOHOSNapi::nativeRegisterPixelMap"; size_t argc = 3; napi_value args[3] = {nullptr}; diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index 5047168738..fa99b84b7e 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -27,8 +27,9 @@ #include "third_party/skia/include/gpu/GrDirectContext.h" #define EGL_PLATFORM_OHOS_KHR 0x34E0 -#define DMA_SIZE 256 // DMA内存分配的分块大小 -#define PIXEL_SIZE 4 // 像素点占用4个字节 + +const int DMA_SIZE = 256 // DMA内存分配的分块大小 +const int PIXEL_SIZE = 4 // 像素点占用4个字节 namespace flutter { using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC; @@ -57,7 +58,8 @@ OHOSExternalTextureGL::~OHOSExternalTextureGL() } } -void OHOSExternalTextureGL::Attach() { +void OHOSExternalTextureGL::Attach() +{ OHOSSurface* ohos_surface_ptr = ohos_surface_.get(); OhosSurfaceGLSkia* ohosSurfaceGLSkia_ = (OhosSurfaceGLSkia*)ohos_surface_ptr; auto result = ohosSurfaceGLSkia_->GLContextMakeCurrent(); @@ -142,7 +144,8 @@ void OHOSExternalTextureGL::OnGrContextCreated() state_ = AttachmentState::uninitialized; } -void OHOSExternalTextureGL::OnGrContextDestroyed() { +void OHOSExternalTextureGL::OnGrContextDestroyed() +{ FML_DLOG(INFO)<<" OHOSExternalTextureGL::OnGrContextDestroyed"; if (state_ == AttachmentState::attached) { Detach(); @@ -206,7 +209,8 @@ void OHOSExternalTextureGL::DispatchImage(ImageNative* image) lastImage_ = image; } -void OHOSExternalTextureGL::HandlePixelMapBuffer() { +void OHOSExternalTextureGL::HandlePixelMapBuffer() +{ BufferHandle *handle = OH_NativeWindow_GetBufferHandleFromNative(buffer_); // get virAddr of bufferHandl by mmap sys interface void *mappedAddr = mmap(handle->virAddr, handle->size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0); @@ -243,7 +247,7 @@ void OHOSExternalTextureGL::HandlePixelMapBuffer() { } OH_PixelMap_UnAccessPixels(pixelMap_); - //munmap after use + // munmap after use ret = munmap(mappedAddr, handle->size); if (ret == -1) { FML_DLOG(FATAL)<<"OHOSExternalTextureGL munmap failed"; @@ -290,7 +294,8 @@ void OHOSExternalTextureGL::ProducePixelMapToNativeImage() } EGLDisplay OHOSExternalTextureGL::GetPlatformEglDisplay(EGLenum platform, void *native_display, - const EGLint *attrib_list) { + const EGLint *attrib_list) +{ GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL; if (!eglGetPlatformDisplayExt) { diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 85919a1f1a..d1e0e0fb8b 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -448,7 +448,7 @@ void PlatformViewOHOS::OnNativeImageFrameAvailable(void *data) return; } std::shared_ptr ohos_surface = frameData->context_->ohos_surface_; - const TaskRunners task_runners = frameData->context_->task_runners_;; + const TaskRunners task_runners = frameData->context_->task_runners_; if (ohos_surface) { fml::AutoResetWaitableEvent latch; fml::TaskRunner::RunNowOrPostTask( @@ -474,7 +474,7 @@ void PlatformViewOHOS::RegisterExternalTextureByPixelMap(int64_t texture_id, Nat if (iter != external_texture_gl_.end()) { iter->second->DispatchPixelMap(pixelMap); } else { - std::shared_ptr ohos_external_gl = + std::shared_ptr ohos_external_gl = std::make_shared(texture_id, ohos_surface_); external_texture_gl_[texture_id] = ohos_external_gl; RegisterTexture(ohos_external_gl); -- Gitee From 5ff2c399da58b9546548ebe4450b873c572fa5d1 Mon Sep 17 00:00:00 2001 From: hazy Date: Mon, 26 Feb 2024 15:26:45 +0000 Subject: [PATCH 5/5] update shell/platform/ohos/ohos_external_texture_gl.cpp. Signed-off-by: hazy --- shell/platform/ohos/ohos_external_texture_gl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/ohos/ohos_external_texture_gl.cpp b/shell/platform/ohos/ohos_external_texture_gl.cpp index fa99b84b7e..9515f268e1 100755 --- a/shell/platform/ohos/ohos_external_texture_gl.cpp +++ b/shell/platform/ohos/ohos_external_texture_gl.cpp @@ -28,8 +28,8 @@ #define EGL_PLATFORM_OHOS_KHR 0x34E0 -const int DMA_SIZE = 256 // DMA内存分配的分块大小 -const int PIXEL_SIZE = 4 // 像素点占用4个字节 +const int DMA_SIZE = 256; // DMA内存分配的分块大小 +const int PIXEL_SIZE = 4; // 像素点占用4个字节 namespace flutter { using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC; -- Gitee