// EXTERNAL INCLUDES
#include <dali/graphics-api/graphics-pipeline-create-info.h>
#include <dali/graphics-api/graphics-pipeline.h>
+#include <string.h>
// INTERNAL INCLUDES
+#include "gles-graphics-reflection.h"
#include "gles-graphics-resource.h"
namespace Dali::Graphics::GLES
{
-using PipelineResource = Resource<Graphics::Pipeline, Graphics::PipelineCreateInfo>;
+class PipelineCache;
+class Program;
-class Pipeline : public PipelineResource
+/**
+ * @brief PipelineImpl is the implementation of Pipeline
+ *
+ * PipelineImpl is owned by the pipeline cache. The client-side
+ * will receive Graphics::Pipeline objects which are only
+ * wrappers for this implementation. The lifecycle of
+ * PipelineImpl is managed by the PipelineCache.
+ */
+class PipelineImpl
+{
+public:
+ /**
+ * @brief Constructor
+ * @param[in] createInfo valid TextureCreateInfo structure
+ * @param[in] controller Reference to the Controller
+ * @param[in] pipelineCache Reference to valid pipeline cache
+ */
+ PipelineImpl(const Graphics::PipelineCreateInfo& createInfo, Graphics::EglGraphicsController& controller, PipelineCache& pipelineCache);
+
+ /**
+ * @brief Destructor
+ */
+ ~PipelineImpl();
+
+ /**
+ * @brief Binds pipeline
+ *
+ * Binds Pipeline by binding GL program and flushing state.
+ *
+ * @param[in] glProgram The GL program to be bound
+ */
+ void Bind(const uint32_t glProgram) const;
+
+ /**
+ * @brief Increases ref count
+ */
+ void Retain();
+
+ /**
+ * @brief Decreases ref count
+ */
+ void Release();
+
+ /**
+ * @brief Retrieves ref count
+ * @return Refcount value
+ */
+ [[nodiscard]] uint32_t GetRefCount() const;
+
+ /**
+ * @brief Returns PipelineCreateInfo structure
+ *
+ * @return PipelineCreateInfo structure
+ */
+ [[nodiscard]] const PipelineCreateInfo& GetCreateInfo() const;
+
+ /**
+ * @brief Returns controller
+ *
+ * @return Reference to the Controller
+ */
+ [[nodiscard]] auto& GetController() const;
+
+private:
+ /**
+ * @brief Helper function. Copies state if pointer is set
+ */
+ template<class T>
+ void CopyStateIfSet(const T* sourceState, T& copyState, T** destState)
+ {
+ *destState = nullptr;
+ if(sourceState)
+ {
+ copyState = *sourceState;
+ *destState = ©State;
+ }
+ }
+
+ /**
+ * @brief Helper function. Copies const state if pointer is set
+ */
+ template<class T>
+ void CopyStateIfSet(const T* sourceState, T& copyState, const T** destState)
+ {
+ *destState = nullptr;
+ if(sourceState)
+ {
+ copyState = *sourceState;
+ *destState = ©State;
+ }
+ }
+
+ // Pipeline state is store locally so any assigned pointers on a
+ // client-side may go safely out of scope.
+ struct PipelineState;
+ std::unique_ptr<PipelineState> mPipelineState;
+
+ EglGraphicsController& mController;
+ PipelineCreateInfo mCreateInfo;
+
+ uint32_t mRefCount{0u};
+};
+
+/**
+ * @brief Pipeline class wraps the PipelineImpl
+ */
+class Pipeline : public Graphics::Pipeline
{
public:
+ Pipeline() = delete;
+
/**
* @brief Constructor
- * @param[in] createInfo Valid createInfo structure
- * @param[in] controller Reference to the controller
+ * @param pipeline Pipeline implementation
*/
- Pipeline(const Graphics::PipelineCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
- : PipelineResource(createInfo, controller)
+ explicit Pipeline(GLES::PipelineImpl& pipeline)
+ : mPipeline(pipeline)
{
+ // increase refcount
+ mPipeline.Retain();
}
/**
* @brief Destructor
*/
- ~Pipeline() override = default;
+ ~Pipeline() override;
/**
- * @brief Called when GL resources are destroyed
+ * @brief Returns pipeline implementation
+ *
+ * @return Valid pipeline implementation
*/
- void DestroyResource() override
+ [[nodiscard]] auto& GetPipeline() const
{
- // TODO: Implement destroying the resource
+ return mPipeline;
}
/**
- * @brief Called when initializing the resource
+ * @brief Returns create info structure
+ *
+ * @return Valid create info structure
+ */
+ [[nodiscard]] const PipelineCreateInfo& GetCreateInfo() const;
+
+ /**
+ * @brief Returns controller
*
- * @return True on success
+ * @return reference to Controller
*/
- bool InitializeResource() override
+ [[nodiscard]] EglGraphicsController& GetController() const;
+
+ bool operator==(const PipelineImpl* impl) const
{
- // TODO: Implement initializing resource
- return {};
+ return &mPipeline == impl;
}
/**
- * @brief Called when UniquePtr<> on client-side dies
+ * @brief Run by UniquePtr to discard resource
*/
- void DiscardResource() override
+ void DiscardResource();
+
+ /**
+ * @brief Destroy resource
+ *
+ * Despite this class doesn't inherit Resource it must provide
+ * (so it won't duplicate same data) same set of functions
+ * so it can work with resource management functions of Controller.
+ */
+ void DestroyResource()
{
- // TODO: Implement moving to the discard queue
+ // Nothing to do here
}
+
+private:
+ GLES::PipelineImpl& mPipeline;
};
} // namespace Dali::Graphics::GLES
-
-#endif
+#endif
\ No newline at end of file