mirror of
https://github.com/openharmony/ace_ace_engine.git
synced 2026-07-21 09:55:23 -04:00
fix clip hole of camera
Signed-off-by: caocan <1532643766@qq.com> Change-Id: I652bc31791406b0ebab984771a41d61557181ce6
This commit is contained in:
@@ -107,6 +107,7 @@ class MockRenderContext : public RenderContext {
|
||||
public:
|
||||
void Repaint(const RefPtr<RenderNode>& node) override {};
|
||||
void PaintChild(const RefPtr<RenderNode>& child, const Offset& offset) override {};
|
||||
void Restore() override {};
|
||||
};
|
||||
|
||||
RefPtr<RenderContext> RenderContext::Create()
|
||||
|
||||
@@ -51,7 +51,11 @@ const char REGION_POSITION_Y[] = "region_position_y";
|
||||
const char REGION_WIDTH[] = "region_width";
|
||||
const char REGION_HEIGHT[] = "region_height";
|
||||
constexpr int32_t DEFAULT_WIDTH = 640;
|
||||
#ifdef PRODUCT_RK
|
||||
constexpr int32_t DEFAULT_HEIGHT = 480;
|
||||
#else
|
||||
constexpr int32_t DEFAULT_HEIGHT = 360;
|
||||
#endif
|
||||
constexpr int32_t SURFACE_STRIDE_ALIGNMENT_VAL = 8;
|
||||
constexpr int32_t PREVIEW_SURFACE_WIDTH = 640;
|
||||
constexpr int32_t PREVIEW_SURFACE_HEIGHT = 480;
|
||||
@@ -231,6 +235,10 @@ sptr<Surface> CameraCallback::createSubWindowSurface()
|
||||
return nullptr;
|
||||
}
|
||||
subwindow_->GetSurface()->SetQueueSize(QUEUE_SIZE);
|
||||
hasMarkWhole_ = false;
|
||||
subwindow_->OnBeforeFrameSubmit([this]() {
|
||||
OnFirstBufferAvailable();
|
||||
});
|
||||
}
|
||||
previewSurface_ = subwindow_->GetSurface();
|
||||
previewSurface_->SetUserData(SURFACE_STRIDE_ALIGNMENT, std::to_string(SURFACE_STRIDE_ALIGNMENT_VAL));
|
||||
@@ -245,10 +253,19 @@ sptr<Surface> CameraCallback::createSubWindowSurface()
|
||||
previewSurface_->SetUserData(REGION_HEIGHT, std::to_string(windowSize_.Height()));
|
||||
previewSurface_->SetUserData(REGION_POSITION_X, std::to_string(windowOffset_.GetX()));
|
||||
previewSurface_->SetUserData(REGION_POSITION_Y, std::to_string(windowOffset_.GetY()));
|
||||
MarkWhole();
|
||||
return previewSurface_;
|
||||
}
|
||||
|
||||
void CameraCallback::OnFirstBufferAvailable()
|
||||
{
|
||||
if (hasMarkWhole_) {
|
||||
return;
|
||||
}
|
||||
LOGI("CameraCallback:OnFirstBufferAvailable first MarkWhole.");
|
||||
MarkWhole();
|
||||
hasMarkWhole_ = true;
|
||||
}
|
||||
|
||||
void CameraCallback::MarkWhole()
|
||||
{
|
||||
auto context = context_.Upgrade();
|
||||
@@ -262,14 +279,16 @@ void CameraCallback::MarkWhole()
|
||||
if (renderNode) {
|
||||
renderNode->SetHasSubWindow(true);
|
||||
}
|
||||
RenderNode::MarkWholeRender(renderNode_, true);
|
||||
LOGI("CameraCallback:MarkWhole success.");
|
||||
}
|
||||
|
||||
void CameraCallback::SetLayoutOffset(double x, double y)
|
||||
{
|
||||
layoutOffset_.SetX(x);
|
||||
layoutOffset_.SetY(y);
|
||||
if (subwindow_) {
|
||||
LOGI("CameraCallback::SetLayoutOffset: move %{public}lf %{public}lf ", x, y);
|
||||
if (hasMarkWhole_ && subwindow_) {
|
||||
LOGI("CameraCallback:Hole change %{public}lf %{public}lf ", x, y);
|
||||
MarkWhole();
|
||||
}
|
||||
}
|
||||
@@ -397,8 +416,13 @@ int32_t CameraCallback::PrepareCamera(bool bIsRecorder)
|
||||
surface = createSubWindowSurface();
|
||||
LOGI("Preview surface width: %{public}d, height: %{public}d", surface->GetDefaultWidth(),
|
||||
surface->GetDefaultHeight());
|
||||
#ifdef PRODUCT_RK
|
||||
previewOutput_ = camManagerObj->CreateCustomPreviewOutput(surface, PREVIEW_SURFACE_WIDTH,
|
||||
PREVIEW_SURFACE_HEIGHT);
|
||||
#else
|
||||
previewOutput_ = camManagerObj->CreateCustomPreviewOutput(surface, surface->GetDefaultHeight(),
|
||||
surface->GetDefaultWidth());
|
||||
#endif
|
||||
if (previewOutput_ == nullptr) {
|
||||
LOGE("Failed to create PreviewOutput");
|
||||
return -1;
|
||||
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
void OnCameraSizeChange(double width, double height);
|
||||
void OnCameraOffsetChange(double x, double y);
|
||||
void MarkWhole();
|
||||
void OnFirstBufferAvailable();
|
||||
void SetLayoutOffset(double x, double y);
|
||||
void SetLayoutSize(double width, double height)
|
||||
{
|
||||
@@ -102,6 +103,8 @@ public:
|
||||
}
|
||||
friend class CaptureListener;
|
||||
|
||||
bool hasMarkWhole_ = false;
|
||||
|
||||
protected:
|
||||
void CloseRecorder();
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ class MockRenderContext : public RenderContext {
|
||||
public:
|
||||
void Repaint(const RefPtr<RenderNode>& node) override {};
|
||||
void PaintChild(const RefPtr<RenderNode>& child, const Offset& offset) override {};
|
||||
void Restore() override {};
|
||||
};
|
||||
|
||||
class MockRenderStack : public RenderStack {
|
||||
|
||||
@@ -135,6 +135,7 @@ class MockRenderContext : public RenderContext {
|
||||
public:
|
||||
void Repaint(const RefPtr<RenderNode>& node) override {};
|
||||
void PaintChild(const RefPtr<RenderNode>& child, const Offset& offset) override {};
|
||||
void Restore() override {};
|
||||
};
|
||||
|
||||
class MockRenderImage : public RenderImage {
|
||||
|
||||
@@ -107,6 +107,7 @@ class MockRenderContext : public RenderContext {
|
||||
public:
|
||||
void Repaint(const RefPtr<RenderNode>& node) override {};
|
||||
void PaintChild(const RefPtr<RenderNode>& child, const Offset& offset) override {};
|
||||
void Restore() override {};
|
||||
};
|
||||
|
||||
RefPtr<RenderContext> RenderContext::Create()
|
||||
|
||||
@@ -67,6 +67,14 @@ void FlutterRenderContext::PaintChild(const RefPtr<RenderNode>& child, const Off
|
||||
if (name != "FlutterRenderForm") {
|
||||
if (child->NeedRender()) {
|
||||
FlutterRenderContext context;
|
||||
auto pipelineContext = child->GetContext().Upgrade();
|
||||
LOGI("Hole: child canvas render");
|
||||
auto transparentHole = pipelineContext->GetTransparentHole();
|
||||
if (transparentHole.IsValid() && child->GetNeedClip()) {
|
||||
Offset childOffset = rect.GetOffset();
|
||||
Rect hole = transparentHole - childOffset;
|
||||
context.SetClipHole(hole);
|
||||
}
|
||||
context.Repaint(child);
|
||||
} else {
|
||||
// No need to repaint, notify to update AccessibilityNode info.
|
||||
@@ -110,6 +118,12 @@ void FlutterRenderContext::StartRecording()
|
||||
recorder_ = flutter::PictureRecorder::Create();
|
||||
canvas_ = flutter::Canvas::Create(
|
||||
recorder_.get(), estimatedRect_.Left(), estimatedRect_.Top(), estimatedRect_.Right(), estimatedRect_.Bottom());
|
||||
if (clipHole_.IsValid()) {
|
||||
canvas_->save();
|
||||
needRestoreHole_ = true;
|
||||
canvas_->clipRect(clipHole_.Left(), clipHole_.Top(),
|
||||
clipHole_.Right(), clipHole_.Bottom(), SkClipOp::kDifference);
|
||||
}
|
||||
containerLayer_->AddChildren(currentLayer_);
|
||||
}
|
||||
|
||||
@@ -119,6 +133,10 @@ void FlutterRenderContext::StopRecordingIfNeeded()
|
||||
return;
|
||||
}
|
||||
|
||||
if (needRestoreHole_) {
|
||||
canvas_->restore();
|
||||
needRestoreHole_ = false;
|
||||
}
|
||||
currentLayer_->SetPicture(recorder_->endRecording());
|
||||
currentLayer_ = nullptr;
|
||||
recorder_ = nullptr;
|
||||
@@ -144,29 +162,6 @@ bool FlutterRenderContext::IsIntersectWith(const RefPtr<RenderNode>& child, Offs
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlutterRenderContext::ClipHoleBegin(const Rect& holeRect)
|
||||
{
|
||||
auto canvas = GetCanvas();
|
||||
if (!canvas) {
|
||||
return;
|
||||
}
|
||||
LOGI("Hole: PrePaint save clip.");
|
||||
canvas->save();
|
||||
if (holeRect.IsValid()) {
|
||||
canvas->clipRect(holeRect.Left(), holeRect.Top(), holeRect.Right(), holeRect.Bottom(), SkClipOp::kDifference);
|
||||
}
|
||||
}
|
||||
|
||||
void FlutterRenderContext::ClipHoleEnd()
|
||||
{
|
||||
LOGI("Hole: PostPaint restore clip");
|
||||
auto canvas = GetCanvas();
|
||||
if (!canvas) {
|
||||
return;
|
||||
}
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
void FlutterRenderContext::InitContext(RenderLayer layer, const Rect& rect)
|
||||
{
|
||||
LOGD("InitContext with width %{public}lf height %{public}lf", rect.Width(), rect.Height());
|
||||
@@ -183,4 +178,12 @@ flutter::Canvas* FlutterRenderContext::GetCanvas()
|
||||
return canvas_.get();
|
||||
}
|
||||
|
||||
void FlutterRenderContext::Restore()
|
||||
{
|
||||
auto canvas = GetCanvas();
|
||||
if (canvas != nullptr) {
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -39,8 +39,7 @@ public:
|
||||
void Repaint(const RefPtr<RenderNode>& node) override;
|
||||
void PaintChild(const RefPtr<RenderNode>& child, const Offset& offset) override;
|
||||
bool IsIntersectWith(const RefPtr<RenderNode>& child, Offset& offset) override;
|
||||
void ClipHoleBegin(const Rect& holeRect) override;
|
||||
void ClipHoleEnd() override;
|
||||
void Restore() override;
|
||||
|
||||
void InitContext(RenderLayer layer, const Rect& rect);
|
||||
flutter::Canvas* GetCanvas();
|
||||
|
||||
@@ -41,11 +41,26 @@ public:
|
||||
virtual void Repaint(const RefPtr<RenderNode>&) = 0;
|
||||
virtual void PaintChild(const RefPtr<RenderNode>&, const Offset& offset) = 0;
|
||||
virtual bool IsIntersectWith(const RefPtr<RenderNode>& child, Offset& offset) { return true; }
|
||||
virtual void ClipHoleBegin(const Rect& holeRect) {}
|
||||
virtual void ClipHoleEnd() {}
|
||||
virtual void Restore() = 0;
|
||||
virtual void SetClipHole(Rect clipHole)
|
||||
{
|
||||
clipHole_ = clipHole;
|
||||
}
|
||||
|
||||
void SetNeedRestoreHole(bool restore)
|
||||
{
|
||||
needRestoreHole_ = restore;
|
||||
}
|
||||
|
||||
bool GetNeedRestoreHole() const
|
||||
{
|
||||
return needRestoreHole_;
|
||||
}
|
||||
|
||||
protected:
|
||||
RenderContext() = default;
|
||||
Rect clipHole_;
|
||||
bool needRestoreHole_ = false;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef ENABLE_ROSEN_BACKEND
|
||||
#include "render_service_client/core/ui/rs_node.h"
|
||||
@@ -65,6 +67,51 @@ constexpr Dimension FOCUS_BOUNDARY = 4.0_vp; // focus padding + effect boundary,
|
||||
|
||||
RenderNode::RenderNode(bool takeBoundary) : takeBoundary_(takeBoundary) {}
|
||||
|
||||
void RenderNode::MarkTreeRender(const RefPtr<RenderNode>& root, bool& meetHole, bool needFlush)
|
||||
{
|
||||
if (root->GetHasSubWindow()) {
|
||||
meetHole = true;
|
||||
}
|
||||
|
||||
if (meetHole) {
|
||||
root->SetNeedClip(false);
|
||||
LOGD("Hole: has meet hole, no need clip");
|
||||
} else {
|
||||
root->SetNeedClip(true);
|
||||
LOGD("Hole: has not meet hole, need clip");
|
||||
}
|
||||
|
||||
if (needFlush) {
|
||||
root->MarkNeedRender();
|
||||
}
|
||||
LOGI("Hole: MarkTreeRender %{public}s", AceType::TypeName(Referenced::RawPtr(root)));
|
||||
bool subMeetHole = meetHole;
|
||||
for (auto child: root->GetChildren()) {
|
||||
MarkTreeRender(child, subMeetHole, needFlush);
|
||||
}
|
||||
meetHole = subMeetHole;
|
||||
}
|
||||
|
||||
void RenderNode::MarkWholeRender(const WeakPtr<RenderNode>& nodeWeak, bool needFlush)
|
||||
{
|
||||
auto node = nodeWeak.Upgrade();
|
||||
if (!node) {
|
||||
LOGE("Hole: MarkWholeRender node is null");
|
||||
return;
|
||||
}
|
||||
|
||||
auto parentWeak = node->GetParent();
|
||||
auto parent = parentWeak.Upgrade();
|
||||
while (parent) {
|
||||
node = parent;
|
||||
parentWeak = node->GetParent();
|
||||
parent = parentWeak.Upgrade();
|
||||
}
|
||||
|
||||
bool meetHole = false;
|
||||
MarkTreeRender(node, meetHole, needFlush);
|
||||
}
|
||||
|
||||
void RenderNode::AddChild(const RefPtr<RenderNode>& child, int32_t slot)
|
||||
{
|
||||
if (!child) {
|
||||
@@ -82,6 +129,10 @@ void RenderNode::AddChild(const RefPtr<RenderNode>& child, int32_t slot)
|
||||
std::advance(pos, slot);
|
||||
children_.insert(pos, child);
|
||||
child->SetParent(AceType::WeakClaim(this));
|
||||
auto context = context_.Upgrade();
|
||||
if (context && context->GetTransparentHole().IsValid()) {
|
||||
MarkWholeRender(AceType::WeakClaim(this), true);
|
||||
}
|
||||
child->SetDepth(GetDepth() + 1);
|
||||
OnChildAdded(child);
|
||||
disappearingNodes_.remove(child);
|
||||
@@ -316,7 +367,16 @@ void RenderNode::RenderWithContext(RenderContext& context, const Offset& offset)
|
||||
onLayoutReady_(std::string("\"layoutReady\",null,null"));
|
||||
}
|
||||
pendingDispatchLayoutReady_ = false;
|
||||
ClipHole(context, offset);
|
||||
if (GetHasSubWindow() || !GetNeedClip()) {
|
||||
LOGI("Hole: meet subwindow node or no need clip");
|
||||
if (context.GetNeedRestoreHole()) {
|
||||
context.Restore();
|
||||
context.SetNeedRestoreHole(false);
|
||||
context.SetClipHole(Rect());
|
||||
}
|
||||
} else {
|
||||
context.SetClipHole(context_.Upgrade()->GetTransparentHole());
|
||||
}
|
||||
Paint(context, offset);
|
||||
for (const auto& item : SortChildrenByZIndex(disappearingNodes_)) {
|
||||
PaintChild(item, context, offset);
|
||||
@@ -367,36 +427,6 @@ void RenderNode::PaintChild(const RefPtr<RenderNode>& child, RenderContext& cont
|
||||
}
|
||||
}
|
||||
|
||||
void RenderNode::ClipHole(RenderContext& context, const Offset& offset)
|
||||
{
|
||||
LOGD("Hole: PrePaint RenderNode");
|
||||
auto pipelineContext = GetContext().Upgrade();
|
||||
|
||||
if (pipelineContext && pipelineContext->GetIsHoleValid()) {
|
||||
if (!(pipelineContext->GetHasClipHole())) {
|
||||
if (!(pipelineContext->GetHasMeetSubWindowNode())) {
|
||||
context.ClipHoleBegin(pipelineContext->GetTransparentHole());
|
||||
pipelineContext->SetHasClipHole(true);
|
||||
} else {
|
||||
LOGI("Hole: hole status is wrong.");
|
||||
}
|
||||
} else {
|
||||
if (!(pipelineContext->GetHasMeetSubWindowNode())) {
|
||||
if (GetHasSubWindow()) {
|
||||
context.ClipHoleEnd();
|
||||
pipelineContext->SetHasMeetSubWindowNode(true);
|
||||
} else {
|
||||
LOGI("Hole: RenderNode has not SubWindow.");
|
||||
}
|
||||
} else {
|
||||
LOGI("Hole: now clip has done.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGD("Hole: hole is not valid.");
|
||||
}
|
||||
}
|
||||
|
||||
void RenderNode::MarkNeedLayout(bool selfOnly, bool forceParent)
|
||||
{
|
||||
bool addSelf = false;
|
||||
|
||||
@@ -68,6 +68,10 @@ public:
|
||||
using SlipFactorSetting = std::function<void(double)>;
|
||||
~RenderNode() override = default;
|
||||
|
||||
static void MarkTreeRender(const RefPtr<RenderNode>& root, bool& meetHole, bool needFlush);
|
||||
|
||||
static void MarkWholeRender(const WeakPtr<RenderNode>& nodeWeak, bool needFlush);
|
||||
|
||||
void SetZIndex(int32_t zIndex)
|
||||
{
|
||||
zIndex_ = zIndex;
|
||||
@@ -964,8 +968,6 @@ public:
|
||||
bool IsPaintOutOfParent();
|
||||
void UpdatePosition();
|
||||
|
||||
virtual void ClipHole(RenderContext& context, const Offset& offset);
|
||||
|
||||
void SetHasSubWindow(bool hasSubWindow)
|
||||
{
|
||||
hasSubWindow_ = hasSubWindow;
|
||||
@@ -1004,6 +1006,16 @@ public:
|
||||
inspector_ = inspectorNode;
|
||||
}
|
||||
|
||||
virtual void SetNeedClip(bool needClip)
|
||||
{
|
||||
needClip_ = needClip;
|
||||
}
|
||||
|
||||
bool GetNeedClip()
|
||||
{
|
||||
return needClip_;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit RenderNode(bool takeBoundary = false);
|
||||
virtual void ClearRenderObject();
|
||||
@@ -1090,6 +1102,7 @@ protected:
|
||||
void MarkNeedSyncGeometryProperties();
|
||||
|
||||
bool hasSubWindow_ = false;
|
||||
bool needClip_ = false;
|
||||
WeakPtr<PipelineContext> context_;
|
||||
Size viewPort_;
|
||||
Point globalPoint_;
|
||||
|
||||
@@ -69,6 +69,14 @@ void RosenRenderContext::PaintChild(const RefPtr<RenderNode>& child, const Offse
|
||||
rsNode_->AddChild(childRSNode, -1);
|
||||
if (child->NeedRender()) {
|
||||
RosenRenderContext context;
|
||||
auto pipelineContext = child->GetContext().Upgrade();
|
||||
LOGI("Hole: child canvas render");
|
||||
auto transparentHole = pipelineContext->GetTransparentHole();
|
||||
if (transparentHole.IsValid() && child->GetNeedClip()) {
|
||||
Offset childOffset = rect.GetOffset();
|
||||
Rect hole = transparentHole - childOffset;
|
||||
context.SetClipHole(hole);
|
||||
}
|
||||
context.Repaint(child);
|
||||
} else {
|
||||
// No need to repaint, notify to update AccessibilityNode info.
|
||||
@@ -84,6 +92,12 @@ void RosenRenderContext::StartRecording()
|
||||
recorder_ = new SkPictureRecorder();
|
||||
recordingCanvas_ = recorder_->beginRecording(
|
||||
SkRect::MakeXYWH(estimatedRect_.Left(), estimatedRect_.Top(), estimatedRect_.Width(), estimatedRect_.Height()));
|
||||
if (clipHole_.IsValid()) {
|
||||
recordingCanvas_->save();
|
||||
needRestoreHole_ = true;
|
||||
recordingCanvas_->clipRect(clipHole_.Left(), clipHole_.Top(),
|
||||
clipHole_.Right(), clipHole_.Bottom(), SkClipOp::kDifference);
|
||||
}
|
||||
}
|
||||
|
||||
void RosenRenderContext::StopRecordingIfNeeded()
|
||||
@@ -92,6 +106,11 @@ void RosenRenderContext::StopRecordingIfNeeded()
|
||||
return;
|
||||
}
|
||||
|
||||
if (needRestoreHole_) {
|
||||
recordingCanvas_->restore();
|
||||
needRestoreHole_ = false;
|
||||
}
|
||||
|
||||
delete recorder_;
|
||||
recorder_ = nullptr;
|
||||
recordingCanvas_ = nullptr;
|
||||
@@ -116,30 +135,6 @@ bool RosenRenderContext::IsIntersectWith(const RefPtr<RenderNode>& child, Offset
|
||||
return true;
|
||||
}
|
||||
|
||||
void RosenRenderContext::ClipHoleBegin(const Rect& holeRect)
|
||||
{
|
||||
auto canvas = GetCanvas();
|
||||
if (!canvas) {
|
||||
return;
|
||||
}
|
||||
LOGI("Hole: PrePaint save clip.");
|
||||
canvas->save();
|
||||
if (holeRect.IsValid()) {
|
||||
canvas->clipRect(
|
||||
{ holeRect.Left(), holeRect.Top(), holeRect.Right(), holeRect.Bottom() }, SkClipOp::kDifference);
|
||||
}
|
||||
}
|
||||
|
||||
void RosenRenderContext::ClipHoleEnd()
|
||||
{
|
||||
LOGI("Hole: PostPaint restore clip");
|
||||
auto canvas = GetCanvas();
|
||||
if (!canvas) {
|
||||
return;
|
||||
}
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
void RosenRenderContext::InitContext(
|
||||
const std::shared_ptr<RSNode>& rsNode, const Rect& rect, const Offset& initialOffset)
|
||||
{
|
||||
@@ -188,4 +183,13 @@ sk_sp<SkImage> RosenRenderContext::FinishRecordingAsImage()
|
||||
nullptr, SkImage::BitDepth::kU8, nullptr);
|
||||
return image;
|
||||
}
|
||||
|
||||
void RosenRenderContext::Restore()
|
||||
{
|
||||
auto canvas = GetCanvas();
|
||||
if (canvas != nullptr) {
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -39,8 +39,7 @@ public:
|
||||
void Repaint(const RefPtr<RenderNode>& node) override;
|
||||
void PaintChild(const RefPtr<RenderNode>& child, const Offset& offset) override;
|
||||
bool IsIntersectWith(const RefPtr<RenderNode>& child, Offset& offset) override;
|
||||
void ClipHoleBegin(const Rect& holeRect) override;
|
||||
void ClipHoleEnd() override;
|
||||
void Restore() override;
|
||||
|
||||
void InitContext(
|
||||
const std::shared_ptr<RSNode>& rsNode, const Rect& rect, const Offset& initialOffset = Offset::Zero());
|
||||
|
||||
@@ -538,6 +538,10 @@ void PipelineContext::FlushRender()
|
||||
UpdateNodesNeedDrawOnPixelMap();
|
||||
|
||||
auto context = RenderContext::Create();
|
||||
if (transparentHole_.IsValid()) {
|
||||
LOGD("Hole: set transparentHole_ in FlushRender");
|
||||
context->SetClipHole(transparentHole_);
|
||||
}
|
||||
if (!dirtyRenderNodes_.empty()) {
|
||||
decltype(dirtyRenderNodes_) dirtyNodes(std::move(dirtyRenderNodes_));
|
||||
for (const auto& dirtyNode : dirtyNodes) {
|
||||
|
||||
Reference in New Issue
Block a user