diff --git a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.cpp b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.cpp index 102b2c708..9d20c2877 100644 --- a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.cpp +++ b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.cpp @@ -15,6 +15,7 @@ #include "NativeImageAdaptor.h" #include "logger_common.h" +#include "cstdint" namespace NativeWindowSample { using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC; @@ -25,6 +26,8 @@ constexpr char CHARACTER_WHITESPACE = ' '; constexpr const char *CHARACTER_STRING_WHITESPACE = " "; constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT"; constexpr int32_t NATIVE_CACHE_BUFFER = 3; +constexpr int32_t GSERROR_OK = 0; +constexpr int32_t GSERROR_FAILD = 1; NativeImageAdaptor *NativeImageAdaptor::GetInstance() { static NativeImageAdaptor imageAdaptor; @@ -121,10 +124,14 @@ bool NativeImageAdaptor::Export(napi_env env, napi_value exports) napi_default, nullptr}, {"ProduceBuffer", nullptr, NativeImageAdaptor::NapiOnProduceBuffer, nullptr, nullptr, nullptr, napi_default, nullptr}, + {"ConsumerBuffer", nullptr, NativeImageAdaptor::NapiOnConsumerBuffer, nullptr, nullptr, nullptr, napi_default, + nullptr}, {"AttachBuffer", nullptr, NativeImageAdaptor::NapiOnAttachBuffer, nullptr, nullptr, nullptr, napi_default, nullptr}, {"DettachBuffer", nullptr, NativeImageAdaptor::NapiOnDettachBuffer, nullptr, nullptr, nullptr, napi_default, nullptr}, + {"ChangeIsAutoConsumer", nullptr, NativeImageAdaptor::NapiOnChangeIsAutoConsumer, nullptr, nullptr, nullptr, + napi_default, nullptr}, }; napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); @@ -263,12 +270,6 @@ void NativeImageAdaptor::DettachBuffer() bufferAttached_.pop(); } -napi_value NativeImageAdaptor::NapiOnProduceBuffer(napi_env env, napi_callback_info info) -{ - NativeImageAdaptor::GetInstance()->ProduceBuffer(0x00, NativeImageAdaptor::GetInstance()->nativeWindow_); - return nullptr; -} - void NativeImageAdaptor::SetConfigAndGetValue() { static int32_t g_cnt = 0; @@ -344,7 +345,7 @@ void NativeImageAdaptor::GetBufferMapPlanes(NativeWindowBuffer *buffer) } } -void NativeImageAdaptor::ProduceBuffer(uint32_t value, OHNativeWindow *InNativeWindow) +int32_t NativeImageAdaptor::ProduceBuffer(uint32_t value, OHNativeWindow *InNativeWindow) { if (InNativeWindow == nativeWindow_) { SetConfigAndGetValue(); @@ -355,14 +356,14 @@ void NativeImageAdaptor::ProduceBuffer(uint32_t value, OHNativeWindow *InNativeW int ret = OH_NativeWindow_NativeWindowRequestBuffer(InNativeWindow, &buffer, &fenceFd); if (ret != 0) { LOGE("OH_NativeWindow_NativeWindowRequestBuffer fail"); - return; + return GSERROR_FAILD; } GetBufferMapPlanes(buffer); if (InNativeWindow == nativeWindowCache_) { OH_NativeWindow_NativeWindowDetachBuffer(nativeWindowCache_, buffer); bufferCache_.push(buffer); - return; + return GSERROR_OK; } int32_t code = GET_FORMAT; int32_t formatType = NATIVEBUFFER_PIXEL_FMT_CLUT1; @@ -396,9 +397,30 @@ void NativeImageAdaptor::ProduceBuffer(uint32_t value, OHNativeWindow *InNativeW ret = OH_NativeWindow_NativeWindowFlushBuffer(InNativeWindow, buffer, fenceFd, *region); if (ret != 0) { LOGE("OH_NativeWindow_NativeWindowFlushBuffer fail"); - return; + GSERROR_FAILD; } + delete region; + return GSERROR_OK; +} + +int32_t NativeImageAdaptor::ConsumerBuffer(uint32_t value, OHNativeWindow *InNativeWindow) +{ + std::lock_guard lockGuard(opMutex_); + NativeWindowBuffer *buffer = nullptr; + int fenceFd = -1; + int ret = OH_NativeImage_AcquireNativeWindowBuffer(image_, &buffer, &fenceFd); + if (ret != 0) { + LOGE("OH_NativeImage_AcquireNativeWindowBuffer fail, ret:%{public}d", ret); + return GSERROR_FAILD; + } + ret = OH_NativeImage_ReleaseNativeWindowBuffer(image_, buffer, fenceFd); + if (ret != 0) { + LOGE("OH_NativeImage_ReleaseNativeWindowBuffer fail, ret:%{public}d", ret); + return GSERROR_FAILD; + } + availableBufferCount_--; + return GSERROR_OK; } void NativeImageAdaptor::OnFrameAvailable(void *context) @@ -411,10 +433,13 @@ void NativeImageAdaptor::DealCallback(void *context) { std::lock_guard lockGuard(opMutex_); LOGD("NativeImageAdaptor success OnFrameAvailable, %{public}d", availableBufferCount_); - availableBufferCount_++; - int32_t ret = OH_NativeImage_UpdateSurfaceImage(image_); - if (ret != 0) { - LOGE("OH_NativeImage_UpdateSurfaceImage fail"); + if (isAutoConsumer_) { + int32_t ret = OH_NativeImage_UpdateSurfaceImage(image_); + if (ret != 0) { + LOGE("OH_NativeImage_UpdateSurfaceImage fail"); + } + } else { + availableBufferCount_++; } return; } @@ -444,6 +469,13 @@ int32_t NativeImageAdaptor::GetCacheBufferCount() return bufferCache_.size(); } +bool NativeImageAdaptor::ChangeIsAutoConsumer() +{ + std::lock_guard lockGuard(opMutex_); + isAutoConsumer_ = !isAutoConsumer_; + return isAutoConsumer_; +} + napi_value NativeImageAdaptor::GetAvailableCount(napi_env env, napi_callback_info info) { napi_value val = nullptr; @@ -476,6 +508,32 @@ napi_value NativeImageAdaptor::NapiOnGetCacheBufferCount(napi_env env, napi_call return val; } +napi_value NativeImageAdaptor::NapiOnChangeIsAutoConsumer(napi_env env, napi_callback_info info) +{ + napi_value val = nullptr; + bool isAutoConsumer = NativeImageAdaptor::GetInstance()->ChangeIsAutoConsumer(); + (void)napi_get_boolean(env, isAutoConsumer, &val); + return val; +} + +napi_value NativeImageAdaptor::NapiOnProduceBuffer(napi_env env, napi_callback_info info) +{ + napi_value val = nullptr; + int32_t ret = NativeImageAdaptor::GetInstance()-> + ProduceBuffer(0x00, NativeImageAdaptor::GetInstance()->nativeWindow_); + (void)napi_create_int32(env, ret, &val); + return val; +} + +napi_value NativeImageAdaptor::NapiOnConsumerBuffer(napi_env env, napi_callback_info info) +{ + napi_value val = nullptr; + int32_t ret = NativeImageAdaptor::GetInstance()-> + ConsumerBuffer(0x00, NativeImageAdaptor::GetInstance()->nativeWindow_); + (void)napi_create_int32(env, ret, &val); + return val; +} + NativeImageAdaptor::~NativeImageAdaptor() { OH_NativeImage_UnsetOnFrameAvailableListener(image_); diff --git a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.h b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.h index 8bb635e55..307f26299 100644 --- a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.h +++ b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/cpp/NativeImageAdaptor.h @@ -35,16 +35,20 @@ public: ~NativeImageAdaptor(); static NativeImageAdaptor *GetInstance(); static napi_value GetAvailableCount(napi_env env, napi_callback_info info); + static napi_value NapiOnChangeIsAutoConsumer(napi_env env, napi_callback_info info); static napi_value NapiOnGetAttachBufferCount(napi_env env, napi_callback_info info); static napi_value NapiOnGetBufferQueueSize(napi_env env, napi_callback_info info); static napi_value NapiOnGetCacheBufferCount(napi_env env, napi_callback_info info); static napi_value NapiOnProduceBuffer(napi_env env, napi_callback_info info); + static napi_value NapiOnConsumerBuffer(napi_env env, napi_callback_info info); static napi_value NapiOnAttachBuffer(napi_env env, napi_callback_info info); static napi_value NapiOnDettachBuffer(napi_env env, napi_callback_info info); + static void OnFrameAvailable(void *context); void DealCallback(void *context); bool Export(napi_env env, napi_value exports); - void ProduceBuffer(uint32_t value, OHNativeWindow *InNativeWindow); + int32_t ProduceBuffer(uint32_t value, OHNativeWindow *InNativeWindow); + int32_t ConsumerBuffer(uint32_t value, OHNativeWindow *InNativeWindow); void InitEGLEnv(); bool InitNativeWindow(); bool InitNativeWindowCache(); @@ -56,6 +60,7 @@ public: int32_t GetAttachBufferCount(); int32_t GetBufferQueueSize(); int32_t GetCacheBufferCount(); + bool ChangeIsAutoConsumer(); private: void SetConfigAndGetValue(); @@ -73,6 +78,7 @@ private: std::mutex opMutex_; std::queue bufferCache_; std::queue bufferAttached_; + bool isAutoConsumer_; }; } #endif // NdkNativeWindow_NativeImageAdaptor_H diff --git a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/interface/NativeWindowContext.ts b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/interface/NativeWindowContext.ts index a4e92ccc5..7a1dfe24b 100644 --- a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/interface/NativeWindowContext.ts +++ b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/interface/NativeWindowContext.ts @@ -30,7 +30,9 @@ export default interface NativeWindowContext { DrawColor(): void; ChangeScalingMode(): void; - ProduceBuffer(): void; + ProduceBuffer(): number; + ConsumerBuffer(): number; + ChangeIsAutoConsumer(): boolean; GetAvailableCount(): number; AttachBuffer(): void; DettachBuffer(): void; diff --git a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/pages/Index.ets b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/pages/Index.ets index 0e2863ed2..bebe34442 100644 --- a/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/pages/Index.ets +++ b/code/BasicFeature/Native/NdkNativeWindow/entry/src/main/ets/pages/Index.ets @@ -26,6 +26,8 @@ struct Index { @State bufferQueueSize: number = 3; @State attachedBufferCount: number = 0; @State frameFlushedCount: number = 0; + @State frameConsumerCount: number = 0; + @State isAutoConsumer: boolean = false; private nativeWindowContext: NativeWindowContext | undefined = undefined; build() { @@ -70,12 +72,39 @@ struct Index { .onClick(() => { if (this.nativeWindowContext) { console.log(TAG, "Produce Buffer"); - this.nativeWindowContext.ProduceBuffer(); - this.frameFlushedCount++; + if (this.nativeWindowContext.ProduceBuffer() ==0) { + this.frameFlushedCount++; + } setTimeout("GetCount", 1000); } }) .height(40) + Row() { + Button(`auto consumer=${this.isAutoConsumer}`) + .fontSize('14fp') + .fontWeight(500) + .margin({ bottom: 24 }) + .onClick(() => { + if (this.nativeWindowContext) { + this.isAutoConsumer = this.nativeWindowContext.ChangeIsAutoConsumer(); + } + }) + .height(40) + Button(`consumer buffer count=${this.frameConsumerCount}`) + .fontSize('14fp') + .fontWeight(500) + .margin({ bottom: 24 }) + .onClick(() => { + if (this.nativeWindowContext) { + console.log(TAG, "Consumer Buffer"); + if (this.nativeWindowContext.ConsumerBuffer() == 0) { + this.frameConsumerCount++; + } + setTimeout("GetCount", 1000); + } + }) + .height(40) + } Button(`update available buffer count=${this.frameAvailableCount}`) .fontSize('14fp') .fontWeight(500)