!43758 【5.0 Release】XComponent-Texture对接buffer轮转fence机制

Merge pull request !43758 from sunbees/text-fence-5.0
This commit is contained in:
openharmony_ci 2024-09-21 06:52:21 +00:00 committed by Gitee
commit da9077c51f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 147 additions and 30 deletions

View File

@ -242,8 +242,18 @@ void XComponentPattern::InitSurface()
}
renderSurface_->InitSurface();
renderSurface_->UpdateSurfaceConfig();
if (type_ == XComponentType::TEXTURE) {
renderSurface_->RegisterBufferCallback();
}
surfaceId_ = renderSurface_->GetUniqueId();
UpdateTransformHint();
}
void XComponentPattern::UpdateTransformHint()
{
auto host = GetHost();
CHECK_NULL_VOID(host);
auto pipelineContext = host->GetContextRefPtr();
CHECK_NULL_VOID(pipelineContext);
pipelineContext->AddWindowStateChangedCallback(host->GetId());

View File

@ -375,6 +375,7 @@ private:
void UpdateAnalyzerOverlay();
void UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode);
void ReleaseImageAnalyzer();
void UpdateTransformHint();
void SetRotation(uint32_t rotation);
void RegisterSurfaceCallbackModeEvent();
#ifdef OHOS_PLATFORM

View File

