Merge branch 'devel/master' into devel/graphics
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-frame-buffer.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // CLASS HEADER
18 #include <dali/internal/render/renderers/render-frame-buffer.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/integration-api/debug.h>
22 #include <dali/internal/render/renderers/render-texture.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace Render
29 {
30 FrameBuffer::FrameBuffer(uint32_t width, uint32_t height, Mask attachments)
31 : mWidth(width),
32   mHeight(height),
33   mDepthBuffer(attachments & Dali::FrameBuffer::Attachment::DEPTH),
34   mStencilBuffer(attachments & Dali::FrameBuffer::Attachment::STENCIL)
35 {
36 }
37
38 FrameBuffer::~FrameBuffer() = default;
39
40 void FrameBuffer::Destroy()
41 {
42   mGraphicsObject.reset();
43 }
44
45 void FrameBuffer::Initialize(Graphics::Controller& graphicsController)
46 {
47   mGraphicsController = &graphicsController;
48 }
49
50 void FrameBuffer::AttachColorTexture(Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer)
51 {
52   if(texture)
53   {
54     if(!texture->GetGraphicsObject())
55     {
56       texture->Create(0 | Graphics::TextureUsageFlagBits::COLOR_ATTACHMENT | Graphics::TextureUsageFlagBits::SAMPLE);
57     }
58
59     uint32_t                  attachmentId = mCreateInfo.colorAttachments.size();
60     Graphics::ColorAttachment colorAttachment{attachmentId, texture->GetGraphicsObject(), layer, mipmapLevel};
61     mCreateInfo.colorAttachments.push_back(colorAttachment);
62   }
63 }
64
65 void FrameBuffer::AttachDepthTexture(Render::Texture* texture, uint32_t mipmapLevel)
66 {
67   if(texture && mDepthBuffer)
68   {
69     if(!texture->GetGraphicsObject())
70     {
71       texture->Create(0 | Graphics::TextureUsageFlagBits::DEPTH_STENCIL_ATTACHMENT | Graphics::TextureUsageFlagBits::SAMPLE);
72     }
73
74     mCreateInfo.depthStencilAttachment.depthTexture = texture->GetGraphicsObject();
75     mCreateInfo.depthStencilAttachment.depthLevel   = mipmapLevel;
76   }
77 }
78
79 void FrameBuffer::AttachDepthStencilTexture(Render::Texture* texture, uint32_t mipmapLevel)
80 {
81   if(texture && mStencilBuffer)
82   {
83     if(!texture->GetGraphicsObject())
84     {
85       texture->Create(0 | Graphics::TextureUsageFlagBits::DEPTH_STENCIL_ATTACHMENT | Graphics::TextureUsageFlagBits::SAMPLE);
86     }
87     mCreateInfo.depthStencilAttachment.stencilTexture = texture->GetGraphicsObject();
88     mCreateInfo.depthStencilAttachment.stencilLevel   = mipmapLevel;
89   }
90 }
91
92 bool FrameBuffer::CreateGraphicsObjects()
93 {
94   bool created = false;
95
96   if(!mGraphicsObject)
97   {
98     // Only create a graphics object if there are attachments for it to render into
99     if(mCreateInfo.colorAttachments.empty() &&
100        mCreateInfo.depthStencilAttachment.depthTexture == nullptr &&
101        mCreateInfo.depthStencilAttachment.stencilTexture == nullptr)
102     {
103       DALI_LOG_ERROR("Attempting to bind a framebuffer with no attachments\n");
104     }
105     else
106     {
107       mGraphicsObject = mGraphicsController->CreateFramebuffer(mCreateInfo, std::move(mGraphicsObject));
108
109       // Create render target
110       Graphics::RenderTargetCreateInfo rtInfo{};
111       rtInfo
112         .SetFramebuffer(mGraphicsObject.get())
113         .SetExtent({mWidth, mHeight})
114         .SetPreTransform(0 | Graphics::RenderTargetTransformFlagBits::TRANSFORM_IDENTITY_BIT);
115       mRenderTarget = mGraphicsController->CreateRenderTarget(rtInfo, std::move(mRenderTarget));
116
117       std::vector<Graphics::AttachmentDescription> attachmentDescriptions;
118
119       // Default behaviour for color attachments is to CLEAR and STORE
120       mClearValues.clear();
121       for(auto& attachments : mCreateInfo.colorAttachments)
122       {
123         if(attachments.texture)
124         {
125           Graphics::AttachmentDescription desc{};
126           desc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR);
127           desc.SetStoreOp(Graphics::AttachmentStoreOp::STORE);
128           attachmentDescriptions.push_back(desc);
129           mClearValues.emplace_back();
130         }
131       }
132
133       if(mCreateInfo.depthStencilAttachment.depthTexture || mCreateInfo.depthStencilAttachment.stencilTexture)
134       {
135         Graphics::AttachmentDescription depthStencilDesc{};
136         depthStencilDesc.SetStencilLoadOp(Graphics::AttachmentLoadOp::CLEAR)
137           .SetStoreOp(Graphics::AttachmentStoreOp::DONT_CARE);
138
139         if(mCreateInfo.depthStencilAttachment.stencilTexture)
140         {
141           depthStencilDesc.SetStencilLoadOp(Graphics::AttachmentLoadOp::CLEAR)
142             .SetStoreOp(Graphics::AttachmentStoreOp::DONT_CARE);
143         }
144         mClearValues.emplace_back();
145         attachmentDescriptions.push_back(depthStencilDesc);
146       }
147
148       Graphics::RenderPassCreateInfo rpInfo{};
149       rpInfo.SetAttachments(attachmentDescriptions);
150
151       // Add default render pass (loadOp = clear)
152       mRenderPass.emplace_back(mGraphicsController->CreateRenderPass(rpInfo, nullptr));
153
154       // Add default render pass (loadOp = dontcare)
155       attachmentDescriptions[0].SetLoadOp(Graphics::AttachmentLoadOp::DONT_CARE);
156       mRenderPass.emplace_back(mGraphicsController->CreateRenderPass(rpInfo, nullptr));
157
158       created = true;
159     }
160   }
161   return created;
162 }
163
164 uint32_t FrameBuffer::GetWidth() const
165 {
166   return mWidth;
167 }
168
169 uint32_t FrameBuffer::GetHeight() const
170 {
171   return mHeight;
172 }
173
174 [[nodiscard]] Graphics::RenderPass* FrameBuffer::GetGraphicsRenderPass(Graphics::AttachmentLoadOp  colorLoadOp,
175                                                                        Graphics::AttachmentStoreOp colorStoreOp) const
176 {
177   // clear only when requested
178   if(colorLoadOp == Graphics::AttachmentLoadOp::CLEAR)
179   {
180     return mRenderPass[0].get();
181   }
182   else
183   {
184     return mRenderPass[1].get();
185   }
186 }
187
188 } // namespace Render
189
190 } // namespace Internal
191
192 } // namespace Dali