[dali_2.0.28] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-framebuffer.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 #include "test-graphics-framebuffer.h"
18 #include <dali/integration-api/gl-defines.h>
19 #include "test-graphics-controller.h"
20 #include "test-graphics-texture.h"
21
22 namespace
23 {
24 const GLenum COLOR_ATTACHMENTS[] =
25   {
26     GL_COLOR_ATTACHMENT0,
27     GL_COLOR_ATTACHMENT1,
28     GL_COLOR_ATTACHMENT2,
29     GL_COLOR_ATTACHMENT3,
30     GL_COLOR_ATTACHMENT4,
31     GL_COLOR_ATTACHMENT5,
32     GL_COLOR_ATTACHMENT6,
33     GL_COLOR_ATTACHMENT7,
34 };
35
36 struct DEPTH_STENCIL_ATTACHMENT_TYPE
37 {
38   constexpr explicit DEPTH_STENCIL_ATTACHMENT_TYPE(Graphics::Format textureFormat)
39   {
40     switch(textureFormat)
41     {
42       case Graphics::Format::D16_UNORM:
43       case Graphics::Format::D32_SFLOAT:
44       case Graphics::Format::X8_D24_UNORM_PACK32:
45       {
46         attachment = GL_DEPTH_ATTACHMENT;
47         break;
48       }
49
50       case Graphics::Format::S8_UINT:
51       {
52         attachment = GL_STENCIL_ATTACHMENT;
53         break;
54       }
55
56       case Graphics::Format::D16_UNORM_S8_UINT:
57       case Graphics::Format::D24_UNORM_S8_UINT:
58       case Graphics::Format::D32_SFLOAT_S8_UINT:
59       {
60         attachment = GL_DEPTH_STENCIL_ATTACHMENT;
61         break;
62       }
63       default:
64       {
65         attachment = GL_NONE;
66         break;
67       }
68     }
69   }
70   GLenum attachment{GL_NONE};
71 };
72
73 } // namespace
74 //namespace
75
76 namespace Dali
77 {
78 TestGraphicsFramebuffer::TestGraphicsFramebuffer(
79   TraceCallStack&                        callStack,
80   TestGlAbstraction&                     glAbstraction,
81   const Graphics::FramebufferCreateInfo& createInfo)
82 : mGl(glAbstraction),
83   mCallStack(callStack)
84 {
85   mCreateInfo.colorAttachments       = std::move(createInfo.colorAttachments);
86   mCreateInfo.depthStencilAttachment = createInfo.depthStencilAttachment;
87   mCreateInfo.size                   = createInfo.size;
88 }
89
90 TestGraphicsFramebuffer::~TestGraphicsFramebuffer()
91 {
92   if(mId)
93   {
94     mGl.DeleteFramebuffers(1, &mId);
95   }
96 }
97
98 void TestGraphicsFramebuffer::Initialize()
99 {
100   mCallStack.PushCall("Initialize", "");
101
102   mGl.GenFramebuffers(1, &mId);
103   mGl.BindFramebuffer(GL_FRAMEBUFFER, mId);
104
105   for(Graphics::ColorAttachment& attachment : mCreateInfo.colorAttachments)
106   {
107     AttachTexture(attachment.texture, COLOR_ATTACHMENTS[attachment.attachmentId], attachment.layerId, attachment.levelId);
108   }
109   mGl.DrawBuffers(mCreateInfo.colorAttachments.size(), COLOR_ATTACHMENTS);
110
111   if(mCreateInfo.depthStencilAttachment.depthTexture)
112   {
113     // Create a depth or depth/stencil render target.
114     auto depthTexture = Uncast<TestGraphicsTexture>(mCreateInfo.depthStencilAttachment.depthTexture);
115     auto attachmentId = DEPTH_STENCIL_ATTACHMENT_TYPE(depthTexture->GetFormat()).attachment;
116
117     mGl.GenRenderbuffers(1, &mDepthBuffer);
118     mGl.BindRenderbuffer(GL_RENDERBUFFER, mDepthBuffer);
119     mGl.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mCreateInfo.size.width, mCreateInfo.size.height);
120     mGl.FramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentId, GL_RENDERBUFFER, mDepthBuffer);
121
122     AttachTexture(depthTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.depthLevel);
123   }
124
125   if(mCreateInfo.depthStencilAttachment.stencilTexture)
126   {
127     auto stencilTexture = Uncast<TestGraphicsTexture>(mCreateInfo.depthStencilAttachment.stencilTexture);
128     auto attachmentId   = DEPTH_STENCIL_ATTACHMENT_TYPE(stencilTexture->GetFormat()).attachment;
129
130     // Create a stencil render target.
131     mGl.GenRenderbuffers(1, &mStencilBuffer);
132     mGl.BindRenderbuffer(GL_RENDERBUFFER, mStencilBuffer);
133     mGl.RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mCreateInfo.size.width, mCreateInfo.size.height);
134     mGl.FramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentId, GL_RENDERBUFFER, mStencilBuffer);
135
136     AttachTexture(stencilTexture, attachmentId, 0, mCreateInfo.depthStencilAttachment.stencilLevel);
137   }
138   mGl.BindFramebuffer(GL_FRAMEBUFFER, 0);
139 }
140
141 void TestGraphicsFramebuffer::AttachTexture(Graphics::Texture* texture, uint32_t attachmentId, uint32_t layerId, uint32_t levelId)
142 {
143   auto graphicsTexture = Uncast<TestGraphicsTexture>(texture);
144   if(graphicsTexture->GetType() == Graphics::TextureType::TEXTURE_2D)
145   {
146     mGl.FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, graphicsTexture->GetTarget(), graphicsTexture->mId, levelId);
147   }
148   else
149   {
150     mGl.FramebufferTexture2D(GL_FRAMEBUFFER, attachmentId, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layerId, graphicsTexture->mId, levelId);
151   }
152 }
153
154 void TestGraphicsFramebuffer::Bind()
155 {
156   mCallStack.PushCall("Bind", "");
157
158   if(!mId)
159   {
160     Initialize();
161   }
162   mGl.BindFramebuffer(GL_FRAMEBUFFER, mId);
163 }
164
165 } // namespace Dali