diff --git a/frameworks/surface/include/consumer_surface.h b/frameworks/surface/include/consumer_surface.h index 7d631411e31d5079d988e2be9294d4ccb1e79564..bdff10f9686495f70a9eaef3823879a07ae5ddb5 100644 --- a/frameworks/surface/include/consumer_surface.h +++ b/frameworks/surface/include/consumer_surface.h @@ -117,6 +117,7 @@ public: GSError SetDefaultColorGamut(int32_t colorGamut) override; sptr GetNativeSurface() override; + GSError SetWptrNativeWindowToPSurface(void* nativeWindow) override; private: std::map userData_; diff --git a/frameworks/surface/include/native_window.h b/frameworks/surface/include/native_window.h index f2fe9a0a2c26f2099abe4cb35ad2704fcd6d26f7..c2c10a9aab13a8595c7d80accea6735656aaa4c0 100644 --- a/frameworks/surface/include/native_window.h +++ b/frameworks/surface/include/native_window.h @@ -21,6 +21,7 @@ #include #include #include +#include struct NativeWindowMagic : public OHOS::RefBase { @@ -35,6 +36,7 @@ struct NativeWindow : public NativeWindowMagic { OHOS::BufferRequestConfig config = {0}; OHOS::sptr surface; int64_t uiTimestamp = 0; + std::unordered_map bufferCache_; }; struct NativeWindowBuffer : public NativeWindowMagic { diff --git a/frameworks/surface/include/producer_surface.h b/frameworks/surface/include/producer_surface.h index f29b2dec25b09af7735692c2cc1e3dc43971cc90..0dfb7c14449cba194801bed07a1a9554b33632eb 100644 --- a/frameworks/surface/include/producer_surface.h +++ b/frameworks/surface/include/producer_surface.h @@ -27,6 +27,7 @@ #include "buffer_queue_consumer.h" #include "surface_buffer.h" +struct NativeWindow; namespace OHOS { class ProducerSurface : public Surface { public: @@ -118,9 +119,10 @@ public: GSError SetDefaultColorGamut(int32_t colorGamut) override; sptr GetNativeSurface() override; - + GSError SetWptrNativeWindowToPSurface(void* nativeWindow) override; private: bool IsRemote(); + void CleanAllLocked(); std::mutex mutex_; std::atomic_bool inited_ = false; @@ -131,6 +133,7 @@ private: uint64_t queueId_ = 0; bool isDisconnected = true; sptr listener_; + wptr wpNativeWindow_ = nullptr; }; } // namespace OHOS diff --git a/frameworks/surface/src/consumer_surface.cpp b/frameworks/surface/src/consumer_surface.cpp index 288c9f5def0be9f534ad0ae23cf32bb2253290e8..b89b8d32235c522758fa5cd61c06ab0fea460d43 100644 --- a/frameworks/surface/src/consumer_surface.cpp +++ b/frameworks/surface/src/consumer_surface.cpp @@ -422,4 +422,10 @@ sptr ConsumerSurface::GetNativeSurface() BLOGND("ConsumerSurface::GetNativeSurface not support."); return nullptr; } + +GSError ConsumerSurface::SetWptrNativeWindowToPSurface(void* nativeWindow) +{ + BLOGND("ConsumerSurface::SetWptrNativeWindowToPSurface not support."); + return GSERROR_NOT_SUPPORT; +} } // namespace OHOS diff --git a/frameworks/surface/src/native_window.cpp b/frameworks/surface/src/native_window.cpp index cbcbf1bba9a020d5b87e9b0d3e95aebe036e3a18..77c968390b5c4493331580f688807ec2abbcfdcb 100644 --- a/frameworks/surface/src/native_window.cpp +++ b/frameworks/surface/src/native_window.cpp @@ -49,6 +49,7 @@ OHNativeWindow* CreateNativeWindowFromSurface(void* pSurface) nativeWindow->config.transform = GraphicTransformType::GRAPHIC_ROTATE_NONE; NativeObjectReference(nativeWindow); + nativeWindow->surface->SetWptrNativeWindowToPSurface(nativeWindow); return nativeWindow; } @@ -97,10 +98,18 @@ int32_t NativeWindowRequestBuffer(OHNativeWindow *window, ret, window->surface->GetUniqueId()); return OHOS::GSERROR_NO_BUFFER; } - OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer(); - nwBuffer->sfbuffer = sfbuffer; - nwBuffer->uiTimestamp = window->uiTimestamp; - *buffer = nwBuffer; + uint32_t seqNum = sfbuffer->GetSeqNum(); + if (window->bufferCache_.find(seqNum) == window->bufferCache_.end()) { + OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer(); + nwBuffer->sfbuffer = sfbuffer; + nwBuffer->uiTimestamp = window->uiTimestamp; + *buffer = nwBuffer; + // Add to cache + NativeObjectReference(nwBuffer); + window->bufferCache_[seqNum] = nwBuffer; + } else { + *buffer = window->bufferCache_[seqNum]; + } *fenceFd = releaseFence->Dup(); return OHOS::GSERROR_OK; } @@ -363,6 +372,9 @@ NativeWindow::NativeWindow() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW), su NativeWindow::~NativeWindow() { + for (auto &[seqNum, buffer] : bufferCache_) { + NativeObjectUnreference(buffer); + } } NativeWindowBuffer::~NativeWindowBuffer() diff --git a/frameworks/surface/src/producer_surface.cpp b/frameworks/surface/src/producer_surface.cpp index d8e69cc12a7bb6978f6bf13d87048658c3746947..8e6edfa92150219d067566289b236df5fbfd7bae 100644 --- a/frameworks/surface/src/producer_surface.cpp +++ b/frameworks/surface/src/producer_surface.cpp @@ -22,6 +22,7 @@ #include "buffer_extra_data_impl.h" #include "buffer_producer_listener.h" #include "sync_fence.h" +#include "native_window.h" namespace OHOS { namespace { @@ -95,7 +96,7 @@ GSError ProducerSurface::RequestBuffer(sptr& buffer, if (ret != GSERROR_OK) { if (ret == GSERROR_NO_CONSUMER) { std::lock_guard lockGuard(mutex_); - bufferProducerCache_.clear(); + CleanAllLocked(); } BLOGND("Producer report %{public}s", GSErrorStr(ret).c_str()); return ret; @@ -128,10 +129,20 @@ GSError ProducerSurface::RequestBuffer(sptr& buffer, } for (auto it = retval.deletingBuffers.begin(); it != retval.deletingBuffers.end(); it++) { - bufferProducerCache_.erase(*it); + uint32_t seqNum = *it; + bufferProducerCache_.erase(seqNum); + auto spNativeWindow = wpNativeWindow_.promote(); + if (spNativeWindow != nullptr) { + auto &bufferCache = spNativeWindow->bufferCache_; + if (bufferCache.find(seqNum) != bufferCache.end()) { + bufferCache.erase(seqNum); + NativeObjectUnreference(bufferCache[seqNum]); + } + } } return GSERROR_OK; } + GSError ProducerSurface::FlushBuffer(sptr& buffer, const sptr& fence, BufferFlushConfig &config) { @@ -331,12 +342,21 @@ bool ProducerSurface::IsRemote() return producer_->AsObject()->IsProxyObject(); } +void ProducerSurface::CleanAllLocked() +{ + bufferProducerCache_.clear(); + auto spNativeWindow = wpNativeWindow_.promote(); + if (spNativeWindow != nullptr) { + spNativeWindow->bufferCache_.clear(); + } +} + GSError ProducerSurface::CleanCache() { BLOGND("Queue Id:%{public}" PRIu64, queueId_); { std::lock_guard lockGuard(mutex_); - bufferProducerCache_.clear(); + CleanAllLocked(); } return producer_->CleanCache(); } @@ -346,7 +366,7 @@ GSError ProducerSurface::GoBackground() BLOGND("Queue Id:%{public}" PRIu64 "", queueId_); { std::lock_guard lockGuard(mutex_); - bufferProducerCache_.clear(); + CleanAllLocked(); } return producer_->GoBackground(); } @@ -389,7 +409,7 @@ GSError ProducerSurface::Disconnect() BLOGND("Queue Id:%{public}" PRIu64 "", queueId_); { std::lock_guard lockGuard(mutex_); - bufferProducerCache_.clear(); + CleanAllLocked(); } GSError ret = producer_->Disconnect(); { @@ -504,4 +524,11 @@ sptr ProducerSurface::GetNativeSurface() BLOGND("ProducerSurface::GetNativeSurface not support."); return nullptr; } + +GSError ProducerSurface::SetWptrNativeWindowToPSurface(void* nativeWindow) +{ + NativeWindow *nw = reinterpret_cast(nativeWindow); + wpNativeWindow_ = nw; + return GSERROR_OK; +} } // namespace OHOS diff --git a/frameworks/surface/test/unittest/producer_surface_test.cpp b/frameworks/surface/test/unittest/producer_surface_test.cpp index 09d4e2d6d8d825e175bb0ab4ac9e7aea96ace6cb..ed7d812fd1f5a62b4e9f0536f265b1b5e1cacd0f 100644 --- a/frameworks/surface/test/unittest/producer_surface_test.cpp +++ b/frameworks/surface/test/unittest/producer_surface_test.cpp @@ -17,6 +17,7 @@ #include #include #include "buffer_consumer_listener.h" +#include using namespace testing; using namespace testing::ext; @@ -744,4 +745,19 @@ HWTEST_F(ProducerSurfaceTest, presentTimestamp004, Function | MediumTest | Level ret = pSurface->CancelBuffer(buffer); ASSERT_EQ(ret, OHOS::GSERROR_OK); } + +/* +* Function: SetWptrNativeWindowToPSurface +* Type: Function +* Rank: Important(1) +* EnvConditions: N/A +* CaseDescription: 1. SetWptrNativeWindowToPSurface and check ret +* @tc.require: issueI7WYIY + */ +HWTEST_F(ProducerSurfaceTest, SetWptrNativeWindowToPSurface001, Function | MediumTest | Level1) +{ + struct NativeWindow nativeWindow; + GSError ret = pSurface->SetWptrNativeWindowToPSurface(&nativeWindow); + ASSERT_EQ(ret, OHOS::GSERROR_OK); +} } diff --git a/interfaces/inner_api/surface/iconsumer_surface.h b/interfaces/inner_api/surface/iconsumer_surface.h index c5bc6d49c3ea107958c438653539d7f4011f274d..8033e92c1258c4fc86e4555759a112ce64486730 100644 --- a/interfaces/inner_api/surface/iconsumer_surface.h +++ b/interfaces/inner_api/surface/iconsumer_surface.h @@ -120,6 +120,7 @@ public: int64_t ×tamp, std::vector &damages) = 0; virtual GSError FlushBuffer(sptr& buffer, const sptr& fence, BufferFlushConfigWithDamages &config) = 0; + virtual GSError SetWptrNativeWindowToPSurface(void* nativeWindow) = 0; protected: IConsumerSurface() = default; }; diff --git a/interfaces/inner_api/surface/surface.h b/interfaces/inner_api/surface/surface.h index b42f85692d44eccf2e77f8a94fbe4b841cbf34d1..f6d05ecc3810b963c5f6983283c00a085771783f 100644 --- a/interfaces/inner_api/surface/surface.h +++ b/interfaces/inner_api/surface/surface.h @@ -119,6 +119,7 @@ public: virtual GSError FlushBuffer(sptr& buffer, const sptr& fence, BufferFlushConfigWithDamages &config) = 0; virtual GSError UnRegisterReleaseListener() = 0; + virtual GSError SetWptrNativeWindowToPSurface(void* nativeWindow) = 0; protected: Surface() = default; }; diff --git a/rosen/modules/render_service_client/core/pipeline/rs_render_thread_visitor.cpp b/rosen/modules/render_service_client/core/pipeline/rs_render_thread_visitor.cpp index 25bcebc35713a691c5a7e51e6cebd0276bd9e9e9..4f525d42795d7e69a5d4a321db73bbeb1ca0035d 100644 --- a/rosen/modules/render_service_client/core/pipeline/rs_render_thread_visitor.cpp +++ b/rosen/modules/render_service_client/core/pipeline/rs_render_thread_visitor.cpp @@ -347,6 +347,8 @@ void RSRenderThreadVisitor::UpdateDirtyAndSetEGLDamageRegion(std::unique_ptrGetBufferAge(); #endif + // we'll fix this in Split Render Mode. + bufferAge = 0; if (!curDirtyManager_->SetBufferAge(bufferAge)) { ROSEN_LOGD("ProcessRootRenderNode SetBufferAge with invalid buffer age %{public}d", bufferAge); curDirtyManager_->ResetDirtyAsSurfaceSize();