[Vulkan] graphics controller, multiple pipelines
[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 #include <dali/internal/common/buffer-index.h>
19 #include <dali/internal/render/gl-resources/context.h>
20 #include <dali/internal/render/gl-resources/gpu-buffer.h>
21 #include <dali/internal/render/renderers/render-property-buffer.h>
22 #include <dali/internal/render/shaders/program.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace Render
29 {
30
31 Geometry::Geometry()
32 : mIndices(),
33   mIndexBuffer(NULL),
34   mGeometryType( Dali::Geometry::TRIANGLES ),
35   mIndicesChanged(false),
36   mHasBeenUpdated(false),
37   mAttributesChanged(true)
38 {
39 }
40
41 Geometry::~Geometry()
42 {
43 }
44
45 void Geometry::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
46 {
47   mVertexBuffers.PushBack( propertyBuffer );
48   mAttributesChanged = true;
49 }
50
51 void Geometry::SetIndexBuffer( Dali::Vector<unsigned short>& indices )
52 {
53   mIndices.Swap( indices );
54   mIndicesChanged = true;
55 }
56
57 void Geometry::RemovePropertyBuffer( const Render::PropertyBuffer* propertyBuffer )
58 {
59   size_t bufferCount = mVertexBuffers.Size();
60   for( size_t i(0); i<bufferCount; ++i )
61   {
62     if( propertyBuffer == mVertexBuffers[i] )
63     {
64       //This will delete the gpu buffer associated to the RenderPropertyBuffer if there is one
65       mVertexBuffers.Remove( mVertexBuffers.Begin()+i );
66       mAttributesChanged = true;
67       break;
68     }
69   }
70 }
71
72
73
74 void Geometry::GetAttributeLocationFromProgram( Vector<GLint>& attributeLocation, Program& program, BufferIndex bufferIndex ) const
75 {
76   attributeLocation.Clear();
77
78   for( size_t i(0); i< mVertexBuffers.Size(); ++i )
79   {
80     unsigned int attributeCount = mVertexBuffers[i]->GetAttributeCount();
81     for( unsigned int j = 0; j < attributeCount; ++j )
82     {
83       const std::string& attributeName = mVertexBuffers[i]->GetAttributeName( j );
84       unsigned int index = program.RegisterCustomAttribute( attributeName );
85       GLint location = program.GetCustomAttributeLocation( index );
86
87       if( -1 == location )
88       {
89         DALI_LOG_WARNING( "Attribute not found in the shader: %s\n", attributeName.c_str() );
90       }
91
92       attributeLocation.PushBack( location );
93     }
94   }
95 }
96
97 void Geometry::OnRenderFinished()
98 {
99   mHasBeenUpdated = false;
100   mAttributesChanged = false;
101 }
102
103 void Geometry::UploadAndDraw(
104     Graphics::API::Controller& controller,
105     BufferIndex bufferIndex,
106     Vector<GLint>& attributeLocation,
107     size_t elementBufferOffset,
108     size_t elementBufferCount )
109 {
110 #if 0
111   if( !mHasBeenUpdated )
112   {
113     // Update buffers
114     if( mIndicesChanged )
115     {
116       if( mIndices.Empty() )
117       {
118         mIndexBuffer = NULL;
119       }
120       else
121       {
122         if ( mIndexBuffer == NULL )
123         {
124           mIndexBuffer = new GpuBuffer( context );
125         }
126
127         std::size_t bufferSize =  sizeof( unsigned short ) * mIndices.Size();
128         mIndexBuffer->UpdateDataBuffer( bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER );
129       }
130
131       mIndicesChanged = false;
132     }
133
134     size_t count = mVertexBuffers.Count();
135     for( unsigned int i = 0; i < count; ++i )
136     {
137
138       if( !mVertexBuffers[i]->Update(  ) )
139       {
140         //Vertex buffer is not ready ( Size, data or format has not been specified yet )
141         return;
142       }
143     }
144
145     mHasBeenUpdated = true;
146   }
147
148   //Bind buffers to attribute locations
149   unsigned int base = 0u;
150   size_t vertexBufferCount(mVertexBuffers.Count());
151   for( unsigned int i = 0; i < vertexBufferCount; ++i )
152   {
153     mVertexBuffers[i]->BindBuffer( GpuBuffer::ARRAY_BUFFER );
154     base += mVertexBuffers[i]->EnableVertexAttributes( context, attributeLocation, base );
155   }
156
157   size_t numIndices(0u);
158   intptr_t firstIndexOffset(0u);
159   if( mIndexBuffer )
160   {
161     numIndices = mIndices.Size();
162
163     if( elementBufferOffset != 0u )
164     {
165       elementBufferOffset = elementBufferOffset >= numIndices ? numIndices - 1 : elementBufferOffset;
166       firstIndexOffset = elementBufferOffset * sizeof(GLushort);
167       numIndices -= elementBufferOffset;
168     }
169
170     if( elementBufferCount != 0u )
171     {
172       numIndices = std::min( elementBufferCount, numIndices );
173     }
174   }
175
176   GLenum geometryGLType(GL_NONE);
177   switch(mGeometryType)
178   {
179     case Dali::Geometry::TRIANGLES:
180     {
181       geometryGLType = GL_TRIANGLES;
182       break;
183     }
184     case Dali::Geometry::LINES:
185     {
186       geometryGLType = GL_LINES;
187       break;
188     }
189     case Dali::Geometry::POINTS:
190     {
191       geometryGLType = GL_POINTS;
192       break;
193     }
194     case Dali::Geometry::TRIANGLE_STRIP:
195     {
196       geometryGLType = GL_TRIANGLE_STRIP;
197       break;
198     }
199     case Dali::Geometry::TRIANGLE_FAN:
200     {
201       geometryGLType = GL_TRIANGLE_FAN;
202       break;
203     }
204     case Dali::Geometry::LINE_LOOP:
205     {
206       geometryGLType = GL_LINE_LOOP;
207       break;
208     }
209     case Dali::Geometry::LINE_STRIP:
210     {
211       geometryGLType = GL_LINE_STRIP;
212       break;
213     }
214   }
215
216   //Draw call
217   if( mIndexBuffer && geometryGLType != GL_POINTS )
218   {
219     //Indexed draw call
220     mIndexBuffer->Bind( GpuBuffer::ELEMENT_ARRAY_BUFFER );
221     context.DrawElements(geometryGLType, numIndices, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(firstIndexOffset));
222   }
223   else
224   {
225     //Unindex draw call
226     unsigned int numVertices(0u);
227     if( vertexBufferCount > 0 )
228     {
229       numVertices = mVertexBuffers[0]->GetElementCount();
230     }
231
232     context.DrawArrays( geometryGLType, 0, numVertices );
233   }
234
235   //Disable attributes
236   for( unsigned int i = 0; i < attributeLocation.Count(); ++i )
237   {
238     if( attributeLocation[i] != -1 )
239     {
240       context.DisableVertexAttributeArray( attributeLocation[i] );
241     }
242   }
243 #endif
244 }
245
246 } // namespace SceneGraph
247 } // namespace Internal
248 } // namespace Dali