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