2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/update/modeling/scene-graph-mesh.h>
22 #include <dali/internal/render/common/post-process-resource-dispatcher.h>
23 #include <dali/internal/render/gl-resources/context.h>
24 #include <dali/internal/render/queue/render-queue.h>
35 Mesh::Mesh( ResourceId id,
36 PostProcessResourceDispatcher& postProcessResourceDispatcher,
37 RenderQueue& renderQueue,
40 mPostProcessResourceDispatcher(postProcessResourceDispatcher),
41 mRenderQueue(renderQueue),
42 mUpdateMeshData(meshData),
43 mRenderMeshData(meshData),
46 mNumberOfVertices(0u),
49 mRefreshVertexBuffer(true)
57 void Mesh::SetMeshData(MeshData* meshData)
59 mUpdateMeshData = meshData;
62 MeshData& Mesh::GetMeshData( Mesh::ThreadBuffer threadBuffer )
64 return const_cast<MeshData&>(static_cast<const Mesh*>(this)->GetMeshData(threadBuffer));
67 const MeshData& Mesh::GetMeshData( Mesh::ThreadBuffer threadBuffer ) const
69 MeshData* meshDataPtr = NULL;
73 case Mesh::UPDATE_THREAD:
76 meshDataPtr = mUpdateMeshData;
80 case Mesh::RENDER_THREAD:
82 meshDataPtr = &(*mRenderMeshData);
87 DALI_ASSERT_DEBUG( meshDataPtr );
91 void Mesh::RefreshVertexBuffer()
93 mRefreshVertexBuffer = true;
96 void Mesh::MeshDataUpdated( BufferIndex bufferIndex, Mesh::ThreadBuffer threadBuffer, MeshData* meshData )
98 if ( threadBuffer == Mesh::RENDER_THREAD )
100 // Called from a message, the old MeshData will be release and the new one is saved.
101 mRenderMeshData = meshData;
102 RefreshVertexBuffer();
106 // Dynamics and animatable meshes don't create new mesh data
107 DALI_ASSERT_DEBUG( threadBuffer == Mesh::UPDATE_THREAD );
108 DALI_ASSERT_DEBUG( meshData == NULL );
110 // Send a message to self in render thread
111 typedef Message< Mesh > LocalType;
112 unsigned int* slot = mRenderQueue.ReserveMessageSlot( bufferIndex, sizeof( LocalType ) );
113 new (slot) LocalType( this, &Mesh::RefreshVertexBuffer);
117 void Mesh::UploadVertexData( Context& context, BufferIndex renderBufferIndex )
119 // Short-circuit if nothing has changed
120 if ( !mRefreshVertexBuffer )
127 // Note, dispatcher should only be used in Render Thread (as should the rest of this method!)
128 ResourcePostProcessRequest ppRequest( mResourceId, ResourcePostProcessRequest::UPLOADED );
129 mPostProcessResourceDispatcher.DispatchPostProcessRequest(ppRequest);
131 mRenderMeshData->Discard();
132 mRefreshVertexBuffer = false;
135 void Mesh::DoUpload( Context& context )
137 const MeshData::VertexContainer& vertices = mRenderMeshData->GetVertices();
139 DALI_ASSERT_DEBUG( !vertices.empty() );
140 if ( !mVertexBuffer )
142 mVertexBuffer = new GpuBuffer(context,GpuBuffer::ARRAY_BUFFER,GpuBuffer::STATIC_DRAW);
144 DALI_ASSERT_DEBUG(mVertexBuffer);
146 mVertexBuffer->UpdateDataBuffer( vertices.size() * sizeof(MeshData::Vertex), &vertices.at(0) );
147 mNumberOfVertices = mRenderMeshData->GetVertexCount();
149 if ( size_t numberOfIndices = mRenderMeshData->GetFaceIndexCount() )
151 const MeshData::FaceIndices& faces = mRenderMeshData->GetFaces();
152 DALI_ASSERT_DEBUG(!faces.empty());
154 if ( !mIndicesBuffer )
156 mIndicesBuffer = new GpuBuffer(context,GpuBuffer::ELEMENT_ARRAY_BUFFER,GpuBuffer::STATIC_DRAW);
159 mIndicesBuffer->UpdateDataBuffer( numberOfIndices * sizeof(GLushort), &(faces.at(0)) );
160 mNumberOfFaces = mRenderMeshData->GetFaceCount();
164 void Mesh::BindBuffers(Context& context)
166 // Short-circuit if nothing has changed
167 if ( !mVertexBuffer )
172 DALI_ASSERT_DEBUG( mIndicesBuffer || mRenderMeshData->GetVertexGeometryType() == Dali::MeshData::POINTS );
174 // Try and recover from context loss using retained data.
175 if( ! mVertexBuffer->BufferIsValid() && ! mRenderMeshData->GetVertices().empty() )
180 if( mVertexBuffer->BufferIsValid() )
182 mVertexBuffer->Bind();
185 if( mIndicesBuffer && mIndicesBuffer->BufferIsValid())
187 mIndicesBuffer->Bind();
191 size_t Mesh::GetFaceIndexCount( ThreadBuffer threadBuffer ) const
193 DALI_ASSERT_DEBUG( threadBuffer == Mesh::RENDER_THREAD );
195 switch( GetMeshData(threadBuffer).GetVertexGeometryType() )
197 case Dali::MeshData::POINTS:
198 faceCount = mNumberOfVertices;
200 case Dali::MeshData::LINES:
201 faceCount = mNumberOfFaces*2;
203 case Dali::MeshData::TRIANGLES:
204 faceCount = mNumberOfFaces*3;
211 bool Mesh::HasGeometry( ThreadBuffer threadBuffer ) const
213 return GetMeshData(threadBuffer).GetVertexCount() > 0;
216 void Mesh::GlContextDestroyed()
220 mVertexBuffer->GlContextDestroyed();
224 mIndicesBuffer->GlContextDestroyed();
228 void Mesh::GlCleanup()
230 mVertexBuffer = NULL;
231 mIndicesBuffer = NULL;
234 } // namespace SceneGraph
236 } // namespace Internal