/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
#include <dali/internal/render/common/render-list.h>
#include <dali/internal/render/renderers/render-renderer.h>
#include <dali/internal/update/nodes/scene-graph-layer.h>
+#include <dali/public-api/math/uint-16-pair.h>
using Dali::Internal::SceneGraph::RenderInstruction;
using Dali::Internal::SceneGraph::RenderItem;
Graphics::StencilOp op{Graphics::StencilOp::KEEP};
};
-inline Graphics::Viewport ViewportFromClippingBox(ClippingBox clippingBox, int orientation)
+inline Graphics::Viewport ViewportFromClippingBox(const Uint16Pair& sceneSize, ClippingBox clippingBox, int orientation)
{
Graphics::Viewport viewport{static_cast<float>(clippingBox.x), static_cast<float>(clippingBox.y), static_cast<float>(clippingBox.width), static_cast<float>(clippingBox.height), 0.0f, 0.0f};
if(orientation == 90 || orientation == 270)
{
+ if(orientation == 90)
+ {
+ viewport.x = sceneSize.GetY() - (clippingBox.y + clippingBox.height);
+ viewport.y = clippingBox.x;
+ }
+ else // orientation == 270
+ {
+ viewport.x = clippingBox.y;
+ viewport.y = sceneSize.GetX() - (clippingBox.x + clippingBox.width);
+ }
viewport.width = static_cast<float>(clippingBox.height);
viewport.height = static_cast<float>(clippingBox.width);
}
+ else if(orientation == 180)
+ {
+ viewport.x = sceneSize.GetX() - (clippingBox.x + clippingBox.width);
+ viewport.y = sceneSize.GetY() - (clippingBox.y + clippingBox.height);
+ }
return viewport;
}
* @param[in] item The current RenderItem about to be rendered
* @param[in,out] commandBuffer The command buffer to write into
* @param[in] instruction The render-instruction to process.
+ * @param[in] orientation The Scene's surface orientation.
*/
inline void RenderAlgorithms::SetupScissorClipping(
const RenderItem& item,
Graphics::CommandBuffer& commandBuffer,
- const RenderInstruction& instruction)
+ const RenderInstruction& instruction,
+ int orientation)
{
// Get the number of child scissors in the stack (do not include layer or root box).
size_t childStackDepth = mScissorStack.size() - 1u;
// This is a clipping node. We generate the AABB for this node and intersect it with the previous intersection further up the tree.
// Get the AABB bounding box for the current render item.
- const ClippingBox scissorBox(item.CalculateViewportSpaceAABB(item.mSize, mViewportRectangle.width, mViewportRectangle.height));
+ const ClippingBox scissorBox(RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3::ZERO, item.mSize, mViewportRectangle.width, mViewportRectangle.height));
// Get the AABB for the parent item that we must intersect with.
const ClippingBox& parentBox(mScissorStack.back());
{
useScissorBox.y = (instruction.mFrameBuffer->GetHeight() - useScissorBox.height) - useScissorBox.y;
}
- Graphics::Rect2D scissorBox = {useScissorBox.x, useScissorBox.y, uint32_t(useScissorBox.width), uint32_t(useScissorBox.height)};
- commandBuffer.SetScissor(scissorBox);
+
+ Graphics::Viewport graphicsViewport = ViewportFromClippingBox(Uint16Pair{0, 0}, mViewportRectangle, 0);
+ commandBuffer.SetScissor(Rect2DFromClippingBox(useScissorBox, orientation, graphicsViewport));
+ }
+ }
+ else
+ {
+ // If there is render callback on the Renderer we need to calculate the scissor box and provide it to the
+ // callback so it may be clipped
+ if(item.mRenderer->GetRenderCallback())
+ {
+ // store clipping box inside the render callback input structure
+ auto& input = item.mRenderer->GetRenderCallbackInput();
+ input.clippingBox = ClippingBox(RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3::ZERO, item.mSize, mViewportRectangle.width, mViewportRectangle.height));
}
}
}
uint32_t& lastClippingDepth,
uint32_t& lastClippingId,
Integration::StencilBufferAvailable stencilBufferAvailable,
- const RenderInstruction& instruction)
+ const RenderInstruction& instruction,
+ int orientation)
{
RenderMode::Type renderMode = RenderMode::AUTO;
- const Renderer* renderer = item.mRenderer;
+ RendererKey renderer = item.mRenderer;
if(renderer)
{
renderMode = renderer->GetRenderMode();
// As both scissor and stencil clips can be nested, we may be simultaneously traversing up the scissor tree, requiring a scissor to be un-done. Whilst simultaneously adding a new stencil clip.
// We process both based on our current and old clipping depths for each mode.
// Both methods with return rapidly if there is nothing to be done for that type of clipping.
- SetupScissorClipping(item, commandBuffer, instruction);
+ SetupScissorClipping(item, commandBuffer, instruction, orientation);
if(stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE)
{
const RenderInstruction& instruction,
const Rect<int32_t>& viewport,
const Rect<int>& rootClippingRect,
- int orientation)
+ int orientation,
+ const Uint16Pair& sceneSize)
{
DALI_PRINT_RENDER_LIST(renderList);
auto* mutableRenderList = const_cast<RenderList*>(&renderList);
auto& secondaryCommandBuffer = mutableRenderList->GetCommandBuffer(mGraphicsController);
secondaryCommandBuffer.Reset();
-
- secondaryCommandBuffer.SetViewport(ViewportFromClippingBox(mViewportRectangle, orientation));
+ secondaryCommandBuffer.SetViewport(ViewportFromClippingBox(sceneSize, mViewportRectangle, orientation));
mHasLayerScissor = false;
// Setup Scissor testing (for both viewport and per-node scissor)
// on the bottom of the stack
if(!rootClippingRect.IsEmpty())
{
- Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+ Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0);
secondaryCommandBuffer.SetScissorTestEnable(true);
secondaryCommandBuffer.SetScissor(Rect2DFromRect(rootClippingRect, orientation, graphicsViewport));
mScissorStack.push_back(rootClippingRect);
if(renderList.IsClipping())
{
- Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+ Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0);
secondaryCommandBuffer.SetScissorTestEnable(true);
const ClippingBox& layerScissorBox = renderList.GetClippingBox();
secondaryCommandBuffer.SetScissor(Rect2DFromClippingBox(layerScissorBox, orientation, graphicsViewport));
mHasLayerScissor = true;
}
+ // Prepare Render::Renderer Render for this secondary command buffer.
+ Renderer::PrepareCommandBuffer();
+
// Loop through all RenderItems in the RenderList, set up any prerequisites to render them, then perform the render.
for(uint32_t index = 0u; index < count; ++index)
{
bool skip = true;
if(!rootClippingRect.IsEmpty())
{
- auto rect = item.CalculateViewportSpaceAABB(item.mUpdateSize, mViewportRectangle.width, mViewportRectangle.height);
+ Vector4 updateArea = item.mRenderer ? item.mRenderer->GetVisualTransformedUpdateArea(bufferIndex, item.mUpdateArea) : item.mUpdateArea;
+ auto rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(updateArea.x, updateArea.y, 0.0f), Vector3(updateArea.z, updateArea.w, 0.0f), mViewportRectangle.width, mViewportRectangle.height);
if(rect.Intersect(rootClippingRect))
{
// Set up clipping based on both the Renderer and Actor APIs.
// The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used.
- SetupClipping(item, secondaryCommandBuffer, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction);
+ SetupClipping(item, secondaryCommandBuffer, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction, orientation);
if(DALI_LIKELY(item.mRenderer))
{
Vector<Graphics::Texture*>& boundTextures,
const Rect<int32_t>& viewport,
const Rect<int>& rootClippingRect,
- int orientation)
+ int orientation,
+ const Uint16Pair& sceneSize)
{
DALI_PRINT_RENDER_INSTRUCTION(instruction, bufferIndex);
instruction, //added for reflection effect
viewport,
rootClippingRect,
- orientation);
+ orientation,
+ sceneSize);
// Execute command buffer
auto* commandBuffer = renderList->GetCommandBuffer();