[dali_1.1.6] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-geometry.cpp
1 /*
2  * Copyright (c) 2015 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 <dali/internal/render/renderers/render-geometry.h>
18
19 #include <dali/internal/common/buffer-index.h>
20 #include <dali/internal/update/common/scene-graph-property-buffer.h>
21 #include <dali/internal/update/rendering/scene-graph-geometry.h>
22 #include <dali/internal/render/data-providers/render-data-provider.h>
23 #include <dali/internal/render/gl-resources/context.h>
24 #include <dali/internal/render/gl-resources/gpu-buffer.h>
25 #include <dali/internal/render/shaders/program.h>
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31 namespace SceneGraph
32 {
33
34 RenderGeometry::RenderGeometry( const GeometryDataProvider& geometryDataProvider )
35 : mGeometryDataProvider( geometryDataProvider ),
36   mHasBeenUpdated(false),
37   mAttributesChanged(true)
38 {
39 }
40
41 RenderGeometry::~RenderGeometry()
42 {
43 }
44
45 void RenderGeometry::GlContextCreated( Context& context )
46 {
47 }
48
49 void RenderGeometry::GlContextDestroyed()
50 {
51 }
52
53 void RenderGeometry::AddPropertyBuffer( const PropertyBufferDataProvider* dataProvider, GpuBuffer::Target gpuBufferTarget, GpuBuffer::Usage gpuBufferUsage )
54 {
55   if( gpuBufferTarget == GpuBuffer::ELEMENT_ARRAY_BUFFER )
56   {
57     RenderPropertyBuffer* renderPropertyBuffer = new RenderPropertyBuffer( *dataProvider, gpuBufferTarget, gpuBufferUsage );
58     mIndexBuffer = renderPropertyBuffer;
59   }
60   else if( gpuBufferTarget == GpuBuffer::ARRAY_BUFFER )
61   {
62     RenderPropertyBuffer* renderPropertyBuffer = new RenderPropertyBuffer( *dataProvider, gpuBufferTarget, gpuBufferUsage );
63     mVertexBuffers.PushBack( renderPropertyBuffer );
64     mAttributesChanged = true;
65   }
66 }
67
68 void RenderGeometry::RemovePropertyBuffer( const PropertyBufferDataProvider* dataProvider )
69 {
70   if( dataProvider == &mIndexBuffer->GetDataProvider() )
71   {
72     mIndexBuffer.Reset();
73   }
74   else
75   {
76     for( RenderPropertyBufferIter iter( mVertexBuffers.Begin() ); iter != mVertexBuffers.End(); ++iter )
77     {
78       if( dataProvider == &(*iter)->GetDataProvider() )
79       {
80         //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one
81         mVertexBuffers.Remove( iter );
82         mAttributesChanged = true;
83         break;
84       }
85     }
86   }
87 }
88
89 void RenderGeometry::GetAttributeLocationFromProgram( Vector<GLint>& attributeLocation, Program& program, BufferIndex bufferIndex ) const
90 {
91   attributeLocation.Clear();
92
93   for( size_t i(0); i< mVertexBuffers.Size(); ++i )
94   {
95     unsigned int attributeCount = mVertexBuffers[i]->GetDataProvider().GetAttributeCount( bufferIndex );
96     for( unsigned int j = 0; j < attributeCount; ++j )
97     {
98       const std::string& attributeName = mVertexBuffers[i]->GetDataProvider().GetAttributeName( bufferIndex, j );
99       unsigned int index = program.RegisterCustomAttribute( attributeName );
100       GLint location = program.GetCustomAttributeLocation( index );
101
102       if( -1 == location )
103       {
104         DALI_LOG_WARNING( "Attribute not found in the shader: %s\n", attributeName.c_str() );
105       }
106
107       attributeLocation.PushBack( location );
108     }
109   }
110 }
111
112 void RenderGeometry::OnRenderFinished()
113 {
114   mHasBeenUpdated = false;
115   mAttributesChanged = false;
116 }
117
118 void RenderGeometry::UploadAndDraw(
119     Context& context,
120     BufferIndex bufferIndex,
121     Vector<GLint>& attributeLocation )
122 {
123   if( !mHasBeenUpdated )
124   {
125     //Update buffers
126     if( mIndexBuffer )
127     {
128       mIndexBuffer->Update( context, bufferIndex );
129     }
130     for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
131     {
132       mVertexBuffers[i]->Update( context, bufferIndex );
133     }
134     mHasBeenUpdated = true;
135   }
136
137   //Bind buffers to attribute locations
138   unsigned int base = 0;
139   for( unsigned int i = 0; i < mVertexBuffers.Count(); ++i )
140   {
141     mVertexBuffers[i]->BindBuffer( context );
142     base += mVertexBuffers[i]->EnableVertexAttributes( context, bufferIndex, attributeLocation, base );
143   }
144
145   if( mIndexBuffer )
146   {
147     mIndexBuffer->BindBuffer( context );
148   }
149
150   //Bind index buffer
151   unsigned int numIndices(0u);
152   if( mIndexBuffer )
153   {
154     const PropertyBufferDataProvider& indexBuffer = mIndexBuffer->GetDataProvider();
155     numIndices = mIndexBuffer->GetDataProvider().GetDataSize(bufferIndex) / indexBuffer.GetElementSize(bufferIndex);
156   }
157
158   //Draw call
159   GeometryDataProvider::GeometryType type = mGeometryDataProvider.GetGeometryType( bufferIndex );
160   switch(type)
161   {
162     case Dali::Geometry::TRIANGLES:
163     {
164       if( numIndices )
165       {
166         context.DrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
167       }
168       else
169       {
170         const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider();
171         unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex );
172         context.DrawArrays( GL_TRIANGLES, 0, numVertices );
173       }
174       break;
175     }
176     case Dali::Geometry::LINES:
177     {
178       if( numIndices )
179       {
180         context.DrawElements(GL_LINES, numIndices, GL_UNSIGNED_SHORT, 0);
181       }
182       else
183       {
184         const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider();
185         unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex );
186         context.DrawArrays( GL_LINES, 0, numVertices );
187       }
188       break;
189     }
190     case Dali::Geometry::POINTS:
191     {
192       const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider();
193       unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex );
194       context.DrawArrays(GL_POINTS, 0, numVertices );
195       break;
196     }
197     case Dali::Geometry::TRIANGLE_STRIP:
198     {
199       if( numIndices )
200       {
201         context.DrawElements(GL_TRIANGLE_STRIP, numIndices, GL_UNSIGNED_SHORT, 0);
202       }
203       else
204       {
205         const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider();
206         unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex );
207         context.DrawArrays(GL_TRIANGLE_STRIP, 0, numVertices );
208       }
209       break;
210     }
211     case Dali::Geometry::TRIANGLE_FAN:
212     {
213       if( numIndices )
214       {
215         context.DrawElements(GL_TRIANGLE_FAN, numIndices, GL_UNSIGNED_SHORT, 0);
216       }
217       else
218       {
219         const PropertyBufferDataProvider& firstVertexBuffer = mVertexBuffers[0]->GetDataProvider();
220         unsigned int numVertices = firstVertexBuffer.GetElementCount( bufferIndex );
221         context.DrawArrays(GL_TRIANGLE_FAN, 0, numVertices );
222       }
223       break;
224     }
225     default:
226     {
227       DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" );
228       break;
229     }
230   }
231
232   //Disable atrributes
233   for( unsigned int i = 0; i < attributeLocation.Count(); ++i )
234   {
235     if( attributeLocation[i] != -1 )
236     {
237       context.DisableVertexAttributeArray( attributeLocation[i] );
238     }
239   }
240 }
241
242 } // namespace SceneGraph
243 } // namespace Internal
244 } // namespace Dali