Changed passing of data providers to renderers
[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 "render-geometry.h"
18
19 #include <dali/internal/common/buffer-index.h>
20 #include <dali/internal/update/geometry/scene-graph-geometry.h>
21 #include <dali/internal/update/common/scene-graph-property-buffer.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()
35 : mDataNeedsUploading( true )
36 {
37 }
38
39 RenderGeometry::~RenderGeometry()
40 {
41 }
42
43 void RenderGeometry::GlContextCreated( Context& context )
44 {
45   mDataNeedsUploading = true;
46 }
47
48 void RenderGeometry::GlContextDestroyed()
49 {
50   for( GpuBuffers::Iterator iter=mVertexBuffers.Begin(); iter != mVertexBuffers.End(); ++iter )
51   {
52     GpuBuffer* gpuBuffer = *iter;
53     if( gpuBuffer )
54     {
55       gpuBuffer->GlContextDestroyed();
56     }
57   }
58
59   if( mIndexBuffer )
60   {
61     mIndexBuffer->GlContextDestroyed();
62   }
63 }
64
65 void RenderGeometry::UploadAndDraw(
66   Context& context,
67   Program& program,
68   BufferIndex bufferIndex,
69   const RenderDataProvider* dataProviders )
70 {
71   UploadVertexData( context, bufferIndex, dataProviders );
72   BindBuffers();
73   EnableVertexAttributes( context, program );
74   Draw( context, bufferIndex, dataProviders );
75   DisableVertexAttributes( context, program );
76 }
77
78 void RenderGeometry::GeometryUpdated()
79 {
80   mDataNeedsUploading = true;
81 }
82
83 void RenderGeometry::UploadVertexData(
84   Context& context,
85   BufferIndex bufferIndex,
86   const RenderDataProvider* dataProviders )
87 {
88   if( mDataNeedsUploading ) // @todo Or if any of the property buffers are dirty
89   {
90     DoUpload( context, bufferIndex, dataProviders );
91
92     mDataNeedsUploading = false;
93   }
94 }
95
96 void RenderGeometry::DoUpload(
97   Context& context,
98   BufferIndex bufferIndex,
99   const RenderDataProvider* dataProvider )
100 {
101   // Vertex buffer
102   RenderDataProvider::VertexBuffers vertexBuffers = dataProvider->GetVertexBuffers();
103
104   DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Need vertex buffers to upload" );
105
106   for( unsigned int i=0; i<vertexBuffers.Count(); ++i)
107   {
108     const PropertyBuffer* vertexBuffer = vertexBuffers[i];
109
110     // @todo MESH_REWORK STATIC_DRAW or DYNAMIC_DRAW depends on property buffer type (static / animated)
111     GpuBuffer* vertexGpuBuffer = new GpuBuffer( context, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
112
113     std::size_t dataSize = vertexBuffer->GetDataSize( bufferIndex );
114     vertexGpuBuffer->UpdateDataBuffer( dataSize, vertexBuffer->GetData( bufferIndex ) );
115     vertexGpuBuffer->SetStride( vertexBuffer->GetElementSize( bufferIndex ) );
116
117     mVertexBuffers.PushBack( vertexGpuBuffer );
118   }
119
120   // Index buffer
121   const PropertyBuffer* indexBuffer = dataProvider->GetIndexBuffer();
122   if( indexBuffer )
123   {
124     GpuBuffer* indexGpuBuffer = new GpuBuffer( context, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW );
125
126     unsigned int dataSize = indexBuffer->GetDataSize( bufferIndex );
127     indexGpuBuffer->UpdateDataBuffer( dataSize, indexBuffer->GetData( bufferIndex ) );
128
129     mIndexBuffer.Reset();
130     mIndexBuffer = indexGpuBuffer;
131   }
132 }
133
134 void RenderGeometry::BindBuffers()
135 {
136   for( GpuBuffers::Iterator iter=mVertexBuffers.Begin(); iter != mVertexBuffers.End(); ++iter )
137   {
138     (*iter)->Bind();
139   }
140
141   if( mIndexBuffer )
142   {
143     mIndexBuffer->Bind();
144   }
145 }
146
147 void RenderGeometry::EnableVertexAttributes( Context& context, Program& program )
148 {
149   // @todo Loop thru the array of vertex buffers
150   // @todo Use AttributeDataProvider to get the attrs and enable them
151   // Need mapping from gpu buffers index to a particular attributes
152   Vector4 *vertex=0;
153
154   unsigned int gpuBufferIndex = 0;
155
156   GLint positionLoc = program.GetAttribLocation( Program::ATTRIB_POSITION );
157   context.VertexAttribPointer( positionLoc,
158                                 2,         // 2D position
159                                 GL_FLOAT,
160                                 GL_FALSE,  // Not normalized
161                                 mVertexBuffers[gpuBufferIndex]->GetStride(),
162                                 &vertex->x );
163
164   context.EnableVertexAttributeArray( positionLoc );
165
166   GLint textureCoordsLoc = program.GetAttribLocation( Program::ATTRIB_TEXCOORD );
167   context.VertexAttribPointer( textureCoordsLoc,
168                                 2,         // Texture Coords = U, V
169                                 GL_FLOAT,
170                                 GL_FALSE,
171                                 mVertexBuffers[gpuBufferIndex]->GetStride(),
172                                 &vertex->z );
173   context.EnableVertexAttributeArray( textureCoordsLoc );
174 }
175
176 void RenderGeometry::DisableVertexAttributes( Context& context, Program& program )
177 {
178   // @todo Loop thru the array of vertex buffers
179   // @todo Use AttributeDataProvider to get the attrs and disable them
180   GLint positionLoc = program.GetAttribLocation( Program::ATTRIB_POSITION );
181   GLint textureCoordsLoc = program.GetAttribLocation( Program::ATTRIB_TEXCOORD );
182   context.DisableVertexAttributeArray( positionLoc );
183   context.DisableVertexAttributeArray( textureCoordsLoc );
184 }
185
186 void RenderGeometry::Draw( Context& context, BufferIndex bufferIndex, const RenderDataProvider* dataProvider )
187 {
188   const GeometryDataProvider& geometry = dataProvider->GetGeometry();
189   const PropertyBuffer* indexBuffer = dataProvider->GetIndexBuffer();
190
191   GeometryDataProvider::GeometryType type = geometry.GetGeometryType( bufferIndex );
192
193   unsigned int numIndices = 0;
194   if( indexBuffer )
195   {
196     numIndices = /* TODO: MESH_REWORK remove this 2, should implement unsigned short properties  */ 2 * indexBuffer->GetDataSize(bufferIndex) / indexBuffer->GetElementSize(bufferIndex);
197   }
198
199   switch(type)
200   {
201     case Dali::Geometry::TRIANGLES:
202     {
203       context.DrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
204       break;
205     }
206     case Dali::Geometry::LINES:
207     {
208       context.DrawElements(GL_LINES, numIndices, GL_UNSIGNED_SHORT, 0);
209       break;
210     }
211     case Dali::Geometry::POINTS:
212     {
213       GpuBuffer* firstVertexBuffer = mVertexBuffers[0];
214
215       unsigned int numVertices = 0;
216       GLuint stride = firstVertexBuffer->GetStride();
217       if( stride != 0 )
218       {
219         numVertices = firstVertexBuffer->GetBufferSize() / stride;
220       }
221
222       context.DrawArrays(GL_POINTS, 0, numVertices );
223       break;
224     }
225     default:
226     {
227       DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" );
228       break;
229     }
230   }
231 }
232
233 } // namespace SceneGraph
234 } // namespace Internal
235 } // namespace Dali