Revert "License conversion from Flora to Apache 2.0"
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / gpu-buffer.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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/gl-resources/gpu-buffer.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/public-api/common/dali-common.h>
22
23 namespace Dali
24 {
25
26 namespace Internal
27 {
28
29 namespace
30 {
31 /**
32  * Helper to get our type enum as GL enum
33  * @param type to convert
34  * @return the corresponding GL enum or -1
35  */
36 inline GLenum TypeAsGlEnum( GpuBuffer::Target type )
37 {
38   GLenum retval( -1 );
39   switch( type )
40   {
41     case GpuBuffer::ARRAY_BUFFER :
42     {
43       retval = GL_ARRAY_BUFFER;
44       break;
45     }
46     case GpuBuffer::ELEMENT_ARRAY_BUFFER :
47     {
48       retval = GL_ELEMENT_ARRAY_BUFFER;
49       break;
50     }
51     case GpuBuffer::TRANSFORM_FEEDBACK_BUFFER :
52     {
53       retval = GL_TRANSFORM_FEEDBACK_BUFFER;
54       break;
55     }
56   }
57   return retval;
58 }
59
60 /**
61  * Helper to get our drawmode enum as GL enum
62  * @param type to convert
63  * @return the corresponding GL enum or -1
64  */
65 inline GLenum ModeAsGlEnum( GpuBuffer::Usage type )
66 {
67   GLenum retval( -1 );
68   switch( type )
69   {
70     case GpuBuffer::STREAM_DRAW :
71     {
72       retval = GL_STREAM_DRAW;
73       break;
74     }
75     case GpuBuffer::STATIC_DRAW :
76     {
77       retval = GL_STATIC_DRAW;
78       break;
79     }
80     case GpuBuffer::DYNAMIC_DRAW :
81     {
82       retval = GL_DYNAMIC_DRAW;
83       break;
84     }
85   }
86   return retval;
87 }
88
89 }
90
91 GpuBuffer::GpuBuffer( Context& context, Target target, Usage usage )
92 : mContext( context ),
93   mCapacity( 0 ),
94   mSize( 0 ),
95   mBufferId( 0 ),
96   mTarget( target ),
97   mUsage( usage ),
98   mBufferCreated( false )
99 {
100 }
101
102 GpuBuffer::~GpuBuffer()
103 {
104   // If we have a buffer then delete it.
105   if (mBufferId)
106   {
107     // If a buffer object that is currently bound is deleted, the binding reverts to 0
108     // (the absence of any buffer object, which reverts to client memory usage)
109     mContext.DeleteBuffers(1,&mBufferId);
110   }
111 }
112
113 /*
114  * Creates or updates the buffer data depending on whether it
115  * already exists or not.
116  */
117 void GpuBuffer::UpdateDataBuffer(GLsizeiptr size,const GLvoid *data)
118 {
119   DALI_ASSERT_DEBUG( size > 0 );
120   mSize = size;
121   // make sure we have a buffer name/id before uploading
122   if (mBufferId == 0)
123   {
124     mContext.GenBuffers(1,&mBufferId);
125     DALI_ASSERT_DEBUG(mBufferId);
126   }
127
128   // make sure the buffer is bound, don't perform any checks because size may be zero
129   BindNoChecks(mBufferId);
130
131   // if the buffer has already been created, just update the data providing it fits
132   if (mBufferCreated )
133   {
134     // if the data will fit in the existing buffer, just update it
135     if (size <= mCapacity )
136     {
137       mContext.BufferSubData( TypeAsGlEnum(mTarget), 0, size, data );
138     }
139     else
140     {
141       // create a new buffer of the larger size,
142       // gl should automatically deallocate the old buffer
143       mContext.BufferData( TypeAsGlEnum(mTarget), size, data, ModeAsGlEnum( mUsage ) );
144       mCapacity = size;
145     }
146   }
147   else
148   {
149     // create the buffer
150     mContext.BufferData( TypeAsGlEnum(mTarget), size, data, ModeAsGlEnum( mUsage ) );
151     mBufferCreated = true;
152     mCapacity = size;
153   }
154
155   switch (mTarget)
156   {
157     case ARRAY_BUFFER:
158     {
159       mContext.BindArrayBuffer(0);
160       break;
161     }
162     case ELEMENT_ARRAY_BUFFER:
163     {
164       mContext.BindElementArrayBuffer(0);
165       break;
166     }
167     case TRANSFORM_FEEDBACK_BUFFER:
168     {
169       mContext.BindTransformFeedbackBuffer(0);
170       break;
171     }
172   }
173 }
174
175 void GpuBuffer::Bind() const
176 {
177   DALI_ASSERT_DEBUG(mCapacity);
178
179   BindNoChecks(mBufferId);
180 }
181
182 bool GpuBuffer::BufferIsValid() const
183 {
184   return mBufferCreated && (0 != mCapacity );
185 }
186
187 void GpuBuffer::GlContextDestroyed()
188 {
189   // If the context is destroyed, GL would have released the buffer.
190   mCapacity = 0;
191   mSize = 0;
192   mBufferId = 0;
193   mBufferCreated = false;
194 }
195
196 void GpuBuffer::BindNoChecks(GLuint bufferId) const
197 {
198   // context currently only supports two targets, element and array
199   // and it caches both of them (as in it won't bind them if the
200   // buffer id is already bound).
201
202   if (mTarget == ARRAY_BUFFER)
203   {
204     mContext.BindArrayBuffer(bufferId);
205   }
206   else
207   {
208     mContext.BindElementArrayBuffer(bufferId);
209   }
210 }
211
212
213 } // namespace Internal
214
215 } //namespace Dali