Each render instruction now has a command buffer.
This enables the backend/gpu to synchronize each command buffer when
rendering to framebuffers.
Because RenderTask API is freeform, the same framebuffer can be written
to more than once in a frame using different actors, so each render pass
needs it's own command buffer.
(May still be potential issue with multiple render tasks against the
scene, e.g. magnifier isn't fixed in Vulkan by this change)
Change-Id: I367f94144ab9670c346b98a8e57ad2b54db96fd5
Signed-off-by: David Steele <david.steele@samsung.com>
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
mCore->SceneCreated();
mCore->Initialize();
+ mCore->ProcessEvents(); // Ensure that scene messages are ready for next update/render.
}
TestApplication::~TestApplication()
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Actor actor = Actor::New();
application.GetScene().Add(actor);
+ application.SendNotification();
+ application.Render(0);
// Build the animation
float durationSeconds(1.0f);
animation.SetLooping(true);
DALI_TEST_CHECK(animation.IsLooping());
+ application.SendNotification();
application.Render(static_cast<unsigned int>(durationSeconds * intervalSeconds * 1000.0f));
application.SendNotification();
finishCheck.CheckSignalNotReceived();
animation.Play();
+ application.SendNotification();
application.Render(0);
application.SendNotification();
const Property::Index index = actor.RegisterProperty("customProperty", startValue);
application.GetScene().Add(actor);
- application.Render();
application.SendNotification();
+ application.Render();
DALI_TEST_EQUALS(actor.GetProperty<int>(index), startValue, TEST_LOCATION);
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
}
-void RenderAlgorithms::ResetCommandBuffer()
-{
- // Reset main command buffer
- if(!mGraphicsCommandBuffer)
- {
- mGraphicsCommandBuffer = mGraphicsController.CreateCommandBuffer(
- Graphics::CommandBufferCreateInfo()
- .SetLevel(Graphics::CommandBufferLevel::PRIMARY),
- nullptr);
- }
- else
- {
- mGraphicsCommandBuffer->Reset();
- }
-
- Graphics::CommandBufferBeginInfo info;
- info.usage = 0 | Graphics::CommandBufferUsageFlagBits::ONE_TIME_SUBMIT;
- mGraphicsCommandBuffer->Begin(info);
-}
-
-void RenderAlgorithms::SubmitCommandBuffer()
-{
- // Submit main command buffer
- mGraphicsCommandBuffer->End();
-
- Graphics::SubmitInfo submitInfo;
- submitInfo.cmdBuffer.push_back(mGraphicsCommandBuffer.get());
- submitInfo.flags = 0 | Graphics::SubmitFlagBits::FLUSH;
- mGraphicsController.SubmitCommandBuffers(submitInfo);
-}
-
-void RenderAlgorithms::DestroyCommandBuffer()
-{
- mGraphicsCommandBuffer.reset();
-}
-
void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& instruction,
BufferIndex bufferIndex,
Integration::DepthBufferAvailable depthBufferAvailable,
int orientation,
const Uint16Pair& sceneSize,
Graphics::RenderPass* renderPass,
- Graphics::RenderTarget* renderTarget)
+ Graphics::RenderTarget* renderTarget,
+ Graphics::CommandBuffer* commandBuffer)
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_INSTRUCTION_PROCESS", [&](std::ostringstream& oss) { oss << "[" << instruction.RenderListCount() << "]"; });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_INSTRUCTION_PROCESS", [&](std::ostringstream& oss)
+ { oss << "[" << instruction.RenderListCount() << "]"; });
DALI_PRINT_RENDER_INSTRUCTION(instruction, bufferIndex);
renderTarget);
// Execute command buffer
- auto* commandBuffer = renderList->GetCommandBuffer();
- if(commandBuffer)
+ auto* secondaryCommandBuffer = renderList->GetCommandBuffer();
+ if(secondaryCommandBuffer)
{
- buffers.push_back(commandBuffer);
+ buffers.push_back(secondaryCommandBuffer);
}
}
}
if(!buffers.empty())
{
- mGraphicsCommandBuffer->ExecuteCommandBuffers(std::move(buffers));
+ commandBuffer->ExecuteCommandBuffers(std::move(buffers));
}
}
DALI_TRACE_END(gTraceFilter, "DALI_RENDER_INSTRUCTION_PROCESS");
#define DALI_INTERNAL_RENDER_ALGORITHMS_H
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* @param[in] rootClippingRect The clipping rectangle
* @param[in] orientation The Scene's surface orientation.
* @param[in] sceneSize The Scene's surface size.
+ * @param[in] renderPass The RenderPass associated with the renderTarget
* @param[in] renderTarget The RenderTarget associated with instruction
+ * @param[in] commandBuffer The CommandBuffer associated with the renderTarget
*/
void ProcessRenderInstruction(const SceneGraph::RenderInstruction& instruction,
BufferIndex bufferIndex,
int orientation,
const Uint16Pair& sceneSize,
Graphics::RenderPass* renderPass,
- Graphics::RenderTarget* renderTarget);
-
- /**
- * Resets main command buffer
- */
- void ResetCommandBuffer();
-
- /**
- * Submits main command buffer
- */
- void SubmitCommandBuffer();
-
- /**
- * @brief Destroy main command buffer (called only one time, at terminate case)
- */
- void DestroyCommandBuffer();
-
- /**
- * Returns main command buffer
- *
- * 'Main' command buffer exists per each scene and it is used
- * to bake all render instructions for the scene.
- *
- * @return main command buffer
- */
- [[nodiscard]] Graphics::CommandBuffer* GetMainCommandBuffer() const
- {
- return mGraphicsCommandBuffer.get();
- }
+ Graphics::RenderTarget* renderTarget,
+ Graphics::CommandBuffer* commandBuffer);
private:
/**
using ScissorStackType = std::vector<Dali::ClippingBox>; ///< The container type used to maintain the applied scissor hierarchy
- Graphics::Controller& mGraphicsController;
- Graphics::UniquePtr<Graphics::CommandBuffer> mGraphicsCommandBuffer{};
+ Graphics::Controller& mGraphicsController;
std::vector<Graphics::CommandBuffer*> mGraphicsRenderItemCommandBuffers{}; ///< Collection of command buffers issuing single draw call
#define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
~RenderInstruction();
+ // Deleted copy constructor
+ RenderInstruction(const RenderInstruction&) = delete;
+
+ // Deleted assignment operator
+ RenderInstruction& operator=(const RenderInstruction& rhs) = delete;
+
/**
* @brief The graphics context is being shutdown. Clean down any outstanding graphics resources.
*/
return mCamera;
}
+ [[nodiscard]] Graphics::CommandBuffer* GetCommandBuffer(Graphics::Controller& graphicsController)
+ {
+ if(!mCommandBuffer)
+ {
+ mCommandBuffer = graphicsController.CreateCommandBuffer(Graphics::CommandBufferCreateInfo().SetLevel(Graphics::CommandBufferLevel::PRIMARY), nullptr);
+ }
+ return mCommandBuffer.get();
+ }
+
/**
* Get the total memory usage of the render instruction
*/
std::size_t GetCapacity();
-private:
- RenderInstruction(const RenderInstruction&) = delete;
- RenderInstruction& operator=(const RenderInstruction& rhs) = delete;
-
-public: // Data
+public:
Render::RenderTracker* mRenderTracker; ///< Pointer to an optional tracker object (not owned)
Viewport mViewport; ///< Optional viewport
Render::FrameBuffer* mFrameBuffer;
uint32_t mRenderPassTag{0u};
-private: // Data
+private:
+ Graphics::UniquePtr<Graphics::CommandBuffer> mCommandBuffer{nullptr}; ///< Output of render lists
+
Camera* mCamera; ///< camera that is used
RenderListContainer mRenderLists; ///< container of all render lists
RenderListContainer::SizeType mNextFreeRenderList; ///< index for the next free render list
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
void ContextDestroyed()
{
sceneContainer.clear();
- renderAlgorithms.DestroyCommandBuffer();
renderedFrameBufferContainer.clear();
samplerContainer.Clear();
uint32_t instructionCount = sceneObject->GetRenderInstructions().Count(mImpl->renderBufferIndex);
- std::vector<Graphics::RenderTarget*> targetsToPresent;
-
Rect<int32_t> surfaceRect = sceneObject->GetSurfaceRect();
if(clippingRect == surfaceRect)
{
}
}
}
+
+ auto sceneRenderTarget = sceneObject->GetSurfaceRenderTarget();
if(!renderToFbo)
{
- mImpl->graphicsController.EnableDepthStencilBuffer(*sceneObject->GetSurfaceRenderTarget(), sceneNeedsDepthBuffer, sceneNeedsStencilBuffer);
+ mImpl->graphicsController.EnableDepthStencilBuffer(*sceneRenderTarget, sceneNeedsDepthBuffer, sceneNeedsStencilBuffer);
}
// Fill resource binding for the scene
std::vector<Graphics::SceneResourceBinding> sceneResourceBindings;
}
mImpl->graphicsController.SetResourceBindingHints(sceneResourceBindings);
- // Reset main algorithms command buffer
- mImpl->renderAlgorithms.ResetCommandBuffer();
-
- auto mainCommandBuffer = mImpl->renderAlgorithms.GetMainCommandBuffer();
-
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Render scene (%s), CPU:%d GPU:%d\n", renderToFbo ? "Offscreen" : "Onscreen", totalSizeCPU, totalSizeGPU);
auto& uboManager = mImpl->uniformBufferManager;
}
#endif
+ if(renderToFbo)
+ {
+ for(uint32_t i = 0; i < instructionCount; ++i)
+ {
+ RenderInstruction& instruction = sceneObject->GetRenderInstructions().At(mImpl->renderBufferIndex, i);
+ if(instruction.mFrameBuffer)
+ {
+ // Ensure graphics framebuffer is created, bind attachments and create render passes/commandbuffers
+ // Only happens once per framebuffer. If the creation fails, e.g. no attachments yet,
+ // then don't render to this framebuffer.
+ if(!instruction.mFrameBuffer->GetGraphicsObject())
+ {
+ const bool created = instruction.mFrameBuffer->CreateGraphicsObjects();
+ if(!created)
+ {
+ continue;
+ }
+ }
+ }
+ }
+ }
+
+ std::vector<Graphics::CommandBuffer*> commandBuffers;
+
for(uint32_t i = 0; i < instructionCount; ++i)
{
RenderInstruction& instruction = sceneObject->GetRenderInstructions().At(mImpl->renderBufferIndex, i);
surfaceOrientation -= 360;
}
- Graphics::RenderTarget* currentRenderTarget = nullptr;
- Graphics::RenderPass* currentRenderPass = nullptr;
+ Graphics::RenderTarget* currentRenderTarget = nullptr;
+ Graphics::RenderPass* currentRenderPass = nullptr;
+ Graphics::CommandBuffer* currentCommandBuffer = nullptr;
std::vector<Graphics::ClearValue> currentClearValues{};
if(instruction.mFrameBuffer)
{
- // Ensure graphics framebuffer is created, bind attachments and create render passes
- // Only happens once per framebuffer. If the create fails, e.g. no attachments yet,
- // then don't render to this framebuffer.
if(!instruction.mFrameBuffer->GetGraphicsObject())
{
- const bool created = instruction.mFrameBuffer->CreateGraphicsObjects();
- if(!created)
- {
- continue;
- }
+ continue;
}
auto& clearValues = instruction.mFrameBuffer->GetGraphicsRenderPassClearValues();
currentRenderPass = sceneObject->GetGraphicsRenderPass(loadOp, Graphics::AttachmentStoreOp::STORE);
}
- targetsToPresent.emplace_back(currentRenderTarget);
+ // Setup command buffer for this instruction.
+ currentCommandBuffer = instruction.GetCommandBuffer(mImpl->graphicsController);
+ commandBuffers.emplace_back(currentCommandBuffer);
+
+ currentCommandBuffer->Reset();
+ Graphics::CommandBufferBeginInfo info;
+ info.usage = 0 | Graphics::CommandBufferUsageFlagBits::ONE_TIME_SUBMIT;
+ info.SetRenderTarget(*currentRenderTarget);
+ currentCommandBuffer->Begin(info);
if(!instruction.mIgnoreRenderToFbo && (instruction.mFrameBuffer != nullptr))
{
// When the surface is rotated, the input values already were set with the rotated angle.
// So, re-calculation is needed.
scissorArea = RecalculateScissorArea(scissorArea, surfaceOrientation, surfaceRect);
-
- // Begin render pass
- mainCommandBuffer->BeginRenderPass(
- currentRenderPass,
- currentRenderTarget,
- scissorArea,
- currentClearValues);
-
- // Note, don't set the viewport/scissor on the primary command buffer.
-
- mImpl->renderAlgorithms.ProcessRenderInstruction(
- instruction,
- mImpl->renderBufferIndex,
- depthBufferAvailable,
- stencilBufferAvailable,
- viewportRect,
- clippingRect,
- surfaceOrientation,
- Uint16Pair(surfaceRect.width, surfaceRect.height),
- currentRenderPass,
- currentRenderTarget);
-
- Graphics::SyncObject* syncObject{nullptr};
- // If the render instruction has an associated render tracker (owned separately)
- // and framebuffer, create a one shot sync object, and use it to determine when
- // the render pass has finished executing on GPU.
- if(instruction.mRenderTracker && instruction.mFrameBuffer)
+ if(scissorArea.width > 0 && scissorArea.height > 0)
{
- syncObject = instruction.mRenderTracker->CreateSyncObject(mImpl->graphicsController);
- instruction.mRenderTracker = nullptr;
- }
- mainCommandBuffer->EndRenderPass(syncObject);
+ // Begin render pass
+ currentCommandBuffer->BeginRenderPass(currentRenderPass,
+ currentRenderTarget,
+ scissorArea,
+ currentClearValues);
+
+ // Note, don't set the viewport/scissor on primary command buffer.
+ mImpl->renderAlgorithms.ProcessRenderInstruction(instruction,
+ mImpl->renderBufferIndex,
+ depthBufferAvailable,
+ stencilBufferAvailable,
+ viewportRect,
+ clippingRect,
+ surfaceOrientation,
+ Uint16Pair(surfaceRect.width, surfaceRect.height),
+ currentRenderPass,
+ currentRenderTarget,
+ currentCommandBuffer);
+
+ Graphics::SyncObject* syncObject{nullptr};
+
+ // If the render instruction has an associated render tracker (owned separately)
+ // and framebuffer, create a one shot sync object, and use it to determine when
+ // the render pass has finished executing on GPU.
+ if(instruction.mRenderTracker && instruction.mFrameBuffer)
+ {
+ syncObject = instruction.mRenderTracker->CreateSyncObject(mImpl->graphicsController);
+ instruction.mRenderTracker = nullptr;
+ }
+ currentCommandBuffer->EndRenderPass(syncObject);
- if(instruction.mFrameBuffer && instruction.mFrameBuffer->IsKeepingRenderResultRequested())
- {
- mainCommandBuffer->ReadPixels(instruction.mFrameBuffer->GetRenderResultBuffer());
- mImpl->renderedFrameBufferContainer.push_back(instruction.mFrameBuffer);
+ if(instruction.mFrameBuffer && instruction.mFrameBuffer->IsKeepingRenderResultRequested())
+ {
+ currentCommandBuffer->ReadPixels(instruction.mFrameBuffer->GetRenderResultBuffer());
+ mImpl->renderedFrameBufferContainer.push_back(instruction.mFrameBuffer);
+ }
}
}
- if(targetsToPresent.size() > 0u)
- {
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss) { oss << "[" << targetsToPresent.size() << "]"; });
- }
-
// Flush UBOs
mImpl->uniformBufferManager->Flush(sceneObject, renderToFbo);
- mImpl->renderAlgorithms.SubmitCommandBuffer();
- mImpl->commandBufferSubmitted = true;
- if(targetsToPresent.size() > 0u)
+ // Submit command buffers
+ Graphics::SubmitInfo submitInfo;
+ submitInfo.flags = 0 | Graphics::SubmitFlagBits::FLUSH;
+
+ for(auto commandBuffer : commandBuffers)
{
- std::sort(targetsToPresent.begin(), targetsToPresent.end());
+ commandBuffer->End();
+ submitInfo.cmdBuffer.push_back(commandBuffer);
+ }
- Graphics::RenderTarget* rt = nullptr;
- for(auto& target : targetsToPresent)
- {
- if(target != rt)
- {
- mImpl->graphicsController.PresentRenderTarget(target);
- rt = target;
- }
- }
+ if(!submitInfo.cmdBuffer.empty())
+ {
+ mImpl->graphicsController.SubmitCommandBuffers(submitInfo);
+ mImpl->commandBufferSubmitted = true;
+ }
+ // present render target (if main scene)
+ if(!renderToFbo)
+ {
+ DALI_TRACE_BEGIN(gTraceFilter, "DALI_RENDER_FINISHED");
+ auto renderTarget = sceneObject->GetSurfaceRenderTarget();
+ mImpl->graphicsController.PresentRenderTarget(renderTarget);
DALI_TRACE_END(gTraceFilter, "DALI_RENDER_FINISHED");
}
}
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
delete[] mRenderResult;
}
mRenderResult = new uint8_t[mWidth * mHeight * Dali::Pixel::GetBytesPerPixel(Pixel::Format::RGBA8888)];
- buffer = mRenderResult;
+ buffer = mRenderResult;
}
return buffer;
}
Dali::PixelData FrameBuffer::GetRenderResult()
{
Dali::Mutex::ScopedLock lock(mPixelDataMutex);
- Dali::PixelData pixelData;
+ Dali::PixelData pixelData;
if(!mIsKeepingRenderResultRequested && mRenderedPixelData)
{
pixelData = mRenderedPixelData;
.SetPreTransform(0 | Graphics::RenderTargetTransformFlagBits::TRANSFORM_IDENTITY_BIT);
mRenderTarget = mGraphicsController->CreateRenderTarget(rtInfo, std::move(mRenderTarget));
- created = true;
+
+ created = true;
}
}
return created;
#define DALI_INTERNAL_RENDER_FRAME_BUFFER_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// INTERNAL INCLUDES
#include <dali/devel-api/rendering/frame-buffer-devel.h>
-#include <dali/internal/render/renderers/render-sampler.h>
-#include <dali/public-api/rendering/frame-buffer.h>
#include <dali/devel-api/threading/mutex.h>
+#include <dali/internal/render/renderers/render-sampler.h>
-#include <dali/integration-api/debug.h>
+#include <unordered_map>
namespace Dali
{
namespace Internal
{
+namespace SceneGraph
+{
+class RenderInstruction;
+}
+
namespace Render
{
class Texture;
/**
* The function returns initialized array of clear values
- * which then can be modified and assed to BeginRenderPass()
+ * which then can be modified and passed to BeginRenderPass()
* command.
*/
[[nodiscard]] auto& GetGraphicsRenderPassClearValues()
return mClearValues;
}
-private:
/**
* @brief Undefined copy constructor. FrameBuffer cannot be copied
*/
Graphics::FramebufferCreateInfo mCreateInfo;
- // Render pass and render target
+ Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr};
/**
* Render passes are created on fly depending on Load and Store operations
* The default render pass (most likely to be used) is the load = CLEAR
- * amd store = STORE for color attachment.
+ * and store = STORE for color attachment.
*/
std::vector<Graphics::UniquePtr<Graphics::RenderPass>> mRenderPass{};
- Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr};
// clear colors
std::vector<Graphics::ClearValue> mClearValues{};
// if it's default, delete the graphics object
// otherwise re-initialize it if dirty
- const Graphics::Sampler* graphicsSampler = samplers ? ((i < (*samplers).Size() && (*samplers)[i]) ? (*samplers)[i]->GetGraphicsObject()
- : nullptr)
- : nullptr;
+ const Graphics::Sampler* graphicsSampler = samplers ? ((i < (*samplers).Size() && (*samplers)[i]) ? (*samplers)[i]->GetGraphicsObject() : nullptr) : nullptr;
const Graphics::TextureBinding textureBinding{graphicsTexture, graphicsSampler, textureUnit};
textureBindings.push_back(textureBinding);
const auto nodeChangeCounter = nodePtr ? uniformMapNode.GetChangeCounter() : 0;
const auto renderItemMapChangeCounter = uniformMap.GetChangeCounter();
- auto iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [nodePtr, programPtr](RenderItemLookup& element) { return (element.node == nodePtr && element.program == programPtr); });
+ auto iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [nodePtr, programPtr](RenderItemLookup& element)
+ { return (element.node == nodePtr && element.program == programPtr); });
std::size_t renderItemMapIndex;
if(iter == mNodeIndexMap.end())
}
// Remove mNodeIndexMap and mUniformIndexMaps.
- auto iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [&node](RenderItemLookup& element) { return element.node == &node; });
+ auto iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [&node](RenderItemLookup& element)
+ { return element.node == &node; });
while(iter != mNodeIndexMap.end())
{
// Swap between end of mUniformIndexMaps and removed.
// Remove uniform index maps.
mUniformIndexMaps.pop_back();
- iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [&node](RenderItemLookup& element) { return element.node == &node; });
+ iter = std::find_if(mNodeIndexMap.begin(), mNodeIndexMap.end(), [&node](RenderItemLookup& element)
+ { return element.node == &node; });
}
}
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define DALI_INTERNAL_SCENE_GRAPH_SCENE_H
/*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
bool mNeedFullUpdate; ///< A flag to update full area
bool mPartialUpdateEnabled; ///< True if the partial update is enabled
- // Render pass and render target
+ // Render target, command buffer and render passes
Graphics::RenderTargetCreateInfo mRenderTargetCreateInfo; // Passed in by message before 2nd stage Initialization happens.
+ Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr}; ///< This is created in Update/Render thread when surface is created/resized/replaced
+
/**
* Render pass is created on fly depending on Load and Store operations
* The default render pass (most likely to be used) is the load = CLEAR
* and store = STORE for color attachment.
*/
- Graphics::UniquePtr<Graphics::RenderPass> mRenderPass{nullptr}; ///< The render pass created to render the surface
- Graphics::UniquePtr<Graphics::RenderPass> mRenderPassNoClear{nullptr}; ///< The render pass created to render the surface without clearing color
- Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr}; ///< This is created in Update/Render thread when surface is created/resized/replaced
+ Graphics::UniquePtr<Graphics::RenderPass> mRenderPass{nullptr}; ///< The render pass created to render the surface
+ Graphics::UniquePtr<Graphics::RenderPass> mRenderPassNoClear{nullptr}; ///< The render pass created to render the surface without clearing color
SceneGraph::Layer* mRoot{nullptr}; ///< Root node