From: David Steele Date: Tue, 10 Mar 2015 18:38:52 +0000 (+0000) Subject: Created renderer objects. X-Git-Tag: dali_1.0.47~8^2^2~66 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F15%2F36615%2F4;p=platform%2Fcore%2Fuifw%2Fdali-core.git Created renderer objects. Change-Id: I936104af411117acf0f96cd81220a37f6de83c60 Signed-off-by: David Steele --- diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h index 071282a..29d868e 100644 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -51,7 +51,6 @@ namespace Internal class NotificationManager; class AnimationPlaylist; class PropertyNotificationManager; -class Context; class EventProcessor; class GestureEventProcessor; class ResourceClient; diff --git a/dali/internal/common/image-sampler.cpp b/dali/internal/common/image-sampler.cpp index 8dfa702..036a69a 100644 --- a/dali/internal/common/image-sampler.cpp +++ b/dali/internal/common/image-sampler.cpp @@ -33,6 +33,8 @@ namespace ImageSampler namespace { +// @todo MESH_REWORK Remove file after image removal + // Adjust these shift sizes if the FilterMode enum grows const int MINIFY_BIT_SHIFT = 0; // Room for 16 const int MAGNIFY_BIT_SHIFT = 4; diff --git a/dali/internal/common/owner-pointer.h b/dali/internal/common/owner-pointer.h index d8bf7ea..7b92978 100644 --- a/dali/internal/common/owner-pointer.h +++ b/dali/internal/common/owner-pointer.h @@ -178,7 +178,7 @@ public: * Returns a const pointer to the object owned. * @return a const pointer to the object. */ - const T* Get() + const T* Get() const { return mObject; } diff --git a/dali/internal/event/common/type-info-impl.cpp b/dali/internal/event/common/type-info-impl.cpp index 91e50cf..35cc27a 100644 --- a/dali/internal/event/common/type-info-impl.cpp +++ b/dali/internal/event/common/type-info-impl.cpp @@ -220,7 +220,6 @@ void TypeInfo::GetSignals(Dali::TypeInfo::NameContainer& ret) const void TypeInfo::GetProperties( Dali::TypeInfo::NameContainer& ret ) const { Property::IndexContainer indices; - GetPropertyIndices(indices); ret.reserve(indices.size()); diff --git a/dali/internal/file.list b/dali/internal/file.list index 6483c94..e989aef 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -134,6 +134,8 @@ internal_src_files = \ $(internal_src_dir)/render/gl-resources/texture-factory.cpp \ $(internal_src_dir)/render/gl-resources/texture-cache.cpp \ $(internal_src_dir)/render/queue/render-queue.cpp \ + $(internal_src_dir)/render/renderers/render-geometry.cpp \ + $(internal_src_dir)/render/renderers/render-renderer.cpp \ $(internal_src_dir)/render/renderers/scene-graph-image-renderer.cpp \ $(internal_src_dir)/render/renderers/scene-graph-renderer.cpp \ $(internal_src_dir)/render/renderers/scene-graph-renderer-debug.cpp \ @@ -173,8 +175,8 @@ internal_src_files = \ $(internal_src_dir)/update/node-attachments/scene-graph-camera-attachment.cpp \ $(internal_src_dir)/update/node-attachments/scene-graph-image-attachment.cpp \ $(internal_src_dir)/update/node-attachments/scene-graph-renderable-attachment.cpp \ - $(internal_src_dir)/update/node-attachments/scene-graph-text-attachment.cpp \ $(internal_src_dir)/update/node-attachments/scene-graph-renderer-attachment.cpp \ + $(internal_src_dir)/update/node-attachments/scene-graph-text-attachment.cpp \ $(internal_src_dir)/update/nodes/node.cpp \ $(internal_src_dir)/update/nodes/node-messages.cpp \ $(internal_src_dir)/update/nodes/scene-graph-layer.cpp \ diff --git a/dali/internal/render/common/render-algorithms.h b/dali/internal/render/common/render-algorithms.h index 7cf9ecc..6a3d8e9 100644 --- a/dali/internal/render/common/render-algorithms.h +++ b/dali/internal/render/common/render-algorithms.h @@ -23,10 +23,8 @@ namespace Dali { - namespace Internal { - class Context; namespace SceneGraph @@ -59,4 +57,3 @@ void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction, } // namespace Dali #endif // __DALI_INTERNAL_RENDER_ALGORITHMS_H__ - diff --git a/dali/internal/render/renderers/attribute-data-provider.h b/dali/internal/render/data-providers/attribute-data-provider.h similarity index 100% rename from dali/internal/render/renderers/attribute-data-provider.h rename to dali/internal/render/data-providers/attribute-data-provider.h diff --git a/dali/internal/render/data-providers/geometry-data-provider.h b/dali/internal/render/data-providers/geometry-data-provider.h new file mode 100644 index 0000000..e40a9ed --- /dev/null +++ b/dali/internal/render/data-providers/geometry-data-provider.h @@ -0,0 +1,86 @@ +#ifndef __DALI_INTERNAL_SCENE_GRAPH_GEOMETRY_DATA_PROVIDER_H__ +#define __DALI_INTERNAL_SCENE_GRAPH_GEOMETRY_DATA_PROVIDER_H__ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ +class PropertyBuffer; + +/** + * An interface to provide geometry data, such as the vertex buffers + * and index buffers (if present). It provides a means of getting the + * vertex attribute meta data and vertex data from each buffer. It + * provides the geometry type; + */ +class GeometryDataProvider +{ +public: + typedef Dali::Geometry::GeometryType GeometryType; + typedef OwnerContainer< PropertyBuffer* > VertexBuffers; + + /** + * Constructor. Nothing to do as a pure interface. + */ + GeometryDataProvider() { } + +public: // GeometryDataProvider + /** + * Get the vertex buffers of the geometry + * @return A const reference to the vertex buffers + */ + virtual const VertexBuffers& GetVertexBuffers() const = 0; + + /** + * Get the index buffer of the geometry + * @return A const reference to the index buffer + */ + virtual const PropertyBuffer* GetIndexBuffer() const = 0; + + /** + * Get the type of geometry to draw + */ + virtual GeometryType GetGeometryType( BufferIndex bufferIndex ) const = 0; + + /** + * @todo MESH_REWORK - Should only use this in Update Sorting algorithm + * Returns true if this geometry requires depth testing, e.g. if it is + * a set of vertices with z != 0 + */ + virtual bool GetRequiresDepthTest( BufferIndex bufferIndex ) const = 0; + +protected: + + /** + * Virtual destructor, this is an interface, no deletion through this interface + */ + virtual ~GeometryDataProvider() { } +}; + +} // SceneGraph +} // Internal +} // Dali + +#endif // __DALI_INTERNAL_SCENE_GRAPH_GEOMETRY_DATA_PROVIDER_H__ diff --git a/dali/internal/render/renderers/material-data-provider.h b/dali/internal/render/data-providers/material-data-provider.h similarity index 88% rename from dali/internal/render/renderers/material-data-provider.h rename to dali/internal/render/data-providers/material-data-provider.h index 4102f56..0be80e5 100644 --- a/dali/internal/render/renderers/material-data-provider.h +++ b/dali/internal/render/data-providers/material-data-provider.h @@ -16,6 +16,8 @@ * limitations under the License. */ +#include + namespace Dali { namespace Internal @@ -28,7 +30,7 @@ class SamplerDataProvider; class MaterialDataProvider { public: - typedef Dali::Vector< SamplerDataProvider* > Samplers; + typedef Dali::Vector< const SamplerDataProvider* > Samplers; /** * Construtor @@ -41,7 +43,7 @@ public: * Returns the list of samplers that this material provides * @return The list of samplers */ - const Samplers& GetSamplers(); + virtual const Samplers& GetSamplers() const = 0; protected: /** diff --git a/dali/internal/render/renderers/render-data-provider.h b/dali/internal/render/data-providers/node-data-provider.h similarity index 79% rename from dali/internal/render/renderers/render-data-provider.h rename to dali/internal/render/data-providers/node-data-provider.h index 344d2d6..cfb293d 100644 --- a/dali/internal/render/renderers/render-data-provider.h +++ b/dali/internal/render/data-providers/node-data-provider.h @@ -1,7 +1,8 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_DATA_PROVIDER_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_DATA_PROVIDER_H__ +#ifndef __DALI_INTERNAL_SCENE_GRAPH_NODE_DATA_PROVIDER_H__ +#define __DALI_INTERNAL_SCENE_GRAPH_NODE_DATA_PROVIDER_H__ + /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2015 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,14 +31,14 @@ namespace SceneGraph /** * An interface to provide data for a Renderer */ -class RenderDataProvider +class NodeDataProvider { public: /** * Constructor. Nothing to do as a pure interface. */ - RenderDataProvider() { } + NodeDataProvider() { } /** * @param bufferId to use @@ -56,11 +57,11 @@ protected: /** * Virtual destructor, this is an interface, no deletion through this interface */ - virtual ~RenderDataProvider() { } + virtual ~NodeDataProvider() { } }; } // SceneGraph } // Internal } // Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_DATA_PROVIDER_H__ +#endif // __DALI_INTERNAL_SCENE_GRAPH_NODE_DATA_PROVIDER_H__ diff --git a/dali/internal/render/renderers/sampler-data-provider.h b/dali/internal/render/data-providers/sampler-data-provider.h similarity index 82% rename from dali/internal/render/renderers/sampler-data-provider.h rename to dali/internal/render/data-providers/sampler-data-provider.h index 5af4e4c..cd589ff 100644 --- a/dali/internal/render/renderers/sampler-data-provider.h +++ b/dali/internal/render/data-providers/sampler-data-provider.h @@ -43,38 +43,44 @@ public: } /** + * Get the sampler's texture unit uniform name + * @return The texture unit uniform name + */ + virtual const std::string& GetUnitName() const = 0; + + /** * Get the texture identity associated with the sampler * @return The texture identity */ - virtual ResourceId GetTextureId() = 0; + virtual ResourceId GetTextureId( BufferIndex bufferIndex ) const = 0; /** * Get the filter mode * @param[in] bufferIndex The buffer index to use * @return The minify filter mode */ - virtual FilterMode GetMinifyFilterMode( BufferIndex bufferIndex ) = 0; + virtual FilterMode GetMinifyFilterMode( BufferIndex bufferIndex ) const = 0; /** * Get the filter mode * @param[in] bufferIndex The buffer index to use * @return The magnify filter mode */ - virtual FilterMode GetMagifyFilterMode( BufferIndex bufferIndex ) = 0; + virtual FilterMode GetMagnifyFilterMode( BufferIndex bufferIndex ) const = 0; /** * Get the horizontal wrap mode * @param[in] bufferIndex The buffer index to use * @return The horizontal wrap mode */ - virtual WrapMode GetUWrapMode( BufferIndex bufferIndex ) = 0; + virtual WrapMode GetUWrapMode( BufferIndex bufferIndex ) const = 0; /** * Get the vertical wrap mode * @param[in] bufferIndex The buffer index to use * @return The vertical wrap mode */ - virtual WrapMode GetVWrapMode( BufferIndex bufferIndex ) = 0; + virtual WrapMode GetVWrapMode( BufferIndex bufferIndex ) const = 0; protected: /** diff --git a/dali/internal/render/data-providers/uniform-map-provider.h b/dali/internal/render/data-providers/uniform-map-provider.h new file mode 100644 index 0000000..f5b3c97 --- /dev/null +++ b/dali/internal/render/data-providers/uniform-map-provider.h @@ -0,0 +1,61 @@ +#ifndef DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_PROVIDER_H +#define DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_PROVIDER_H + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ + +/** + * This class maps uniform names to property value pointers. + * After the first string lookup, it caches the uniform location to avoid + * further lookups. + */ +class UniformMapProvider +{ +public: + /** + * Constructor + */ + UniformMapProvider() + { + } + + // @todo Force material color? + +protected: + + /** + * No deletion through this interface + */ + virtual ~UniformMapProvider() + { + } +}; + +} // namespace SceneGraph +} // namespace Internal +} // namespace Dali + +#endif // DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_PROVIDER_H diff --git a/dali/internal/render/gl-resources/gpu-buffer.h b/dali/internal/render/gl-resources/gpu-buffer.h index f356e66..04b24f4 100644 --- a/dali/internal/render/gl-resources/gpu-buffer.h +++ b/dali/internal/render/gl-resources/gpu-buffer.h @@ -82,7 +82,7 @@ public: * @param size Specifies the size in bytes of the buffer object's new data store. * @param data pointer to the data to load */ - void UpdateDataBuffer(GLsizeiptr size,const GLvoid *data); + void UpdateDataBuffer(GLsizeiptr size, const GLvoid *data); /** * Bind the buffer object to the target @@ -104,6 +104,16 @@ public: return mSize; } + void SetStride( GLuint stride ) + { + mStride = stride; + } + + GLuint GetStride() + { + return mStride; + } + /** * Needs to be called when GL context is destroyed */ @@ -123,6 +133,7 @@ private: // Data GLsizeiptr mCapacity; ///< buffer capacity GLsizeiptr mSize; ///< buffer size GLuint mBufferId; ///< buffer object name(id) + GLuint mStride; ///< stride of data in buffer object Target mTarget:2; ///< type of buffer (array/element), 2 bits are enough Usage mUsage:2; ///< how the buffer is used (read, read/write etc), 2 bits are enough diff --git a/dali/internal/render/renderers/render-geometry.cpp b/dali/internal/render/renderers/render-geometry.cpp new file mode 100644 index 0000000..b8dcd92 --- /dev/null +++ b/dali/internal/render/renderers/render-geometry.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "render-geometry.h" + +#include +#include +#include +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ + +RenderGeometry::RenderGeometry() +: mDataNeedsUploading( true ) +{ +} + +RenderGeometry::~RenderGeometry() +{ +} + +void RenderGeometry::GlContextCreated( Context& context ) +{ + mDataNeedsUploading = true; +} + +void RenderGeometry::GlContextDestroyed() +{ + for( GpuBuffers::Iterator iter=mVertexBuffers.Begin(); iter != mVertexBuffers.End(); ++iter ) + { + GpuBuffer* gpuBuffer = *iter; + if( gpuBuffer ) + { + gpuBuffer->GlContextDestroyed(); + } + } + + if( mIndexBuffer ) + { + mIndexBuffer->GlContextDestroyed(); + } +} + +void RenderGeometry::UploadAndDraw( + Context* context, + Program& program, + BufferIndex bufferIndex, + const GeometryDataProvider& geometryDataProvider ) +{ + UploadVertexData( context, bufferIndex, geometryDataProvider ); + BindBuffers(); + EnableVertexAttributes( context, program ); + Draw( context, bufferIndex, geometryDataProvider ); + DisableVertexAttributes( context, program ); +} + +void RenderGeometry::GeometryUpdated() +{ + mDataNeedsUploading = true; +} + +void RenderGeometry::UploadVertexData( + Context* context, + BufferIndex bufferIndex, + const GeometryDataProvider& geometry ) +{ + if( mDataNeedsUploading ) // @todo Or if any of the property buffers are dirty + { + DoUpload( context, bufferIndex, geometry ); + + mDataNeedsUploading = false; + } +} + +void RenderGeometry::DoUpload( + Context* context, + BufferIndex bufferIndex, + const GeometryDataProvider& geometry) +{ + // @todo MESH_REWORK Add support for multiple vertex buffers and attrs + + // Vertex buffer + const Geometry::VertexBuffers& vertexBuffers = geometry.GetVertexBuffers(); + DALI_ASSERT_DEBUG( vertexBuffers.Count() > 0 && "Need vertex buffers to upload" ); + + PropertyBuffer* firstVertexBuffer = vertexBuffers[0]; + + // @todo MESH_REWORK STATIC_DRAW or DYNAMIC_DRAW depends on property buffer type (static / animated) + GpuBuffer* vertexGpuBuffer = new GpuBuffer( *context, GpuBuffer::ARRAY_BUFFER, GpuBuffer::STATIC_DRAW ); + + std::size_t dataSize = firstVertexBuffer->GetDataSize( bufferIndex ); + vertexGpuBuffer->UpdateDataBuffer( dataSize, firstVertexBuffer->GetData( bufferIndex ) ); + vertexGpuBuffer->SetStride( firstVertexBuffer->GetElementSize( bufferIndex ) ); + + mVertexBuffers.PushBack( vertexGpuBuffer ); + + // Index buffer + const PropertyBuffer* indexBuffer = geometry.GetIndexBuffer(); + if( indexBuffer ) + { + GpuBuffer* indexGpuBuffer = new GpuBuffer( *context, GpuBuffer::ELEMENT_ARRAY_BUFFER, GpuBuffer::STATIC_DRAW ); + + dataSize = indexBuffer->GetDataSize( bufferIndex ); + indexGpuBuffer->UpdateDataBuffer( dataSize, indexBuffer->GetData( bufferIndex ) ); + + mIndexBuffer.Reset(); + mIndexBuffer = indexGpuBuffer; + } +} + +void RenderGeometry::BindBuffers() +{ + for( GpuBuffers::Iterator iter=mVertexBuffers.Begin(); iter != mVertexBuffers.End(); ++iter ) + { + (*iter)->Bind(); + } + + if( mIndexBuffer ) + { + mIndexBuffer->Bind(); + } +} + +void RenderGeometry::EnableVertexAttributes( Context* context, Program& program ) +{ + // @todo Loop thru the array of vertex buffers + // @todo Use AttributeDataProvider to get the attrs and enable them + // Need mapping from gpu buffers index to a particular attributes + Vector4 *vertex=0; + + unsigned int gpuBufferIndex = 0; + + GLint positionLoc = program.GetAttribLocation( Program::ATTRIB_POSITION ); + context->VertexAttribPointer( positionLoc, + 2, // 2D position + GL_FLOAT, + GL_FALSE, // Not normalized + mVertexBuffers[gpuBufferIndex]->GetStride(), + &vertex->x ); + + context->EnableVertexAttributeArray( positionLoc ); + + GLint textureCoordsLoc = program.GetAttribLocation( Program::ATTRIB_TEXCOORD ); + context->VertexAttribPointer( textureCoordsLoc, + 2, // Texture Coords = U, V + GL_FLOAT, + GL_FALSE, + mVertexBuffers[gpuBufferIndex]->GetStride(), + &vertex->z ); + context->EnableVertexAttributeArray( textureCoordsLoc ); +} + +void RenderGeometry::DisableVertexAttributes( Context* context, Program& program ) +{ + // @todo Loop thru the array of vertex buffers + // @todo Use AttributeDataProvider to get the attrs and disable them + GLint positionLoc = program.GetAttribLocation( Program::ATTRIB_POSITION ); + GLint textureCoordsLoc = program.GetAttribLocation( Program::ATTRIB_TEXCOORD ); + context->DisableVertexAttributeArray( positionLoc ); + context->DisableVertexAttributeArray( textureCoordsLoc ); +} + +void RenderGeometry::Draw( Context* context, BufferIndex bufferIndex, const GeometryDataProvider& geometry ) +{ + GeometryDataProvider::GeometryType type = geometry.GetGeometryType( bufferIndex ); + + unsigned int numIndices = 0; + const PropertyBuffer* indexBuffer = geometry.GetIndexBuffer(); + + if( indexBuffer ) + { + numIndices = indexBuffer->GetDataSize(bufferIndex) / indexBuffer->GetElementSize(bufferIndex); + } + + switch(type) + { + case Dali::Geometry::TRIANGLES: + { + context->DrawElements(GL_TRIANGLES, numIndices/3, GL_UNSIGNED_SHORT, 0); + break; + } + case Dali::Geometry::LINES: + { + context->DrawElements(GL_LINES, numIndices/2, GL_UNSIGNED_SHORT, 0); + break; + } + case Dali::Geometry::POINTS: + { + GpuBuffer* firstVertexBuffer = mVertexBuffers[0]; + + unsigned int numVertices = 0; + GLuint stride = firstVertexBuffer->GetStride(); + if( stride != 0 ) + { + numVertices = firstVertexBuffer->GetBufferSize() / stride; + } + + context->DrawArrays(GL_POINTS, 0, numVertices ); + break; + } + default: + { + DALI_ASSERT_ALWAYS( 0 && "Geometry type not supported (yet)" ); + break; + } + } +} + +} // namespace SceneGraph +} // namespace Internal +} // namespace Dali diff --git a/dali/internal/render/renderers/render-geometry.h b/dali/internal/render/renderers/render-geometry.h index 4472526..4cb7377 100644 --- a/dali/internal/render/renderers/render-geometry.h +++ b/dali/internal/render/renderers/render-geometry.h @@ -18,13 +18,20 @@ */ #include +#include +#include namespace Dali { namespace Internal { +class Context; +class Program; +class GpuBuffer; + namespace SceneGraph { +class GeometryDataProvider; /** * This class encapsulates the GPU buffers. It is used to upload vertex data @@ -34,28 +41,105 @@ namespace SceneGraph class RenderGeometry { public: - typedef OwnerContainer< GPUBuffer* > GPUBuffers; + typedef OwnerContainer< GpuBuffer* > GpuBuffers; /** - * Constructor + * Constructor. Creates a render geometry object with no GPU buffers. */ - RenderGeometry(); + RenderGeometry( ); /** * Destructor */ + ~RenderGeometry(); + + /** + * Called on Gl Context created + */ + void GlContextCreated( Context& context ); + + /** + * Called on Gl Context destroyed. + */ + void GlContextDestroyed(); + + /** + * Upload the geometry if it has changed, set up the attributes and perform + * the Draw call corresponding to the geometry type + * @param[in] context The GL context + * @param[in] program The shader program to query for attribute locations + * @param[in] bufferIndex The current buffer index + * @param[in] geometryDataProvider The geometry data provider (to fetch geometry from) + */ + void UploadAndDraw(Context* context, + Program& program, + BufferIndex bufferIndex, + const GeometryDataProvider& geometryDataProvider ); + + /** + * Tell the object that the geometry has been updated. + * It will be uploaded on the next UploadAndDraw call. + */ + void GeometryUpdated(); + + /** + * Upload the vertex data if it needs uploading. + * @param[in] context The GL context + * @param[in] bufferIndex The current buffer index + * @param[in] geometryDataProvider The geometry data provider (to fetch geometry from) + */ + void UploadVertexData( Context* context, + BufferIndex bufferIndex, + const GeometryDataProvider& geometryDataProvider ); + - void UploadVertexData(); +private: + /** + * Perform the upload of the geometry + * @param[in] context The GL context + * @param[in] bufferIndex The current buffer index + * @param[in] geometryDataProvider The geometry data provider (to fetch geometry from) + */ + void DoUpload( Context* context, + BufferIndex bufferIndex, + const GeometryDataProvider& geometryDataProvider ); + /** + * Bind the geometry buffers + */ void BindBuffers(); - void EnableVertexAttributes( Program& progam ); + /** + * Enable the vertex attributes for each vertex buffer from the corresponding + * shader program. + * @param[in] context The GL context + * @param[in] program The shader program to query for attribute locations + */ + void EnableVertexAttributes( Context* context, Program& progam ); - void DisableVertexAttributes( Program& program ); + /** + * Disable the vertex attributes for each vertex buffer from the corresponding + * shader program. + * @param[in] context The GL context + * @param[in] program The shader program to query for attribute locations + */ + void DisableVertexAttributes( Context* context, Program& program ); + + /** + * Perform the correct draw call corresponding to the geometry type + * @param[in] context The GL context + * @param[in] bufferIndex The current buffer index + * @param[in] geometryDataProvider The geometry data provider (to fetch geometry from) + */ + void Draw( Context* context, + BufferIndex bufferIndex, + const GeometryDataProvider& geometry ); private: - GPUBuffers mGpuBuffers; - AttributeDataProvider& mAttributeDataProvider; + GpuBuffers mVertexBuffers; + OwnerPointer< GpuBuffer > mIndexBuffer; + + bool mDataNeedsUploading; }; } // namespace SceneGraph diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp new file mode 100644 index 0000000..d360079 --- /dev/null +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "render-renderer.h" + +#include +#include +#include +#include +#include +#include +#include + + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ + +NewRenderer* NewRenderer::New( NodeDataProvider& nodeDataProvider, + const GeometryDataProvider* geometryDataProvider, + const MaterialDataProvider* materialDataProvider) +{ + return new NewRenderer(nodeDataProvider, geometryDataProvider, materialDataProvider); +} + + +NewRenderer::NewRenderer( NodeDataProvider& nodeDataProvider, + const GeometryDataProvider* geometryDataProvider, + const MaterialDataProvider* materialDataProvider) +: Renderer( nodeDataProvider ), + //mShaderDataProvider( shaderDataProvider ), //@todo Add in after merge with parent class + mMaterialDataProvider( materialDataProvider ), + mGeometryDataProvider( geometryDataProvider ) +{ +} + +NewRenderer::~NewRenderer() +{ +} + +// @todo MESH_REWORK Should we consider changing the providers, or should we instead +// create a new renderer when these change? +void NewRenderer::SetGeometryDataProvider( const GeometryDataProvider* geometryDataProvider ) +{ + mGeometryDataProvider = geometryDataProvider; +} + +void NewRenderer::SetMaterialDataProvider( const MaterialDataProvider* materialDataProvider ) +{ + mMaterialDataProvider = materialDataProvider; +} + + +// Note - this is currently called from UpdateThread, PrepareRenderInstructions, +// as an optimisation. +// @todo MESH_REWORK Should use Update thread objects only in PrepareRenderInstructions. +bool NewRenderer::RequiresDepthTest() const +{ + return true; +} + +bool NewRenderer::CheckResources() +{ + // Query material to check it has texture pointers & image has size + // Query geometry to check it has vertex buffers + + // General point though - why would we have a render item in RenderThread with no ready + // resources in UpdateThread? + return true; +} + +void NewRenderer::ResolveGeometryTypes( BufferIndex bufferIndex, GeometryType& outType, ShaderSubTypes& outSubType ) +{ + // @todo MESH_REWORK Remove after merge + + // Do nothing +} + +bool NewRenderer::IsOutsideClipSpace( const Matrix& modelMatrix, const Matrix& modelViewProjectionMatrix ) +{ + // @todo MESH_REWORK Add clipping + return false; +} + +void NewRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix ) +{ + BindTextures( bufferIndex, program, mMaterialDataProvider->GetSamplers() ); + + SetUniforms( program ); + + mRenderGeometry.UploadAndDraw( mContext, program, bufferIndex, *mGeometryDataProvider ); +} + +void NewRenderer::GlContextDestroyed() +{ + mRenderGeometry.GlContextDestroyed(); +} + +void NewRenderer::GlCleanup() +{ +} + +void NewRenderer::SetUniforms( Program& program ) +{ + // @todo MESH_REWORK Implement uniform map +} + +void NewRenderer::BindTextures( + BufferIndex bufferIndex, + Program& program, + const MaterialDataProvider::Samplers& samplers ) +{ + // @todo MESH_REWORK Write a cache of texture units to commonly used sampler textures + unsigned int textureUnit = 0; + + for( MaterialDataProvider::Samplers::Iterator iter = samplers.Begin(); + iter != samplers.End(); + ++iter ) + { + const SamplerDataProvider* sampler = *iter; + ResourceId textureId = sampler->GetTextureId(bufferIndex); + Texture* texture = mTextureCache->GetTexture( textureId ); + if( texture != NULL ) + { + unsigned int textureUnitUniformIndex = GetTextureUnitUniformIndex( program, *sampler ); + TextureUnit theTextureUnit = static_cast(textureUnit); + BindTexture( program, textureId, texture, theTextureUnit, textureUnitUniformIndex ); + ApplySampler( bufferIndex, texture, theTextureUnit, *sampler ); + } + + ++textureUnit; + } +} + +void NewRenderer::BindTexture( + Program& program, + ResourceId id, + Texture* texture, + TextureUnit textureUnit, + unsigned int textureUnitUniformIndex ) +{ + DALI_ASSERT_DEBUG( NULL != mTextureCache ); + + if( texture != NULL ) + { + mTextureCache->BindTexture( texture, id, GL_TEXTURE_2D, textureUnit ); + + // Set sampler uniform location for the texture + GLint textureUnitLoc = program.GetUniformLocation( textureUnitUniformIndex ); + if( Program::UNIFORM_UNKNOWN != textureUnitLoc ) + { + program.SetUniform1i( textureUnitLoc, textureUnit ); + } + } +} + +void NewRenderer::ApplySampler( + BufferIndex bufferIndex, + Texture* texture, + TextureUnit textureUnit, + const SamplerDataProvider& sampler ) +{ + unsigned int samplerBitfield = ImageSampler::PackBitfield( + static_cast< FilterMode::Type >(sampler.GetMinifyFilterMode(bufferIndex)), + static_cast< FilterMode::Type >(sampler.GetMagnifyFilterMode(bufferIndex)) ); + + texture->ApplySampler( textureUnit, samplerBitfield ); + + // @todo MESH_REWORK add support for wrap modes +} + +unsigned int NewRenderer::GetTextureUnitUniformIndex( + Program& program, + const SamplerDataProvider& sampler ) +{ + // Find sampler in mSamplerNameCache + // If it doesn't exist, + // get the index by calling program.RegisterUniform and store it + // If it exists, it's index should be set. + // @todo Cache should be reset on scene change + + unsigned int uniformIndex = 0; + bool found = false; + + for( unsigned int i=0; i< mTextureUnitUniforms.Count(); ++i ) + { + if( mTextureUnitUniforms[i].sampler == &sampler ) + { + uniformIndex = mTextureUnitUniforms[i].index; + found = true; + } + } + + if( ! found ) + { + TextureUnitUniformIndex textureUnitUniformIndex; + textureUnitUniformIndex.sampler = &sampler; + textureUnitUniformIndex.index = program.RegisterUniform( sampler.GetUnitName() ); + mTextureUnitUniforms.PushBack( textureUnitUniformIndex ); + uniformIndex = textureUnitUniformIndex.index; + } + + return uniformIndex; +} + + +} // SceneGraph +} // Internal +} // Dali diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h new file mode 100644 index 0000000..59b1f10 --- /dev/null +++ b/dali/internal/render/renderers/render-renderer.h @@ -0,0 +1,205 @@ +#ifndef __DALI_INTERNAL_SCENE_GRAPH_NEW_RENDERER_H__ +#define __DALI_INTERNAL_SCENE_GRAPH_NEW_RENDERER_H__ + +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include // For resource id +#include +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ +class NodeDataProvider; +class ShaderDataProvider; +class SamplerDataProvider; +class MaterialDataProvider; +class GeometryDataProvider; +class RenderGeometry; + +/** + * The new geometry renderer. + * + * @todo MESH_REWORK It will be merged into the base class eventually + */ +class NewRenderer : public Renderer +{ +public: + typedef Integration::ResourceId ResourceId; + + /** + * Create a new renderer instance + * @param[in] nodeDataProvider The node data provider + * @param[in] geoemtryDataProvider The geometry data provider + * @param[in] materialDataProvider The material data provider + */ + static NewRenderer* New( NodeDataProvider& nodeDataProvider, + const GeometryDataProvider* geometryDataProvider, + const MaterialDataProvider* materialDataProvider ); + /** + * Constructor. + * @param[in] nodeDataProvider The node data provider + * @param[in] geoemtryDataProvider The geometry data provider + * @param[in] materialDataProvider The material data provider + */ + NewRenderer( NodeDataProvider& nodeDataProvider, + const GeometryDataProvider* geometryDataProvider, + const MaterialDataProvider* materialDataProvider ); + + virtual ~NewRenderer(); + + /** + * Change the geometry data provider of the renderer + * @param[in] geoemtryDataProvider The geometry data provider + */ + void SetGeometryDataProvider( const GeometryDataProvider* geometryDataProvider ); + + /** + * Change the material data provider of the renderer + * @param[in] materialDataProvider The material data provider + */ + void SetMaterialDataProvider( const MaterialDataProvider* materialDataProvider ); + +public: // Implementation of Renderer + /** + * @copydoc SceneGraph::Renderer::RequiresDepthTest() + */ + virtual bool RequiresDepthTest() const; + + /** + * @copydoc SceneGraph::Renderer::CheckResources() + */ + virtual bool CheckResources(); + + /** + * @copydoc SceneGraph::Renderer::ResolveGeometryTypes() + */ + virtual void ResolveGeometryTypes( BufferIndex bufferIndex, + GeometryType& outType, + ShaderSubTypes& outSubType ); + + /** + * @copydoc SceneGraph::Renderer::IsOutsideClipSpace() + */ + virtual bool IsOutsideClipSpace( const Matrix& modelMatrix, + const Matrix& modelViewProjectionMatrix ); + + /** + * @copydoc SceneGraph::Renderer::DoRender() + */ + virtual void DoRender( BufferIndex bufferIndex, + Program& program, + const Matrix& modelViewMatrix, + const Matrix& viewMatrix ); + +public: // Implementation of GlResourceOwner + + /** + * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed() + */ + virtual void GlContextDestroyed(); + + /** + * @copydoc Dali::Internal::GlResourceOwner::GlCleanup() + */ + virtual void GlCleanup(); + +private: + /** + * Set the uniforms from properties according to the uniform map + * @param[in] program The shader program on which to set the uniforms. + */ + void SetUniforms( Program& program ); + + /** + * Bind the material textures in the samplers and setup the samplers + * @param[in] bufferIndex The buffer index + * @param[in] program The shader program + * @param[in] samplers The samplers to bind + */ + void BindTextures( BufferIndex bufferIndex, + Program& program, + const MaterialDataProvider::Samplers& samplers ); + + /** + * Bind a material texture to a texture unit, and set the sampler's texture uniform + * to that texture unit. + * @param[in] program The shader program + * @param[in] id The resource id of the texture to bind + * @param[in] texture The texture to bind + * @param[in] textureUnit The texture unit index to use + * @param[in] nameIndex The index of the texture uniform in the program + */ + void BindTexture( Program& program, + ResourceId id, + Texture* texture, + TextureUnit textureUnit, + unsigned int nameIndex ); + + /** + * Apply the sampler modes to the texture. + * @param[in] bufferIndex The current buffer index + * @param[in] texture The texture to which to apply the sampler modes + * @param[in] textureUnit The texture unit of the texture + * @param[in] sampler The sampler from which to get the modes. + */ + void ApplySampler( BufferIndex bufferIndex, + Texture* texture, + TextureUnit textureUnit, + const SamplerDataProvider& sampler ); + + /** + * Get the texture uniform index of the name sampler in the program. + * If not already registered in the program, then this performs the registration + * @param[in] program The shader program + * @param[in] sampler The sampler holding a texture unit uniform name to search for + * @return The texture uniform index in the program + */ + unsigned int GetTextureUnitUniformIndex( Program& program, + const SamplerDataProvider& sampler ); + + +private: + //const NodeDataProvider& mNodeDataProvider; + //const ShaderDataProvider& mShaderDataProvider; + const MaterialDataProvider* mMaterialDataProvider; + const GeometryDataProvider* mGeometryDataProvider; + + RenderGeometry mRenderGeometry; + + struct TextureUnitUniformIndex + { + const SamplerDataProvider* sampler; + unsigned int index; + }; + + typedef Dali::Vector< TextureUnitUniformIndex > TextureUnitUniforms; + TextureUnitUniforms mTextureUnitUniforms; +}; + + +} // SceneGraph +} // Internal +} // Dali + +#endif // __DALI_INTERNAL_SCENE_GRAPH_NEW_RENDERER_H__ diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.cpp b/dali/internal/render/renderers/scene-graph-image-renderer.cpp index ad9b96b..18b3775 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-image-renderer.cpp @@ -114,9 +114,9 @@ namespace Internal namespace SceneGraph { -ImageRenderer* ImageRenderer::New( RenderDataProvider& dataprovider ) +ImageRenderer* ImageRenderer::New( NodeDataProvider& dataProvider ) { - return new ImageRenderer( dataprovider ); + return new ImageRenderer( dataProvider ); } ImageRenderer::~ImageRenderer() @@ -925,8 +925,8 @@ void ImageRenderer::GenerateMeshIndices(GLushort* indices, int rectanglesX, int } } -ImageRenderer::ImageRenderer( RenderDataProvider& dataprovider ) -: Renderer( dataprovider ), +ImageRenderer::ImageRenderer( NodeDataProvider& dataProvider ) +: Renderer( dataProvider ), mTexture( NULL ), mBorder( 0.45, 0.45, 0.1, 0.1 ), mPixelArea(), diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.h b/dali/internal/render/renderers/scene-graph-image-renderer.h index f6d3108..ee8c20f 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.h +++ b/dali/internal/render/renderers/scene-graph-image-renderer.h @@ -35,7 +35,7 @@ class GpuBuffer; namespace SceneGraph { -class RenderDataProvider; +class NodeDataProvider; /** * Used to render an image. @@ -61,7 +61,7 @@ public: * @param dataprovider to render * @return The newly allocated ImageRenderer. */ - static ImageRenderer* New( RenderDataProvider& dataprovider ); + static ImageRenderer* New( NodeDataProvider& dataprovider ); /** * Virtual destructor @@ -199,13 +199,13 @@ private: /** * Private constructor. @see New() */ - ImageRenderer(RenderDataProvider& dataprovider); + ImageRenderer( NodeDataProvider& dataprovider ); // Undefined - ImageRenderer(const ImageRenderer&); + ImageRenderer( const ImageRenderer& ); // Undefined - ImageRenderer& operator=(const ImageRenderer& rhs); + ImageRenderer& operator=( const ImageRenderer& rhs ); private: diff --git a/dali/internal/render/renderers/scene-graph-renderer-debug.cpp b/dali/internal/render/renderers/scene-graph-renderer-debug.cpp index 85d667f..2059fd4 100644 --- a/dali/internal/render/renderers/scene-graph-renderer-debug.cpp +++ b/dali/internal/render/renderers/scene-graph-renderer-debug.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include namespace Dali diff --git a/dali/internal/render/renderers/scene-graph-renderer-debug.h b/dali/internal/render/renderers/scene-graph-renderer-debug.h index 9f91c14..e174c48 100644 --- a/dali/internal/render/renderers/scene-graph-renderer-debug.h +++ b/dali/internal/render/renderers/scene-graph-renderer-debug.h @@ -31,7 +31,7 @@ class Context; namespace SceneGraph { -class RenderDataProvider; +class NodeDataProvider; void DebugBoundingBox(Context& context, Rect boundingBox, const Matrix& mvp); diff --git a/dali/internal/render/renderers/scene-graph-renderer.cpp b/dali/internal/render/renderers/scene-graph-renderer.cpp index 6e05c9d..a74bdde 100644 --- a/dali/internal/render/renderers/scene-graph-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-renderer.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -252,7 +252,7 @@ void Renderer::Render( BufferIndex bufferIndex, DoRender( bufferIndex, *program, modelViewMatrix, viewMatrix ); } -Renderer::Renderer( RenderDataProvider& dataprovider ) +Renderer::Renderer( NodeDataProvider& dataprovider ) : mDataProvider( dataprovider ), mContext( NULL ), diff --git a/dali/internal/render/renderers/scene-graph-renderer.h b/dali/internal/render/renderers/scene-graph-renderer.h index 0c92d21..843c56b 100644 --- a/dali/internal/render/renderers/scene-graph-renderer.h +++ b/dali/internal/render/renderers/scene-graph-renderer.h @@ -42,7 +42,7 @@ namespace SceneGraph class SceneController; class Shader; class TextureCache; -class RenderDataProvider; +class NodeDataProvider; /** * Renderers are used to render images, text, & meshes etc. @@ -127,12 +127,11 @@ public: bool cull ); protected: - /** * Protected constructor; only derived classes can be instantiated. * @param dataprovider for rendering */ - Renderer( RenderDataProvider& dataprovider ); + Renderer( NodeDataProvider& dataprovider ); private: @@ -150,6 +149,9 @@ private: virtual bool CheckResources() = 0; /** + * @deprecated - Not needed in final MESH_REWORK + * @todo MESH_REWORK Remove this API + * * Resolve the derived renderers geometry type and subtype * @param[in] bufferIndex The index of the previous update buffer. * @param[out] outType The geometry type @@ -176,7 +178,7 @@ private: protected: - RenderDataProvider& mDataProvider; + NodeDataProvider& mDataProvider; Context* mContext; TextureCache* mTextureCache; Shader* mShader; diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.cpp b/dali/internal/render/renderers/scene-graph-text-renderer.cpp index 1dc0484..11ddafc 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-text-renderer.cpp @@ -52,7 +52,7 @@ namespace Internal namespace SceneGraph { -TextRenderer* TextRenderer::New( RenderDataProvider& dataprovider ) +TextRenderer* TextRenderer::New( NodeDataProvider& dataprovider ) { return new TextRenderer( dataprovider ); } @@ -523,7 +523,7 @@ void TextRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Ma } -TextRenderer::TextRenderer( RenderDataProvider& dataprovider ) +TextRenderer::TextRenderer( NodeDataProvider& dataprovider ) : Renderer( dataprovider ), mTexture( NULL ), mTextColor( NULL ), diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.h b/dali/internal/render/renderers/scene-graph-text-renderer.h index fdb18ad..8bb1e22 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.h +++ b/dali/internal/render/renderers/scene-graph-text-renderer.h @@ -39,7 +39,6 @@ class TextParameters; namespace SceneGraph { -class RenderDataProvider; class TextureCache; /** @@ -54,7 +53,7 @@ public: * @param dataprovider to render * @return The newly allocated TextRenderer */ - static TextRenderer* New( RenderDataProvider& dataprovider ); + static TextRenderer* New( NodeDataProvider& dataprovider ); /** * Virtual destructor @@ -168,7 +167,7 @@ private: /** * Private constructor. @see New() */ - TextRenderer( RenderDataProvider& dataprovider ); + TextRenderer( NodeDataProvider& dataprovider ); // Undefined TextRenderer( const TextRenderer& copy ); diff --git a/dali/internal/render/shaders/program.cpp b/dali/internal/render/shaders/program.cpp index 3a47253..73b2ef5 100644 --- a/dali/internal/render/shaders/program.cpp +++ b/dali/internal/render/shaders/program.cpp @@ -168,16 +168,46 @@ GLint Program::GetAttribLocation( AttribType type ) { DALI_ASSERT_DEBUG(type != ATTRIB_UNKNOWN); - if( mAttribLocations[ type ] == ATTRIB_UNKNOWN ) + return GetCustomAttributeLocation( type ); +} + +unsigned int Program::RegisterCustomAttribute( const std::string& name ) +{ + unsigned int index = 0; + // find the value from cache + for( ;index < mAttributeLocations.size(); ++index ) { - GLint loc = CHECK_GL( mGlAbstraction, mGlAbstraction.GetAttribLocation( mProgramId, gStdAttribs[type] ) ); - mAttribLocations[ type ] = loc; - LOG_GL( "GetAttribLocation(program=%d,%s) = %d\n", mProgramId, gStdAttribs[type], mAttribLocations[type] ); + if( mAttributeLocations[ index ].first == name ) + { + // name found so return index + return index; + } } + // if we get here, index is one past end so push back the new name + mAttributeLocations.push_back( std::make_pair( name, ATTRIB_UNKNOWN ) ); + return index; +} - return mAttribLocations[type]; +GLint Program::GetCustomAttributeLocation( unsigned int attributeIndex ) +{ + // debug check that index is within name cache + DALI_ASSERT_DEBUG( mAttributeLocations.size() > attributeIndex ); + + // check if we have already queried the location of the attribute + GLint location = mAttributeLocations[ attributeIndex ].second; + + if( location == ATTRIB_UNKNOWN ) + { + location = CHECK_GL( mGlAbstraction, mGlAbstraction.GetAttribLocation( mProgramId, mAttributeLocations[ attributeIndex ].first.c_str() ) ); + + mAttributeLocations[ attributeIndex ].second = location; + LOG_GL( "GetAttributeLocation(program=%d,%s) = %d\n", mProgramId, mAttributeLocations[ attributeIndex ].first.c_str(), mAttributeLocations[ attributeIndex ].second ); + } + + return location; } + unsigned int Program::RegisterUniform( const std::string& name ) { unsigned int index = 0; @@ -442,6 +472,13 @@ Program::Program( ProgramCache& cache, Integration::ShaderDataPtr shaderData, bo mProgramData(shaderData), mModifiesGeometry( modifiesGeometry ) { + // reserve space for standard attributes + mAttributeLocations.reserve( ATTRIB_TYPE_LAST ); + for( int i=0; i > mAttributeLocations; ///< attribute location cache std::vector< std::pair< std::string, GLint > > mUniformLocations; ///< uniform location cache // uniform value caching diff --git a/dali/internal/update/common/property-boolean.h b/dali/internal/update/common/property-boolean.h index 2181466..b166e83 100644 --- a/dali/internal/update/common/property-boolean.h +++ b/dali/internal/update/common/property-boolean.h @@ -20,7 +20,6 @@ // INTERNAL INCLUDES #include -#include #include #include #include @@ -117,10 +116,10 @@ private: PropertyBoolean& operator=(const PropertyBoolean& rhs); public: - boolean mValue; ///< The property value + bool mValue; ///< The property value private: - boolean mDirtyFlag; + bool mDirtyFlag; }; } // namespace SceneGraph diff --git a/dali/internal/update/common/scene-graph-property-buffer.cpp b/dali/internal/update/common/scene-graph-property-buffer.cpp index dcdf83a..ab81fbe 100644 --- a/dali/internal/update/common/scene-graph-property-buffer.cpp +++ b/dali/internal/update/common/scene-graph-property-buffer.cpp @@ -35,8 +35,8 @@ PropertyBuffer::~PropertyBuffer() PropertyBuffer* PropertyBuffer::NewQuadVertices() { PropertyBuffer* propertyBuffer = new PropertyBuffer(); - propertyBuffer->mVertexSize = sizeof(Vector4); - propertyBuffer->mData.Resize( propertyBuffer->mVertexSize * 4 ); + propertyBuffer->mElementSize = sizeof(Vector4); + propertyBuffer->mData.Resize( propertyBuffer->mElementSize * 4 ); Vector4* vertices = reinterpret_cast(propertyBuffer->mData[0]); vertices[ 0 ] = Vector4( -0.5f, -0.5f, 1.0f, 0.0f ); @@ -52,8 +52,8 @@ PropertyBuffer* PropertyBuffer::NewQuadIndices() { PropertyBuffer* propertyBuffer = new PropertyBuffer(); - propertyBuffer->mVertexSize = sizeof( unsigned short ); - propertyBuffer->mData.Resize( propertyBuffer->mVertexSize * 6 ); + propertyBuffer->mElementSize = sizeof( unsigned short ); + propertyBuffer->mData.Resize( propertyBuffer->mElementSize * 6 ); unsigned short* indices = reinterpret_cast(propertyBuffer->mData[0]); indices[0] = 0; indices[1] = 3; indices[2] = 1; @@ -62,6 +62,25 @@ PropertyBuffer* PropertyBuffer::NewQuadIndices() return propertyBuffer; } +std::size_t PropertyBuffer::GetDataSize( BufferIndex bufferIndex ) const +{ + // @todo MESH_REWORK mData should be double buffered + return mData.Count(); +} + +std::size_t PropertyBuffer::GetElementSize( BufferIndex bufferIndex ) const +{ + // @todo MESH_REWORK mElementSize should be double buffered + return mElementSize; +} + +const void* PropertyBuffer::GetData( BufferIndex bufferIndex ) const +{ + // @todo MESH_REWORK mData should be double buffered + return reinterpret_cast< const void* >(mData[0]); +} + + } // namespace SceneGraph } // namespace Internal } // namespace Dali diff --git a/dali/internal/update/common/scene-graph-property-buffer.h b/dali/internal/update/common/scene-graph-property-buffer.h index b930f2f..ddbe558 100644 --- a/dali/internal/update/common/scene-graph-property-buffer.h +++ b/dali/internal/update/common/scene-graph-property-buffer.h @@ -18,7 +18,7 @@ */ #include -#include +#include namespace Dali { @@ -46,12 +46,30 @@ public: */ ~PropertyBuffer(); + /** + * Get the size of the property buffer in bytes + * @return the size in bytes + */ + std::size_t GetDataSize( BufferIndex bufferIndex ) const; + + /** + * Get the size of an element of the buffer in bytes + * @return the element size in bytes + */ + std::size_t GetElementSize( BufferIndex bufferIndex ) const; + + /** + * Get the property buffer data + * @return the property buffer's data array + */ + const void* GetData( BufferIndex bufferIndex ) const; + private: // @todo MESH_REWORK - TEMPORARY TYPES - REMOVE WHEN WE HAVE WORKING BUFFERS typedef Dali::Vector< char > CharBuffer; CharBuffer mData; - std::size_t mVertexSize; + std::size_t mElementSize; }; } // namespace SceneGraph diff --git a/dali/internal/update/effects/scene-graph-material.cpp b/dali/internal/update/effects/scene-graph-material.cpp index 146e20e..bf91dd6 100644 --- a/dali/internal/update/effects/scene-graph-material.cpp +++ b/dali/internal/update/effects/scene-graph-material.cpp @@ -18,7 +18,8 @@ #include "scene-graph-material.h" // INTERNAL HEADERS -#include +#include +#include namespace Dali { @@ -28,7 +29,8 @@ namespace SceneGraph { Material::Material() -: mShader(NULL) +: mShader(NULL), + mColor( Color::WHITE ) { } @@ -38,6 +40,7 @@ Material::~Material() void Material::SetShader( Shader* shader ) { + mShader = shader; } Shader* Material::GetShader() @@ -47,22 +50,30 @@ Shader* Material::GetShader() void Material::AddSampler( const Sampler* sampler ) { - // @todo MESH_REWORK + const SamplerDataProvider* sdp = static_cast< const SamplerDataProvider*>( sampler ); + mSamplers.PushBack( sdp ); } void Material::RemoveSampler( const Sampler* sampler ) { - // @todo MESH_REWORK + const SamplerDataProvider* samplerDataProvider = sampler; + + for( Samplers::Iterator iter = mSamplers.Begin(); iter != mSamplers.End(); ++iter ) + { + if( *iter == samplerDataProvider ) + { + mSamplers.Erase(iter); + return; + } + } + DALI_ASSERT_DEBUG( 0 && "Sampler not found" ); } const Material::Samplers& Material::GetSamplers() const { - // @todo MESH_REWORK return mSamplers; } - - } // namespace SceneGraph } // namespace Internal } // namespace Dali diff --git a/dali/internal/update/effects/scene-graph-material.h b/dali/internal/update/effects/scene-graph-material.h index fa5cce7..17f1d82 100644 --- a/dali/internal/update/effects/scene-graph-material.h +++ b/dali/internal/update/effects/scene-graph-material.h @@ -21,9 +21,10 @@ #include #include #include +#include #include #include -#include +#include namespace Dali { @@ -37,7 +38,6 @@ class Shader; class Material : public PropertyOwner, public MaterialDataProvider { public: - typedef Dali::Vector< Sampler* > Samplers; /** * Constructor @@ -77,11 +77,13 @@ public: * Get the samplers this material uses. * @return the samplers */ - const Samplers& GetSamplers() const; + virtual const Samplers& GetSamplers() const; private: Shader* mShader; - Samplers mSamplers; // Not owned (though who does?) + Samplers mSamplers; // Not owned ( @todo MESH_REWORK though who does?) + + AnimatableProperty mColor; // @todo MESH_REWORK add property values for cull face mode, blending options, blend color // Add getters/setters? diff --git a/dali/internal/update/effects/scene-graph-sampler.cpp b/dali/internal/update/effects/scene-graph-sampler.cpp index 4014226..594b6e1 100644 --- a/dali/internal/update/effects/scene-graph-sampler.cpp +++ b/dali/internal/update/effects/scene-graph-sampler.cpp @@ -27,27 +27,30 @@ namespace Internal namespace SceneGraph { -Sampler::Sampler( const std::string& samplerName ) -: mUniformName( samplerName ), - mTextureId( 0 ), +Sampler::Sampler( const std::string& unitName ) +: mUnitName( unitName ), mMinFilter( Dali::Sampler::DEFAULT ), mMagFilter( Dali::Sampler::DEFAULT ), mUWrapMode( Dali::Sampler::CLAMP_TO_EDGE ), mVWrapMode( Dali::Sampler::CLAMP_TO_EDGE ) { + mTextureId[0] = 0; + mTextureId[1] = 0; } Sampler::~Sampler() { } -void Sampler::SetUniformName( const std::string& samplerName ) +void Sampler::SetUnitName( const std::string& unitName ) { + mUnitName = unitName; } -void Sampler::SetTextureId( ResourceId textureId ) +void Sampler::SetTexture( BufferIndex bufferIndex, Integration::ResourceId textureId, const BitmapMetadata& metadata ) { - mTextureId = textureId; + mTextureId[bufferIndex] = textureId; + mBitmapMetadata[bufferIndex] = metadata; } void Sampler::SetFilterMode( BufferIndex bufferIndex, FilterMode minFilter, FilterMode magFilter ) @@ -60,45 +63,44 @@ void Sampler::SetWrapMode( BufferIndex bufferIndex, WrapMode uWrap, WrapMode vWr { } -const std::string& Sampler::GetUniformName() +const std::string& Sampler::GetUnitName() { - // @todo MESH_REWORK - return mUniformName; + return mUnitName; } -Integration::ResourceId Sampler::GetTextureId() +Integration::ResourceId Sampler::GetTextureId( BufferIndex bufferIndex ) const { - // @todo MESH_REWORK - return mTextureId; + return mTextureId[bufferIndex]; } -Sampler::FilterMode Sampler::GetMinifyFilterMode( BufferIndex bufferIndex ) +Sampler::FilterMode Sampler::GetMinifyFilterMode( BufferIndex bufferIndex ) const { - // @todo MESH_REWORK return mMinFilter[bufferIndex]; } -Sampler::FilterMode Sampler::GetMagnifyFilterMode( BufferIndex bufferIndex ) +Sampler::FilterMode Sampler::GetMagnifyFilterMode( BufferIndex bufferIndex ) const { - // @todo MESH_REWORK return mMagFilter[bufferIndex]; } -Sampler::WrapMode Sampler::GetUWrapMode( BufferIndex bufferIndex ) +Sampler::WrapMode Sampler::GetUWrapMode( BufferIndex bufferIndex ) const { - // @todo MESH_REWORK return mUWrapMode[bufferIndex]; } -Sampler::WrapMode Sampler::GetVWrapMode( BufferIndex bufferIndex ) +Sampler::WrapMode Sampler::GetVWrapMode( BufferIndex bufferIndex ) const { - // @todo MESH_REWORK return mVWrapMode[bufferIndex]; } -bool Sampler::IsFullyOpaque() +bool Sampler::AffectsTransparency( BufferIndex bufferIndex ) const { - return true; // @todo MESH_REWORK - check the actual image. For the moment, pretend it's opaque + return mAffectsTransparency[bufferIndex] ; +} + +bool Sampler::IsFullyOpaque( BufferIndex bufferIndex ) const +{ + return mBitmapMetadata[bufferIndex].IsFullyOpaque(); } } // namespace SceneGraph diff --git a/dali/internal/update/effects/scene-graph-sampler.h b/dali/internal/update/effects/scene-graph-sampler.h index 950b5f9..9f80850 100644 --- a/dali/internal/update/effects/scene-graph-sampler.h +++ b/dali/internal/update/effects/scene-graph-sampler.h @@ -18,10 +18,12 @@ */ #include +#include #include #include #include -#include +#include +#include #include @@ -52,13 +54,16 @@ public: * Set the uniform name of this sampler. This allows the shader to find the * GL index of this sampler. */ - void SetUniformName( const std::string& samplerName ); + void SetUnitName( const std::string& unitName ); /** - * Set the texture identity of this sampler + * Set the texture identity of this sampler (needs to double buffer this value because + * it can be read through the data provider interface in the render thread ) + * @param[in] bufferIndex The buffer index to use * @param[in] textureId The identity of the texture + * @param[in] bitmapMetadata The metadata for the texture */ - void SetTextureId( ResourceId textureId ); + void SetTexture( BufferIndex bufferIndex, Integration::ResourceId textureId, const BitmapMetadata& bitmapMetadata ); /** * Set the filter modes for minify and magnify filters @@ -73,60 +78,82 @@ public: */ void SetWrapMode( BufferIndex bufferIndex, WrapMode uWrap, WrapMode vWrap ); -public: // SamplerDataProvider interface /** - * + * @param[in] bufferIndex The buffer index to use + * @return true if this sampler affects transparency of the material + * @note this should only be called from Update thread + */ + bool AffectsTransparency( BufferIndex bufferIndex ) const; + + /** + * @param[in] bufferIndex The buffer index to use + * @return true if the texture is fully opaque + * @note this should only be called from Update thread + */ + bool IsFullyOpaque( BufferIndex bufferIndex ) const; + + +public: // SamplerDataProvider interface - called from RenderThread + /** + * Get the texture unit uniform name + * @return the name of the texture unit uniform */ - const std::string& GetUniformName(); + virtual const std::string& GetUnitName(); /** * Get the texture ID + * @param[in] bufferIndex The buffer index to use * @return the identity of the associated texture */ - virtual ResourceId GetTextureId(); + virtual Integration::ResourceId GetTextureId(BufferIndex buffer) const; /** * Get the filter mode * @param[in] bufferIndex The buffer index to use * @return The minify filter mode */ - virtual FilterMode GetMinifyFilterMode( BufferIndex bufferIndex ); + virtual FilterMode GetMinifyFilterMode( BufferIndex bufferIndex ) const; /** * Get the filter mode * @param[in] bufferIndex The buffer index to use * @return The magnify filter mode */ - virtual FilterMode GetMagnifyFilterMode( BufferIndex bufferIndex ); + virtual FilterMode GetMagnifyFilterMode( BufferIndex bufferIndex ) const; /** * Get the horizontal wrap mode * @param[in] bufferIndex The buffer index to use * @return The horizontal wrap mode */ - virtual WrapMode GetUWrapMode( BufferIndex bufferIndex ); + virtual WrapMode GetUWrapMode( BufferIndex bufferIndex ) const; /** * Get the vertical wrap mode * @param[in] bufferIndex The buffer index to use * @return The vertical wrap mode */ - virtual WrapMode GetVWrapMode( BufferIndex bufferIndex ); - - /** - * @return true if the texture is fully opaque. - * @todo MESH_REWORK Requires access to ResourceManager::GetBitmapMetadata() - */ - bool IsFullyOpaque(); + virtual WrapMode GetVWrapMode( BufferIndex bufferIndex ) const; private: - std::string mUniformName; ///< The name of the uniform referencing this sampler - ResourceId mTextureId; ///< The identity of the associated texture + std::string mUnitName; ///< The name of the uniform of the texture unit + // @todo MESH_REWORK Need these to automatically copy + // new value into old value on frame change + + ResourceId mTextureId[2]; ///< The identity of the associated texture for this frame (Can be read from RenderThread) + + BitmapMetadata mBitmapMetadata[2]; /// The meta data of the associated texture for this frame (Not needed in RenderThread) + + // @todo MESH_REWORK These need to be non-animatable properties (that also copy + // new values into old on frame change ) that can be read in RenderThread DoubleBuffered mMinFilter; ///< The minify filter DoubleBuffered mMagFilter; ///< The magnify filter DoubleBuffered mUWrapMode; ///< The horizontal wrap mode DoubleBuffered mVWrapMode; ///< The vertical wrap mode + + // Note, this is only called from UpdateThread + DoubleBuffered mAffectsTransparency; ///< If this sampler affects renderer transparency }; inline void SetUniformNameMessage( EventToUpdate& eventToUpdate, const Sampler& sampler, const std::string& name ) @@ -137,7 +164,7 @@ inline void SetUniformNameMessage( EventToUpdate& eventToUpdate, const Sampler& unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) ); // Construct message in the message queue memory; note that delete should not be called on the return value - new (slot) LocalType( &sampler, &Sampler::SetUniformName, name ); + new (slot) LocalType( &sampler, &Sampler::SetUnitName, name ); } } // namespace SceneGraph diff --git a/dali/internal/update/geometry/scene-graph-geometry.cpp b/dali/internal/update/geometry/scene-graph-geometry.cpp index 8ae76a6..16492a7 100644 --- a/dali/internal/update/geometry/scene-graph-geometry.cpp +++ b/dali/internal/update/geometry/scene-graph-geometry.cpp @@ -76,24 +76,30 @@ void Geometry::ClearIndexBuffer() mIndexBuffer.Reset(); } -void Geometry::SetGeometryType( Geometry::GeometryType geometryType ) +void Geometry::SetGeometryType( BufferIndex bufferIndex, Geometry::GeometryType geometryType ) { - mGeometryType = geometryType; + mGeometryType[bufferIndex] = geometryType; } -const Geometry::VertexBuffers& Geometry::GetVertexBuffers() +const GeometryDataProvider::VertexBuffers& Geometry::GetVertexBuffers() const { return mVertexBuffers; } -const PropertyBuffer& Geometry::GetIndexBuffer() +const PropertyBuffer* Geometry::GetIndexBuffer() const { - return *mIndexBuffer.Get(); + return mIndexBuffer.Get(); } -Geometry::GeometryType Geometry::GetGeometryType( ) +Geometry::GeometryType Geometry::GetGeometryType( BufferIndex bufferIndex) const { - return mGeometryType; + int geometryType = mGeometryType[ bufferIndex ]; + return static_cast< GeometryDataProvider::GeometryType > ( geometryType ); +} + +bool Geometry::GetRequiresDepthTest( BufferIndex bufferIndex ) const +{ + return mRequiresDepthTest.GetBoolean( bufferIndex ); } } // namespace SceneGraph diff --git a/dali/internal/update/geometry/scene-graph-geometry.h b/dali/internal/update/geometry/scene-graph-geometry.h index 0830833..d0a37ef 100644 --- a/dali/internal/update/geometry/scene-graph-geometry.h +++ b/dali/internal/update/geometry/scene-graph-geometry.h @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include namespace Dali { @@ -35,12 +37,9 @@ namespace SceneGraph * This scene graph object is a property owner. It describes a geometry using a * number of PropertyBuffers acting as Vertex buffers. */ -class Geometry : public PropertyOwner +class Geometry : public PropertyOwner, public GeometryDataProvider { public: - typedef Dali::Geometry::GeometryType GeometryType; - - typedef OwnerContainer< PropertyBuffer* > VertexBuffers; /** * Constructor @@ -79,35 +78,46 @@ public: * Set the type of geometry to draw (Points, Lines, Triangles, etc) * @param[in] geometryType The geometry type */ - void SetGeometryType( GeometryType geometryType ); + void SetGeometryType( BufferIndex bufferIndex, GeometryType geometryType ); public: // GeometryDataProvider /** * Get the vertex buffers of the geometry * @return A const reference to the vertex buffers */ - virtual const VertexBuffers& GetVertexBuffers(); + virtual const GeometryDataProvider::VertexBuffers& GetVertexBuffers() const; /** * Get the index buffer of the geometry - * @return A const reference to the index buffer + * @return A const pointer to the index buffer if it exists, or NULL if it doesn't. */ - virtual const PropertyBuffer& GetIndexBuffer(); + virtual const PropertyBuffer* GetIndexBuffer() const; /** * Get the type of geometry to draw */ - virtual GeometryType GetGeometryType( ); + virtual GeometryType GetGeometryType( BufferIndex bufferIndex ) const; + + /** + * Returns true if this geometry requires depth testing, e.g. if it is + * a set of vertices with z != 0 + */ + virtual bool GetRequiresDepthTest( BufferIndex bufferIndex ) const; private: VertexBuffers mVertexBuffers; ///< The vertex buffers OwnerPointer mIndexBuffer; ///< The index buffer if required private: // Properties - AnimatableProperty mCenter; - AnimatableProperty mHalfExtents; - GeometryType mGeometryType; ///< The type of geometry (tris/lines etc) - AnimatableProperty mRequiresDepthTest; + //DoubleBufferedProperty mCenter; + //DoubleBufferedProperty mHalfExtents; + //DoubleBufferedProperty mGeometryType; ///< The type of geometry (tris/lines etc) + //DoubleBufferedProperty mRequiresDepthTest; + + AnimatableProperty mCenter; + AnimatableProperty mHalfExtents; + AnimatableProperty mGeometryType; ///< The type of geometry (tris/lines etc) + PropertyBoolean mRequiresDepthTest; }; inline void AddVertexBufferMessage( EventToUpdate& eventToUpdate, const Geometry& geometry, PropertyBuffer& vertexBuffer ) @@ -164,7 +174,7 @@ namespace SceneGraph inline void SetGeometryTypeMessage( EventToUpdate& eventToUpdate, const Geometry& geometry, SceneGraph::Geometry::GeometryType geometryType ) { - typedef MessageValue1< Geometry, SceneGraph::Geometry::GeometryType > LocalType; + typedef MessageDoubleBuffered1< Geometry, SceneGraph::Geometry::GeometryType > LocalType; // Reserve some memory inside the message queue unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) ); diff --git a/dali/internal/update/manager/prepare-render-instructions.cpp b/dali/internal/update/manager/prepare-render-instructions.cpp index 70a3584..bc637ed 100644 --- a/dali/internal/update/manager/prepare-render-instructions.cpp +++ b/dali/internal/update/manager/prepare-render-instructions.cpp @@ -49,6 +49,8 @@ namespace SceneGraph */ inline void SetOpaqueRenderFlags( RenderList& renderList, bool transparentRenderersExist, bool stencilRenderablesExist, bool depthTestDisabled ) { + //@todo MESH_REWORK Move RequiresDepthTest from render thread object to update thread object + // Special optimization if depth test is disabled or if only one opaque rendered in the layer (for example background image) // and this renderer does not need depth test against itself (e.g. mesh) // and if this layer has got exactly one opaque renderer diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 3b0f651..8d84728 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -586,6 +586,7 @@ void UpdateManager::RemoveMaterial( Material* material ) // This keeps the material alive, until the render-thread has finished with it mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), materials.Release( iter ) ); + materials.Erase(iter); return; } } diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index d174bdf..53a4cc9 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -31,14 +31,18 @@ #include #include #include -#include -#include #include #include #include #include +//@todo MESH_REWORK Move messages to a separate file to avoid having dependent headers +// pollute core & slow the build down. +#include +#include + + namespace Dali { diff --git a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp index 377a812..1240841 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp @@ -15,6 +15,13 @@ */ #include "scene-graph-renderer-attachment.h" +#include +#include +#include +#include +#include +#include +#include namespace Dali { @@ -23,8 +30,15 @@ namespace Internal namespace SceneGraph { +RendererAttachment* RendererAttachment::New() +{ + return new RendererAttachment(); +} + + RendererAttachment::RendererAttachment() : RenderableAttachment( false ), + mRenderer(NULL), mMaterial(NULL), mGeometry(NULL), mDepthIndex(0) @@ -37,10 +51,16 @@ RendererAttachment::~RendererAttachment() mGeometry=NULL; } -void RendererAttachment::SetMaterial(const Material* material) +void RendererAttachment::SetMaterial( BufferIndex updateBufferIndex, const Material* material) { - // @todo MESH_REWORK mMaterial = material; + + // Tell renderer about a new provider + { + typedef MessageValue1< NewRenderer, const MaterialDataProvider*> DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &NewRenderer::SetMaterialDataProvider, material ); + } } const Material& RendererAttachment::GetMaterial() const @@ -48,10 +68,16 @@ const Material& RendererAttachment::GetMaterial() const return *mMaterial; } -void RendererAttachment::SetGeometry(const Geometry* geometry) +void RendererAttachment::SetGeometry( BufferIndex updateBufferIndex, const Geometry* geometry) { - // @todo MESH_REWORK mGeometry = geometry; + + // Tell renderer about a new provider + { + typedef MessageValue1< NewRenderer, const GeometryDataProvider*> DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &NewRenderer::SetGeometryDataProvider, geometry ); + } } const Geometry& RendererAttachment::GetGeometry() const @@ -70,6 +96,135 @@ int RendererAttachment::GetDepthIndex() const return mDepthIndex; } + +Renderer& RendererAttachment::GetRenderer() +{ + return *mRenderer; +} + +const Renderer& RendererAttachment::GetRenderer() const +{ + return *mRenderer; +} + +void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex ) +{ + // Do nothing +} + +bool RendererAttachment::IsFullyOpaque( BufferIndex updateBufferIndex ) +{ + bool opaque = false; + + if( mParent ) + { + opaque = mParent->GetWorldColor( updateBufferIndex ).a >= FULLY_OPAQUE; + } + + // Require that all affecting samplers are opaque + unsigned int opaqueCount=0; + unsigned int affectingCount=0; + const Material::Samplers& samplers = mMaterial->GetSamplers(); + for( Material::Samplers::ConstIterator iter = samplers.Begin(); + iter != samplers.End(); ++iter ) + { + const Sampler* sampler = static_cast(*iter); + if( sampler->AffectsTransparency( updateBufferIndex ) ) + { + affectingCount++; + if( sampler->IsFullyOpaque( updateBufferIndex ) ) + { + opaqueCount++; + } + } + } + opaque = (opaqueCount == affectingCount); + + return opaque; +} + +void RendererAttachment::SizeChanged( BufferIndex updateBufferIndex ) +{ + // Do nothing. +} + +void RendererAttachment::ConnectToSceneGraph2( BufferIndex updateBufferIndex ) +{ + DALI_ASSERT_DEBUG( mSceneController ); + mRenderer = NewRenderer::New( *mParent, mGeometry, mMaterial ); + mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer ); +} + +void RendererAttachment::OnDestroy2() +{ + DALI_ASSERT_DEBUG( mSceneController ); + mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer ); + mRenderer = NULL; +} + +bool RendererAttachment::DoPrepareResources( + BufferIndex updateBufferIndex, + ResourceManager& resourceManager ) +{ + DALI_ASSERT_DEBUG( mSceneController ); + + CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager(); + + bool ready = false; + mFinishedResourceAcquisition = false; + + if( mGeometry && mMaterial ) + { + unsigned int completeCount = 0; + unsigned int neverCount = 0; + unsigned int frameBufferCount = 0; + + const Material::Samplers& samplers = mMaterial->GetSamplers(); + for( Material::Samplers::ConstIterator iter = samplers.Begin(); + iter != samplers.End(); ++iter ) + { + const Sampler* sampler = static_cast(*iter); + + ResourceId textureId = sampler->GetTextureId( updateBufferIndex ); + switch( completeStatusManager.GetStatus( textureId ) ) + { + case CompleteStatusManager::NOT_READY: + { + ready = false; + BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId ); + if( metaData.GetIsFramebuffer() ) + { + frameBufferCount++; + } + FollowTracker( textureId ); // @todo MESH_REWORK Trackers per sampler rather than per actor? + } + break; + + case CompleteStatusManager::COMPLETE: + { + completeCount++; + } + break; + + case CompleteStatusManager::NEVER: + { + neverCount++; + } + break; + } + } + + // We are ready if all samplers are complete, or those that aren't are framebuffers + // We are complete if all samplers are either complete or will never complete + + ready = ( completeCount + frameBufferCount >= samplers.Count() ) ; + mFinishedResourceAcquisition = ( completeCount + neverCount >= samplers.Count() ); + } + return ready; +} + + + } // namespace SceneGraph } // namespace Internal } // namespace Dali diff --git a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h index b4eda54..43ec50e 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h @@ -19,7 +19,10 @@ #include #include +#include +#include #include +#include namespace Dali { @@ -29,12 +32,19 @@ namespace SceneGraph { class Material; class Geometry; +class NewRenderer; -class RendererAttachment : public RenderableAttachment, public PropertyOwner +class RendererAttachment : public RenderableAttachment, public PropertyOwner, public UniformMapProvider { public: /** + * Create a new renderer attachment. + * @return The newly allocated RendererAttachment + */ + static RendererAttachment* New(); + + /** * Constructor */ RendererAttachment(); @@ -46,9 +56,10 @@ public: /** * Set the material for the renderer + * @param[in] bufferIndex The current frame's buffer index * @param[in] material The material this renderer will use */ - void SetMaterial(const Material* material); + void SetMaterial( BufferIndex bufferIndex, const Material* material); /** * Get the material of this renderer @@ -58,9 +69,10 @@ public: /** * Set the geometry for the renderer + * @param[in] bufferIndex The current frame's buffer index * @param[in] geometry The geometry this renderer will use */ - void SetGeometry(const Geometry* geometry); + void SetGeometry( BufferIndex bufferIndex, const Geometry* geometry); /** * Get the geometry of this renderer @@ -80,9 +92,54 @@ public: */ int GetDepthIndex() const ; +protected: // From RenderableAttachment + /** + * @copydoc RenderableAttachment::GetRenderer(). + */ + virtual Renderer& GetRenderer(); + + /** + * @copydoc RenderableAttachment::GetRenderer(). + */ + virtual const Renderer& GetRenderer() const; + + /** + * @copydoc RenderableAttachment::DoPrepareRender() + */ + virtual void DoPrepareRender( BufferIndex updateBufferIndex ); + + /** + * @copydoc RenderableAttachment::IsFullyOpaque() + */ + virtual bool IsFullyOpaque( BufferIndex updateBufferIndex ); + + /** + * @copydoc RenderableAttachment::SizeChanged() + */ + virtual void SizeChanged( BufferIndex updateBufferIndex ); + + /** + * @copydoc RenderableAttachment::ConnectToSceneGraph2(). + */ + virtual void ConnectToSceneGraph2( BufferIndex updateBufferIndex ); + + /** + * @copydoc RenderableAttachment::OnDestroy2(). + */ + virtual void OnDestroy2(); + + /** + * @copydoc RenderableAttachment::DoPrepareResources() + */ + virtual bool DoPrepareResources( BufferIndex updateBufferIndex, + ResourceManager& resourceManager ); + private: + NewRenderer* mRenderer; ///< Raw pointer to the new renderer (that's owned by RenderManager) + const Material* mMaterial; ///< The material this renderer uses. (Not owned) const Geometry* mGeometry; ///< The geometry this renderer uses. (Not owned) + int mDepthIndex; ///< Used only in PrepareRenderInstructions }; @@ -90,7 +147,7 @@ private: inline void SetMaterialMessage( EventToUpdate& eventToUpdate, const RendererAttachment& attachment, const Material& material ) { - typedef MessageValue1< RendererAttachment, const Material* > LocalType; + typedef MessageDoubleBuffered1< RendererAttachment, const Material* > LocalType; // Reserve some memory inside the message queue unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) ); @@ -101,7 +158,7 @@ inline void SetMaterialMessage( EventToUpdate& eventToUpdate, const RendererAtta inline void SetGeometryMessage( EventToUpdate& eventToUpdate, const RendererAttachment& attachment, const Geometry& geometry ) { - typedef MessageValue1< RendererAttachment, const Geometry* > LocalType; + typedef MessageDoubleBuffered1< RendererAttachment, const Geometry* > LocalType; // Reserve some memory inside the message queue unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) ); diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index b3c6989..6910ece 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -35,7 +35,7 @@ #include #include #include -#include +#include namespace Dali { @@ -85,11 +85,13 @@ static const int RenderableUpdateFlags = TransformFlag | SortModifierFlag | Chil /** * Node is the base class for all nodes in the Scene Graph. - * Each node provides a transformation which applies to the node and its children. - * Node data is double-buffered. This allows an update thread to modify node data, without interferring - * with another thread reading the values from the previous update traversal. + * + * Each node provides a transformation which applies to the node and + * its children. Node data is double-buffered. This allows an update + * thread to modify node data, without interferring with another + * thread reading the values from the previous update traversal. */ -class Node : public PropertyOwner, public RenderDataProvider +class Node : public PropertyOwner, public NodeDataProvider { public: @@ -979,10 +981,10 @@ protected: */ Node(); -private: // from RenderDataProvider +private: // from NodeDataProvider /** - * @copydoc RenderDataProvider::GetModelMatrix + * @copydoc NodeDataProvider::GetModelMatrix */ virtual const Matrix& GetModelMatrix( unsigned int bufferId ) { @@ -990,7 +992,7 @@ private: // from RenderDataProvider } /** - * @copydoc RenderDataProvider::GetRenderColor + * @copydoc NodeDataProvider::GetRenderColor */ virtual const Vector4& GetRenderColor( unsigned int bufferId ) {