mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-10-07 08:24:11 +00:00
!43758 【5.0 Release】XComponent-Texture对接buffer轮转fence机制
Merge pull request !43758 from sunbees/text-fence-5.0
This commit is contained in:
commit
da9077c51f
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -130,6 +130,8 @@ public:
|
||||
|
||||
virtual void Disconnect() const {};
|
||||
|
||||
virtual void RegisterBufferCallback() {}
|
||||
|
||||
protected:
|
||||
ACE_DISALLOW_COPY_AND_MOVE(RenderSurface);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user