mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
api: remove SwCanvas::mempool()
We have improved the functionality to manage the memory pool safely, by figuring out the current working threads. Users no longer need to manually configure memory pool management, and the related APIs have been removed. API Removals: - Result SwCanvas::mempool(MempoolPolicy policy) - enum SwCanvas::MempoolPolicy - Tvg_Result tvg_swcanvas_set_mempool(Tvg_Canvas* canvas, Tvg_Mempool_Policy policy) - enum Tvg_Mempool_Policy issue: https://github.com/thorvg/thorvg/issues/3116
This commit is contained in:
parent
3ed357e17a
commit
eab9d68e67
11 changed files with 28 additions and 134 deletions
|
@ -303,7 +303,6 @@ int main(int argc, char **argv)
|
|||
//create the canvas
|
||||
canvas = tvg_swcanvas_create();
|
||||
tvg_swcanvas_set_target(canvas, (uint32_t*)surface->pixels, surface->w, surface->pitch / 4, surface->h, TVG_COLORSPACE_ARGB8888);
|
||||
tvg_swcanvas_set_mempool(canvas, TVG_MEMPOOL_POLICY_DEFAULT);
|
||||
|
||||
contents();
|
||||
|
||||
|
|
35
inc/thorvg.h
35
inc/thorvg.h
|
@ -1666,17 +1666,6 @@ class TVG_API SwCanvas final : public Canvas
|
|||
public:
|
||||
~SwCanvas();
|
||||
|
||||
/**
|
||||
* @brief Enumeration specifying the methods of Memory Pool behavior policy.
|
||||
* @since 0.4
|
||||
*/
|
||||
enum MempoolPolicy : uint8_t
|
||||
{
|
||||
Default = 0, ///< Default behavior that ThorVG is designed to.
|
||||
Shareable, ///< Memory Pool is shared among the SwCanvases.
|
||||
Individual ///< Allocate designated memory pool that is only used by current instance.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Sets the drawing target for the rasterization.
|
||||
*
|
||||
|
@ -1699,30 +1688,6 @@ public:
|
|||
*/
|
||||
Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Set sw engine memory pool behavior policy.
|
||||
*
|
||||
* Basically ThorVG draws a lot of shapes, it allocates/deallocates a few chunk of memory
|
||||
* while processing rendering. It internally uses one shared memory pool
|
||||
* which can be reused among the canvases in order to avoid memory overhead.
|
||||
*
|
||||
* Thus ThorVG suggests using a memory pool policy to satisfy user demands,
|
||||
* if it needs to guarantee the thread-safety of the internal data access.
|
||||
*
|
||||
* @param[in] policy The method specifying the Memory Pool behavior. The default value is @c MempoolPolicy::Default.
|
||||
*
|
||||
* @retval Result::InsufficientCondition If the canvas contains some paints already.
|
||||
* @retval Result::NonSupport In case the software engine is not supported.
|
||||
*
|
||||
* @note When @c policy is set as @c MempoolPolicy::Individual, the current instance of canvas uses its own individual
|
||||
* memory data, which is not shared with others. This is necessary when the canvas is accessed on a worker-thread.
|
||||
*
|
||||
* @warning It's not allowed after pushing any paints.
|
||||
*
|
||||
* @since 0.4
|
||||
*/
|
||||
Result mempool(MempoolPolicy policy) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Creates a new SwCanvas object.
|
||||
* @return A new SwCanvas object.
|
||||
|
|
|
@ -419,16 +419,6 @@ TVG_API Tvg_Result tvg_engine_version(uint32_t* major, uint32_t* minor, uint32_t
|
|||
/* SwCanvas API */
|
||||
/************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Enumeration specifying the methods of Memory Pool behavior policy.
|
||||
*/
|
||||
typedef enum {
|
||||
TVG_MEMPOOL_POLICY_DEFAULT = 0, ///< Default behavior that ThorVG is designed to.
|
||||
TVG_MEMPOOL_POLICY_SHAREABLE, ///< Memory Pool is shared among canvases.
|
||||
TVG_MEMPOOL_POLICY_INDIVIDUAL ///< Allocate designated memory pool that is used only by the current canvas instance.
|
||||
} Tvg_Mempool_Policy;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Creates a Canvas object.
|
||||
*
|
||||
|
@ -462,31 +452,6 @@ TVG_API Tvg_Canvas* tvg_swcanvas_create(void);
|
|||
TVG_API Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Tvg_Colorspace cs);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Sets the software engine memory pool behavior policy.
|
||||
*
|
||||
* ThorVG draws a lot of shapes, it allocates/deallocates a few chunk of memory
|
||||
* while processing rendering. It internally uses one shared memory pool
|
||||
* which can be reused among the canvases in order to avoid memory overhead.
|
||||
*
|
||||
* Thus ThorVG suggests using a memory pool policy to satisfy user demands,
|
||||
* if it needs to guarantee the thread-safety of the internal data access.
|
||||
*
|
||||
* @param[in] canvas The Tvg_Canvas object of which the Memory Pool behavior is to be specified.
|
||||
* @param[in] policy The method specifying the Memory Pool behavior. The default value is @c TVG_MEMPOOL_POLICY_DEFAULT.
|
||||
*
|
||||
* @return Tvg_Result enumeration.
|
||||
* @retval TVG_RESULT_INVALID_ARGUMENTS An invalid canvas pointer passed.
|
||||
* @retval TVG_RESULT_INSUFFICIENT_CONDITION The canvas contains some paints already.
|
||||
* @retval TVG_RESULT_NOT_SUPPORTED The software engine is not supported.
|
||||
*
|
||||
* @note When @c policy is set as @c TVG_MEMPOOL_POLICY_INDIVIDUAL, the current instance of canvas uses its own individual
|
||||
* memory data, which is not shared with others. This is necessary when the canvas is accessed on a worker-thread.
|
||||
*
|
||||
* @warning It's not allowed after pushing any paints.
|
||||
*/
|
||||
TVG_API Tvg_Result tvg_swcanvas_set_mempool(Tvg_Canvas* canvas, Tvg_Mempool_Policy policy);
|
||||
|
||||
/** \} */ // end defgroup ThorVGCapi_SwCanvas
|
||||
|
||||
|
||||
|
|
|
@ -88,13 +88,6 @@ TVG_API Tvg_Result tvg_canvas_destroy(Tvg_Canvas* canvas)
|
|||
}
|
||||
|
||||
|
||||
TVG_API Tvg_Result tvg_swcanvas_set_mempool(Tvg_Canvas* canvas, Tvg_Mempool_Policy policy)
|
||||
{
|
||||
if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
|
||||
return (Tvg_Result) reinterpret_cast<SwCanvas*>(canvas)->mempool(static_cast<SwCanvas::MempoolPolicy>(policy));
|
||||
}
|
||||
|
||||
|
||||
TVG_API Tvg_Result tvg_swcanvas_set_target(Tvg_Canvas* canvas, uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Tvg_Colorspace cs)
|
||||
{
|
||||
if (!canvas) return TVG_RESULT_INVALID_ARGUMENT;
|
||||
|
|
|
@ -522,26 +522,6 @@ bool SwRenderer::beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_
|
|||
}
|
||||
|
||||
|
||||
bool SwRenderer::mempool(bool shared)
|
||||
{
|
||||
if (shared == sharedMpool) return true;
|
||||
|
||||
if (shared) {
|
||||
if (!sharedMpool) {
|
||||
if (!mpoolTerm(mpool)) return false;
|
||||
mpool = globalMpool;
|
||||
}
|
||||
} else {
|
||||
if (sharedMpool) mpool = mpoolInit(threadsCnt);
|
||||
}
|
||||
|
||||
sharedMpool = shared;
|
||||
|
||||
if (mpool) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const RenderSurface* SwRenderer::mainSurface()
|
||||
{
|
||||
return surface;
|
||||
|
@ -811,8 +791,15 @@ RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
|||
}
|
||||
|
||||
|
||||
SwRenderer::SwRenderer():mpool(globalMpool)
|
||||
SwRenderer::SwRenderer()
|
||||
{
|
||||
if (TaskScheduler::onthread()) {
|
||||
TVGLOG("SW_RENDERER", "Running on a non-dominant thread!, Renderer(%p)", this);
|
||||
mpool = mpoolInit(threadsCnt);
|
||||
} else {
|
||||
mpool = globalMpool;
|
||||
sharedMpool = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ public:
|
|||
bool clear() override;
|
||||
bool sync() override;
|
||||
bool target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs);
|
||||
bool mempool(bool shared);
|
||||
|
||||
RenderCompositor* target(const RenderRegion& region, ColorSpace cs, CompositionFlag flags) override;
|
||||
bool beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity) override;
|
||||
|
|
|
@ -81,4 +81,4 @@ Result Canvas::viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept
|
|||
Result Canvas::sync() noexcept
|
||||
{
|
||||
return pImpl->sync();
|
||||
}
|
||||
}
|
|
@ -43,25 +43,6 @@ SwCanvas::~SwCanvas()
|
|||
}
|
||||
|
||||
|
||||
Result SwCanvas::mempool(MempoolPolicy policy) noexcept
|
||||
{
|
||||
#ifdef THORVG_SW_RASTER_SUPPORT
|
||||
//We know renderer type, avoid dynamic_cast for performance.
|
||||
auto renderer = static_cast<SwRenderer*>(pImpl->renderer);
|
||||
if (!renderer) return Result::MemoryCorruption;
|
||||
|
||||
//It can't change the policy during the running.
|
||||
if (!pImpl->scene->paints().empty()) return Result::InsufficientCondition;
|
||||
|
||||
if (policy == MempoolPolicy::Individual) renderer->mempool(false);
|
||||
else renderer->mempool(true);
|
||||
|
||||
return Result::Success;
|
||||
#endif
|
||||
return Result::NonSupport;
|
||||
}
|
||||
|
||||
|
||||
Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs) noexcept
|
||||
{
|
||||
#ifdef THORVG_SW_RASTER_SUPPORT
|
||||
|
|
|
@ -20,14 +20,12 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include "tvgArray.h"
|
||||
#include "tvgInlist.h"
|
||||
#include "tvgTaskScheduler.h"
|
||||
|
||||
#ifdef THORVG_THREAD_SUPPORT
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* Internal Class Implementation */
|
||||
|
@ -36,7 +34,9 @@
|
|||
namespace tvg {
|
||||
|
||||
struct TaskSchedulerImpl;
|
||||
static TaskSchedulerImpl* inst = nullptr;
|
||||
static TaskSchedulerImpl* _inst = nullptr;
|
||||
static std::thread::id _tid; //dominant thread id
|
||||
|
||||
|
||||
#ifdef THORVG_THREAD_SUPPORT
|
||||
|
||||
|
@ -189,6 +189,7 @@ struct TaskSchedulerImpl
|
|||
|
||||
#endif //THORVG_THREAD_SUPPORT
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -197,27 +198,28 @@ struct TaskSchedulerImpl
|
|||
|
||||
void TaskScheduler::init(uint32_t threads)
|
||||
{
|
||||
if (inst) return;
|
||||
inst = new TaskSchedulerImpl(threads);
|
||||
if (_inst) return;
|
||||
_inst = new TaskSchedulerImpl(threads);
|
||||
_tid = std::this_thread::get_id();
|
||||
}
|
||||
|
||||
|
||||
void TaskScheduler::term()
|
||||
{
|
||||
delete(inst);
|
||||
inst = nullptr;
|
||||
delete(_inst);
|
||||
_inst = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void TaskScheduler::request(Task* task)
|
||||
{
|
||||
if (inst) inst->request(task);
|
||||
if (_inst) _inst->request(task);
|
||||
}
|
||||
|
||||
|
||||
uint32_t TaskScheduler::threads()
|
||||
{
|
||||
if (inst) return inst->threadCnt();
|
||||
if (_inst) return _inst->threadCnt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -226,4 +228,9 @@ void TaskScheduler::async(bool on)
|
|||
{
|
||||
//toggle async tasking for each thread on/off
|
||||
_async = on;
|
||||
}
|
||||
|
||||
bool TaskScheduler::onthread()
|
||||
{
|
||||
return _tid != std::this_thread::get_id();
|
||||
}
|
|
@ -104,6 +104,7 @@ struct TaskScheduler
|
|||
static void term();
|
||||
static void request(Task* task);
|
||||
static void async(bool on);
|
||||
static bool onthread(); //figure out whether on worker thread or not
|
||||
};
|
||||
|
||||
} //namespace
|
||||
|
|
|
@ -34,9 +34,6 @@ void GifSaver::run(unsigned tid)
|
|||
auto canvas = unique_ptr<SwCanvas>(SwCanvas::gen());
|
||||
if (!canvas) return;
|
||||
|
||||
//Do not share the memory pool since this canvas could be running on a thread.
|
||||
canvas->mempool(SwCanvas::Individual);
|
||||
|
||||
auto w = static_cast<uint32_t>(vsize[0]);
|
||||
auto h = static_cast<uint32_t>(vsize[1]);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue