Merge "Remove the replacing surface code" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-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
18 // CLASS HEADER
19 #include "gles-graphics-buffer.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/gl-abstraction.h>
23 #include <dali/integration-api/gl-defines.h>
24
25 // INTERNAL INCLUDES
26 #include "egl-graphics-controller.h"
27
28 namespace Dali::Graphics::GLES
29 {
30 Buffer::Buffer(const Graphics::BufferCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
31 : BufferResource(createInfo, controller)
32 {
33   // Check if buffer is CPU allocated
34   if(((0 | BufferUsage::UNIFORM_BUFFER) & mCreateInfo.usage) &&
35      (0 | BufferPropertiesFlagBit::CPU_ALLOCATED) & mCreateInfo.propertiesFlags)
36   {
37     // cpu allocated buffer
38     mCpuAllocated = true;
39   }
40
41   // Check if buffer is transient
42   if((0 | BufferPropertiesFlagBit::TRANSIENT_MEMORY) & mCreateInfo.propertiesFlags)
43   {
44     // memory is transient, may be lazily allocated when
45     // mapped, together with cpu allocated it may create emulated uniform
46     // buffer in this implementation
47     mTransient = true;
48   }
49
50   controller.AddBuffer(*this);
51 }
52
53 bool Buffer::InitializeResource()
54 {
55   // CPU allocated uniform buffer is a special "compatibility" mode
56   // for older GLES
57   if(mCpuAllocated && !mTransient)
58   {
59     InitializeCPUBuffer();
60   }
61   else if(!mCpuAllocated)
62   {
63     InitializeGPUBuffer();
64   }
65
66   return true;
67 }
68
69 void Buffer::InitializeCPUBuffer()
70 {
71   // Just allocate memory
72   // @TODO put better CPU memory management in place
73   const auto allocators = GetCreateInfo().allocationCallbacks;
74   if(allocators)
75   {
76     mBufferPtr = allocators->allocCallback(mCreateInfo.size, 0, allocators->userData);
77   }
78   else
79   {
80     mBufferPtr = malloc(mCreateInfo.size);
81   }
82 }
83
84 void Buffer::InitializeGPUBuffer()
85 {
86   auto gl = mController.GetGL();
87   gl->GenBuffers(1, &mBufferId);
88   gl->BindBuffer(GL_ARRAY_BUFFER, mBufferId);
89   gl->BufferData(GL_ARRAY_BUFFER, mCreateInfo.size, nullptr, GL_STATIC_DRAW);
90 }
91
92 void Buffer::DestroyResource()
93 {
94   // Destroy CPU allocated buffer
95   if(mCpuAllocated && mBufferPtr)
96   {
97     const auto allocators = GetCreateInfo().allocationCallbacks;
98     if(allocators)
99     {
100       allocators->freeCallback(mBufferPtr, allocators->userData);
101     }
102     else
103     {
104       free(mBufferPtr);
105     }
106     mBufferPtr = nullptr;
107   }
108   // Deestroy GPU allocation
109   else
110   {
111     auto gl = mController.GetGL();
112     gl->DeleteBuffers(1, &mBufferId);
113   }
114 }
115
116 void Buffer::DiscardResource()
117 {
118   mController.DiscardResource(this);
119 }
120
121 void Buffer::Bind(Graphics::BufferUsage bindingTarget) const
122 {
123   auto gl = mController.GetGL();
124
125   // CPU allocated buffer may be bound only as Uniform Buffer
126   // on special binding point
127   if(mCpuAllocated && mBufferPtr)
128   {
129     if(bindingTarget == Graphics::BufferUsage::UNIFORM_BUFFER)
130     {
131       // TODO: probably nothing to do, the GLES Context
132       //       we may use CPU backed buffer for future data
133       //       transfers (copy operations)
134     }
135   }
136   else
137   {
138     switch(bindingTarget)
139     {
140       case Graphics::BufferUsage::VERTEX_BUFFER:
141       {
142         gl->BindBuffer(GL_ARRAY_BUFFER, mBufferId);
143         break;
144       }
145       case Graphics::BufferUsage::INDEX_BUFFER:
146       {
147         gl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId);
148         break;
149       }
150       default:
151       {
152         // Nothing to do
153       }
154     }
155   }
156 }
157
158 } // namespace Dali::Graphics::GLES