@ -17,6 +17,7 @@
#include "render_service_client/core/ui/rs_surface_node.h"
#include "surface_utils.h"
#include "sync_fence.h"
#include "transaction/rs_interfaces.h"
#include "base/log/dump_log.h"
#include "base/memory/referenced.h"
@ -76,22 +77,38 @@ struct SurfaceBufferNode {
sptr<SurfaceBuffer> buffer_;
sptr<SyncFence> fence_;
OffsetF orgin_ { 0, 0 };
uint32_t bufferId_ {};
uint32_t sendTimes_ = 0;
};
#endif
RosenRenderSurface::~RosenRenderSurface()
{
if (SystemProperties::GetExtSurfaceEnabled() && surfaceDelegate_) {
surfaceDelegate_->ReleaseSurface();
} else {
if (nativeWindow_) {
DestoryNativeWindow(nativeWindow_);
nativeWindow_ = nullptr;
}
UnregisterSurface();
return;
}
if (nativeWindow_) {
DestoryNativeWindow(nativeWindow_);
nativeWindow_ = nullptr;
}
UnregisterSurface();
if (isTexture_) {
Rosen::RSInterfaces::GetInstance().UnregisterSurfaceBufferCallback(getpid(), GetUniqueIdNum());
std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
while (!availableBuffers_.empty()) {
auto surfaceNode = availableBuffers_.front();
availableBuffers_.pop();
consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
if (surfaceNode) {
consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
}
}
auto iter = availableBufferList_.begin();
while (iter != availableBufferList_.end()) {
auto surfaceNode = *iter;
if (surfaceNode) {
consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
}
iter = availableBufferList_.erase(iter);
}
}
}
@ -234,6 +251,14 @@ std::string RosenRenderSurface::GetUniqueId() const
return std::to_string(producerSurface_->GetUniqueId());
}
uint64_t RosenRenderSurface::GetUniqueIdNum() const
{
if (!producerSurface_) {
return 0;
}
return producerSurface_->GetUniqueId();
}
void RosenRenderSurface::SetExtSurfaceBounds(int32_t left, int32_t top, int32_t width, int32_t height)
{
if (SystemProperties::GetExtSurfaceEnabled() && surfaceDelegate_) {
@ -426,24 +451,22 @@ void RosenRenderSurface::ConsumeXComponentBuffer()
OHOS::Rect damage;
SurfaceError surfaceErr = consumerSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
if (surfaceErr != SURFACE_ERROR_OK) {
if (surfaceErr != SURFACE_ERROR_OK || !surfaceBuffer) {
TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "XComponent cannot acquire buffer error = %{public}d", surfaceErr);
return;
}
PostRenderOnlyTaskToUI();
std::shared_ptr<SurfaceBufferNode> surfaceNode = nullptr;
auto surfaceNode = std::make_shared<SurfaceBufferNode>(surfaceBuffer, fence, orgin_);
CHECK_NULL_VOID(surfaceNode);
surfaceNode->bufferId_ = surfaceBuffer->GetSeqNum();
{
std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
if (availableBuffers_.size() >= MAX_BUFFER_SIZE) {
surfaceNode = availableBuffers_.front();
availableBuffers_.pop();
surfaceErr = consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
if (surfaceErr != SURFACE_ERROR_OK) {
TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "XComponent release buffer error = %{public}d", surfaceErr);
}
auto lastSurfaceNode = availableBufferList_.back();
if (lastSurfaceNode && lastSurfaceNode->sendTimes_ <= 0) {
consumerSurface_->ReleaseBuffer(lastSurfaceNode->buffer_, SyncFence::INVALID_FENCE);
availableBufferList_.pop_back();
}
availableBuffers_.push(std::make_shared<SurfaceBufferNode>(surfaceBuffer, fence, orgin_));
availableBufferList_.emplace_back(surfaceNode);
}
#endif
}
@ -456,11 +479,15 @@ void RosenRenderSurface::ReleaseSurfaceBuffers()
CHECK_NULL_VOID(consumerSurface_);
{
std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
while (availableBuffers_.size() > 1) {
auto surfaceNode = availableBuffers_.front();
availableBuffers_.pop();
if (surfaceNode) {
consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
if (!availableBufferList_.empty()) {
auto iter = availableBufferList_.begin();
auto lastIter = std::prev(availableBufferList_.end());
while (iter != lastIter) {
auto surfaceNode = *iter;
if (surfaceNode) {
consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
}
iter = availableBufferList_.erase(iter);
}
}
}
@ -478,13 +505,14 @@ void RosenRenderSurface::DrawBufferForXComponent(
{
std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
if (!availableBuffers_.empty()) {
surfaceNode = availableBuffers_.back();
if (!availableBufferList_.empty()) {
surfaceNode = availableBufferList_.back();
}
}
if (!surfaceNode) {
TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "surfaceNode is null");
return;
if (!surfaceNode) {
TAG_LOGW(AceLogTag::ACE_XCOMPONENT, "surfaceNode is null");
return;
}
++surfaceNode->sendTimes_;
}
ACE_SCOPED_TRACE("XComponent DrawBuffer");
#ifndef USE_ROSEN_DRAWING
@ -500,7 +528,7 @@ void RosenRenderSurface::DrawBufferForXComponent(
#else
auto& recordingCanvas = static_cast<RSRecordingCanvas&>(canvas);
Rosen::DrawingSurfaceBufferInfo info { surfaceNode->buffer_, offsetX, offsetY, static_cast<int32_t>(width),
static_cast<int32_t>(height) };
static_cast<int32_t>(height), getpid(), GetUniqueIdNum() };
recordingCanvas.DrawSurfaceBuffer(info);
#endif
CHECK_NULL_VOID(recordingCanvas.GetDrawCmdList());
@ -509,6 +537,40 @@ void RosenRenderSurface::DrawBufferForXComponent(
#endif
}
void RosenRenderSurface::RegisterBufferCallback()
{
#ifdef OHOS_PLATFORM
CHECK_EQUAL_VOID(isTexture_, false);
auto pid = getpid();
auto uid = GetUniqueIdNum();
if (!bufferCallback_) {
bufferCallback_ = std::make_shared<XComponentSurfaceBufferCallback>(WeakClaim(this));
}
Rosen::RSInterfaces::GetInstance().RegisterSurfaceBufferCallback(pid, uid, bufferCallback_);
#endif
}
void RosenRenderSurface::ReleaseSurfaceBufferById(uint32_t bufferId)
{
std::lock_guard<std::mutex> lock(surfaceNodeMutex_);
auto iter = availableBufferList_.begin();
while (iter != availableBufferList_.end()) {
auto surfaceNode = *iter;
if (!surfaceNode) {
iter = availableBufferList_.erase(iter);
} else if (surfaceNode->bufferId_ == bufferId) {
// at least reserve one buffer
if (--surfaceNode->sendTimes_ <= 0 && (iter != std::prev(availableBufferList_.end()))) {
consumerSurface_->ReleaseBuffer(surfaceNode->buffer_, SyncFence::INVALID_FENCE);
availableBufferList_.erase(iter);
}
return;
} else {
++iter;
}
}
}
void DrawBufferListener::OnBufferAvailable()
{
auto renderSurface = renderSurface_.Upgrade();
@ -520,6 +582,20 @@ void DrawBufferListener::OnBufferAvailable()
}
}
#ifdef OHOS_PLATFORM
void XComponentSurfaceBufferCallback::OnFinish(uint64_t uid, const std::vector<uint32_t>& surfaceBufferIds)
{
auto renderSurface = renderSurface_.Upgrade();
CHECK_NULL_VOID(renderSurface);
if (uid != renderSurface->GetUniqueIdNum()) {
return;
}
for (const auto& bufferId : surfaceBufferIds) {
renderSurface->ReleaseSurfaceBufferById(bufferId);
}
}
#endif
void ExtSurfaceCallback::OnSurfaceCreated(const sptr<Surface>& /* surface */)
{
auto interface = weakInterface_.Upgrade();

View File

@ -22,6 +22,7 @@
#include "surface.h"
#include "surface_delegate.h"
#include "surface/window.h"
#include "transaction/rs_render_service_client.h"
#endif
#include "base/memory/referenced.h"
@ -60,6 +61,8 @@ public:
std::string GetUniqueId() const override;
uint64_t GetUniqueIdNum() const;
void SetIsTexture(bool isTexture) override
{
isTexture_ = isTexture;
@ -139,6 +142,10 @@ public:
void DumpInfo() override;
void ReleaseSurfaceBufferById(uint32_t bufferId);
void RegisterBufferCallback() override;
private:
void PostRenderOnlyTaskToUI();
@ -155,6 +162,8 @@ private:
struct NativeWindow* nativeWindow_ = nullptr;
sptr<OHOS::SurfaceDelegate> surfaceDelegate_;
std::queue<std::shared_ptr<SurfaceBufferNode>> availableBuffers_;
std::list<std::shared_ptr<SurfaceBufferNode>> availableBufferList_;
std::shared_ptr<Rosen::SurfaceBufferCallback> bufferCallback_;
int32_t failTimes_ = 0;
#endif
WeakPtr<NG::RenderContext> renderContext_ = nullptr;
@ -172,6 +181,18 @@ public:
~DrawBufferListener() override = default;
void OnBufferAvailable() override;
private:
WeakPtr<NG::RosenRenderSurface> renderSurface_;
};
class XComponentSurfaceBufferCallback : public Rosen::SurfaceBufferCallback {
public:
explicit XComponentSurfaceBufferCallback(const WeakPtr<NG::RosenRenderSurface>& renderSurface)
: renderSurface_(renderSurface)
{}
virtual ~XComponentSurfaceBufferCallback() = default;
void OnFinish(uint64_t uid, const std::vector<uint32_t>& surfaceBufferIds) override;
private:
WeakPtr<NG::RosenRenderSurface> renderSurface_;
};

View File

@ -103,4 +103,11 @@ void RosenRenderSurface::Connect() const {}
void RosenRenderSurface::Disconnect() const {}
uint64_t RosenRenderSurface::GetUniqueIdNum() const
{
return 0;
}
void RosenRenderSurface::RegisterBufferCallback() {}
} // namespace OHOS::Ace::NG

View File

@ -130,6 +130,8 @@ public:
virtual void Disconnect() const {};
virtual void RegisterBufferCallback() {}
protected:
ACE_DISALLOW_COPY_AND_MOVE(RenderSurface);
};