Merge "CanvasRenderer: Fix changed update when buffer committed" 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     if(gl)
113     {
114       gl->DeleteBuffers(1, &mBufferId);
115     }
116   }
117 }
118
119 void Buffer::DiscardResource()
120 {
121   mController.DiscardResource(this);
122 }
123
124 void Buffer::Bind(Graphics::BufferUsage bindingTarget) const
125 {
126   auto gl = mController.GetGL();
127
128   // CPU allocated buffer may be bound only as Uniform Buffer
129   // on special binding point
130   if(mCpuAllocated && mBufferPtr)
131   {
132     if(bindingTarget == Graphics::BufferUsage::UNIFORM_BUFFER)
133     {
134       // TODO: probably nothing to do, the GLES Context
135       //       we may use CPU backed buffer for future data
136       //       transfers (copy operations)
137     }
138   }
139   else
140   {
141     switch(bindingTarget)
142     {
143       case Graphics::BufferUsage::VERTEX_BUFFER:
144       {
145         gl->BindBuffer(GL_ARRAY_BUFFER, mBufferId);
146         break;
147       }
148       case Graphics::BufferUsage::INDEX_BUFFER:
149       {
150         gl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId);
151         break;
152       }
153       default:
154       {
155         // Nothing to do
156       }
157     }
158   }
159 }
160
161 } // namespace Dali::Graphics::GLES