Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-property-buffer.cpp
1
2 #include <dali/internal/render/renderers/render-property-buffer.h>
3 #include <dali/internal/event/common/property-buffer-impl.h>  // Dali::Internal::PropertyBuffer
4
5 namespace
6 {
7
8 using namespace Dali;
9 using Dali::Property;
10 using Dali::Internal::PropertyImplementationType;
11
12 Dali::GLenum GetPropertyImplementationGlType( Property::Type propertyType )
13 {
14   Dali::GLenum type = GL_BYTE;
15
16   switch( propertyType )
17   {
18     case Property::NONE:
19     case Property::STRING:
20     case Property::ARRAY:
21     case Property::MAP:
22     case Property::RECTANGLE:
23     case Property::ROTATION:
24     {
25       // types not supported by gl
26       break;
27     }
28     case Property::BOOLEAN:
29     {
30       type = GL_BYTE;
31       break;
32     }
33     case Property::INTEGER:
34     {
35       type = GL_SHORT;
36       break;
37     }
38     case Property::FLOAT:
39     case Property::VECTOR2:
40     case Property::VECTOR3:
41     case Property::VECTOR4:
42     case Property::MATRIX3:
43     case Property::MATRIX:
44     {
45       type = GL_FLOAT;
46       break;
47     }
48   }
49
50   return type;
51 }
52
53 size_t GetPropertyImplementationGlSize( Property::Type propertyType )
54 {
55   size_t size = 1u;
56
57   switch( propertyType )
58   {
59     case Property::NONE:
60     case Property::STRING:
61     case Property::ARRAY:
62     case Property::MAP:
63     case Property::RECTANGLE:
64     case Property::ROTATION:
65     {
66       // types not supported by gl
67       break;
68     }
69     case Property::BOOLEAN:
70     {
71       size = 1u;
72       break;
73     }
74     case Property::INTEGER:
75     {
76       size = 2u;
77       break;
78     }
79     case Property::FLOAT:
80     case Property::VECTOR2:
81     case Property::VECTOR3:
82     case Property::VECTOR4:
83     case Property::MATRIX3:
84     case Property::MATRIX:
85     {
86       size = 4u;
87       break;
88     }
89   }
90
91   return size;
92 }
93 } //Unnamed namespace
94
95 namespace Dali
96 {
97 namespace Internal
98 {
99 namespace Render
100 {
101
102 PropertyBuffer::PropertyBuffer()
103 :mFormat(NULL),
104  mData(NULL),
105  mGpuBuffer(NULL),
106  mSize(0),
107  mDataChanged(true)
108 {
109 }
110
111 PropertyBuffer::~PropertyBuffer()
112 {
113 }
114
115 void PropertyBuffer::SetFormat( PropertyBuffer::Format* format )
116 {
117   mFormat = format;
118   mDataChanged = true;
119 }
120
121 void PropertyBuffer::SetData( Dali::Vector<char>* data, size_t size )
122 {
123   mData = data;
124   mSize = size;
125   mDataChanged = true;
126 }
127
128 bool PropertyBuffer::Update( Context& context, bool isIndexBuffer )
129 {
130   if( !mData || !mFormat || !mSize )
131   {
132     return false;
133   }
134
135   if( !mGpuBuffer || mDataChanged )
136   {
137     if ( ! mGpuBuffer )
138     {
139       mGpuBuffer = new GpuBuffer( context );
140     }
141
142     // Update the GpuBuffer
143     if ( mGpuBuffer )
144     {
145       DALI_ASSERT_DEBUG( mSize && "No data in the property buffer!" );
146
147       const void *data = &((*mData)[0]);
148       std::size_t dataSize =  GetDataSize();
149
150       // Index buffer needs to be unsigned short which is not supported by the property system
151       Vector<unsigned short> ushortData;
152       if( isIndexBuffer )
153       {
154         ushortData.Resize(mSize);
155         const unsigned int* unsignedData = static_cast<const unsigned int*>(data);
156         for( unsigned int i = 0; i < mSize; ++i )
157         {
158           ushortData[i] = unsignedData[i];
159         }
160         data = &(ushortData[0]);
161         dataSize = ushortData.Size() * sizeof( unsigned short );
162       }
163
164       GpuBuffer::Target target = GpuBuffer::ARRAY_BUFFER;
165       if(isIndexBuffer)
166       {
167         target = GpuBuffer::ELEMENT_ARRAY_BUFFER;
168       }
169       mGpuBuffer->UpdateDataBuffer( dataSize, data, GpuBuffer::STATIC_DRAW, target );
170
171     }
172
173     mDataChanged = false;
174   }
175
176   return true;
177 }
178
179 void PropertyBuffer::BindBuffer(GpuBuffer::Target target)
180 {
181   if(mGpuBuffer)
182   {
183     mGpuBuffer->Bind(target);
184   }
185 }
186
187 unsigned int PropertyBuffer::EnableVertexAttributes( Context& context, Vector<GLint>& vAttributeLocation, unsigned int locationBase )
188 {
189
190   unsigned int attributeCount = mFormat->components.size();
191
192   GLsizei elementSize = mFormat->size;
193
194   for( unsigned int i = 0; i < attributeCount; ++i )
195   {
196     GLint attributeLocation = vAttributeLocation[i+locationBase];
197     if( attributeLocation != -1 )
198     {
199       context.EnableVertexAttributeArray( attributeLocation );
200
201       const GLint attributeSize = mFormat->components[i].size;
202       size_t attributeOffset = mFormat->components[i].offset;
203       const Property::Type attributeType = mFormat->components[i].type;
204
205       context.VertexAttribPointer( attributeLocation,
206                                    attributeSize  / GetPropertyImplementationGlSize(attributeType),
207                                    GetPropertyImplementationGlType(attributeType),
208                                    GL_FALSE,  // Not normalized
209                                    elementSize,
210                                    (void*)attributeOffset );
211     }
212   }
213
214   return attributeCount;
215
216 }
217
218 } //Render
219 } //Internal
220 } //Dali