Merge "Add TOUCH_FOCUSABLE property" into devel/master
[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   mCreateInfo.size.width  = width;
37   mCreateInfo.size.height = height;
38   if(mDepthBuffer)
39   {
40     mCreateInfo.depthStencilAttachment.depthUsage = Graphics::DepthStencilAttachment::Usage::WRITE;
41   }
42   if(mStencilBuffer)
43   {
44     mCreateInfo.depthStencilAttachment.stencilUsage = Graphics::DepthStencilAttachment::Usage::WRITE;
45   }
46 }
47
48 FrameBuffer::~FrameBuffer() = default;
49
50 void FrameBuffer::Destroy()
51 {
52   mGraphicsObject.reset();
53 }
54
55 void FrameBuffer::Initialize(Graphics::Controller& graphicsController)
56 {
57   mGraphicsController = &graphicsController;
58 }
59
60 void FrameBuffer::AttachColorTexture(Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer)
61 {
62   if(texture)
63   {
64     if(!texture->GetGraphicsObject())
65     {
66       texture->Create(0 | Graphics::TextureUsageFlagBits::COLOR_ATTACHMENT | Graphics::TextureUsageFlagBits::SAMPLE);
67     }
68
69     uint32_t                  attachmentId = mCreateInfo.colorAttachments.size();
70     Graphics::ColorAttachment colorAttachment{attachmentId, texture->GetGraphicsObject(), layer, mipmapLevel};
71     mCreateInfo.colorAttachments.push_back(colorAttachment);
72   }
73 }
74
75 void FrameBuffer::AttachDepthTexture(Render::Texture* texture, uint32_t mipmapLevel)
76 {
77   if(texture)
78   {
79     if(!texture->GetGraphicsObject())
80     {
81       texture->Create(0 | Graphics::TextureUsageFlagBits::DEPTH_STENCIL_ATTACHMENT | Graphics::TextureUsageFlagBits::SAMPLE);
82     }
83
84     mCreateInfo.depthStencilAttachment.depthTexture = texture->GetGraphicsObject();
85     mCreateInfo.depthStencilAttachment.depthUsage   = Graphics::DepthStencilAttachment::Usage::WRITE;
86     mCreateInfo.depthStencilAttachment.depthLevel   = mipmapLevel;
87   }
88 }
89
90 void FrameBuffer::AttachDepthStencilTexture(Render::Texture* texture, uint32_t mipmapLevel)
91 {
92   if(texture)
93   {
94     if(!texture->GetGraphicsObject())
95     {
96       texture->Create(0 | Graphics::TextureUsageFlagBits::DEPTH_STENCIL_ATTACHMENT | Graphics::TextureUsageFlagBits::SAMPLE);
97     }
98     mCreateInfo.depthStencilAttachment.stencilTexture = texture->GetGraphicsObject();
99     mCreateInfo.depthStencilAttachment.stencilUsage   = Graphics::DepthStencilAttachment::Usage::WRITE;
100     mCreateInfo.depthStencilAttachment.stencilLevel   = mipmapLevel;
101   }
102 }
103
104 bool FrameBuffer::CreateGraphicsObjects()
105 {
106   bool created = false;
107
108   if(!mGraphicsObject)
109   {
110     // Only create a graphics object if there are attachments for it to render into
111     if(mCreateInfo.colorAttachments.empty() &&
112        mCreateInfo.depthStencilAttachment.depthTexture == nullptr &&
113        mCreateInfo.depthStencilAttachment.stencilTexture == nullptr &&
114        !mDepthBuffer && !mStencilBuffer)
115     {
116       DALI_LOG_ERROR("Attempting to bind a framebuffer with no attachments\n");
117     }
118     else
119     {
120       mGraphicsObject = mGraphicsController->CreateFramebuffer(mCreateInfo, std::move(mGraphicsObject));
121
122       // Create render target
123       Graphics::RenderTargetCreateInfo rtInfo{};
124       rtInfo
125         .SetFramebuffer(mGraphicsObject.get())
126         .SetExtent({mWidth, mHeight})
127         .SetPreTransform(0 | Graphics::RenderTargetTransformFlagBits::TRANSFORM_IDENTITY_BIT);
128       mRenderTarget = mGraphicsController->CreateRenderTarget(rtInfo, std::move(mRenderTarget));
129
130       std::vector<Graphics::AttachmentDescription> attachmentDescriptions;
131
132       // Default behaviour for color attachments is to CLEAR and STORE
133       mClearValues.clear();
134       for(auto& attachments : mCreateInfo.colorAttachments)
135       {
136         if(attachments.texture)
137         {
138           Graphics::AttachmentDescription desc{};
139           desc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR);
140           desc.SetStoreOp(Graphics::AttachmentStoreOp::STORE);
141           attachmentDescriptions.push_back(desc);
142           mClearValues.emplace_back();
143         }
144       }
145
146       if(mCreateInfo.depthStencilAttachment.depthTexture || mCreateInfo.depthStencilAttachment.stencilTexture ||
147          mDepthBuffer || mStencilBuffer)
148       {
149         Graphics::AttachmentDescription depthStencilDesc{};
150         depthStencilDesc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR)
151           .SetStoreOp(Graphics::AttachmentStoreOp::DONT_CARE);
152
153         if(mCreateInfo.depthStencilAttachment.stencilTexture || mStencilBuffer)
154         {
155           depthStencilDesc.SetStencilLoadOp(Graphics::AttachmentLoadOp::CLEAR)
156             .SetStencilStoreOp(Graphics::AttachmentStoreOp::DONT_CARE);
157         }
158         mClearValues.emplace_back();
159         attachmentDescriptions.push_back(depthStencilDesc);
160       }
161
162       Graphics::RenderPassCreateInfo rpInfo{};
163       rpInfo.SetAttachments(attachmentDescriptions);
164
165       // Add default render pass (loadOp = clear)
166       mRenderPass.emplace_back(mGraphicsController->CreateRenderPass(rpInfo, nullptr));
167
168       // Add default render pass (loadOp = dontcare)
169       attachmentDescriptions[0].SetLoadOp(Graphics::AttachmentLoadOp::DONT_CARE);
170       mRenderPass.emplace_back(mGraphicsController->CreateRenderPass(rpInfo, nullptr));
171
172       created = true;
173     }
174   }
175   return created;
176 }
177
178 uint32_t FrameBuffer::GetWidth() const
179 {
180   return mWidth;
181 }
182
183 uint32_t FrameBuffer::GetHeight() const
184 {
185   return mHeight;
186 }
187
188 [[nodiscard]] Graphics::RenderPass* FrameBuffer::GetGraphicsRenderPass(Graphics::AttachmentLoadOp  colorLoadOp,
189                                                                        Graphics::AttachmentStoreOp colorStoreOp) const
190 {
191   // clear only when requested
192   if(colorLoadOp == Graphics::AttachmentLoadOp::CLEAR)
193   {
194     return mRenderPass[0].get();
195   }
196   else
197   {
198     return mRenderPass[1].get();
199   }
200 }
201
202 } // namespace Render
203
204 } // namespace Internal
205
206 } // namespace Dali