首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >开罗-多线程-在cairo_image_surface_create期间卡住了

开罗-多线程-在cairo_image_surface_create期间卡住了
EN

Stack Overflow用户
提问于 2019-09-26 15:42:07
回答 1查看 175关注 0票数 0

我有多线程应用程序,每个线程创建自己的表面,渲染内容,保存和销毁所有。

然而,过了一段时间(如。20张图片被保存下来),这个应用程序在_cairo_atomic_init_once_enter中运行,来自cairo-atomic-private.h

下面是的堆栈跟踪:

代码语言:javascript
复制
[Inline Frame] app.exe!_cairo_atomic_init_once_enter(unsigned int *) Line 409   C
app.exe!_cairo_image_spans_compositor_get() Line 3135   C
[Inline Frame] app.exe!_cairo_image_surface_init(_cairo_image_surface *) Line 176   C
app.exe!_cairo_image_surface_create_for_pixman_image(pixman_image * pixman_image=0x0000023c1d1f31f0, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8) Line 197   C
app.exe!_cairo_image_surface_create_with_pixman_format(unsigned char * data=0x0000000000000000, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8, int width, int height, int stride=-1) Line 355  C
app.exe!cairo_image_surface_create(_cairo_format format, int width, int height) Line 403    C

我打电话说:

代码语言:javascript
复制
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, int(w), int(h));

我的并行循环通过以下方式完成:

代码语言:javascript
复制
std::vector<int> xSeq(countX); 
std::iota(std::begin(xSeq), std::end(xSeq), 0); // Fill with 0, 1, ..., countX.
std::for_each(std::execution::par, std::begin(xSeq), std::end(xSeq), [&](auto x)
{
    //create cairo surface, write to it, store it and release it
}

如果我运行串行版本,一切都正常工作。

编辑:存储表面到图像,我不使用内部PNG保护程序。我有自己的执行,这是基于:

代码语言:javascript
复制
cairo_surface_flush(surface);
data = cairo_image_surface_get_data(surface);

data包含来自cairo的原始数据,我手动处理它们,并将它们存储在自己的压缩系统中。

在某些情况下,我还使用相同的系统将数据“注入”到cairo面。我获得data指针,手动重写一些像素,并调用cairo_surface_mark_dirty(surface)通知Cairo更改。

EN

回答 1

Stack Overflow用户

发布于 2019-09-27 05:38:22

这并不是真正的答案,但你所看到的行为应该是不可能的。

_cairo_image_traps_compositor_get有一个cairo_atomic_once_t变量,用于保护某些初始化。因为它是静态的,所以我们可以确保没有其他代码接触到这个变量。

https://github.com/freedesktop/cairo/blob/52a7c79fd4ff96bb5fac175f0199819b0f8c18fc/src/cairo-image-compositor.c#L1270-L1304

_cairo_atomic_init_once_enter检查once是否已经初始化,然后只返回0/ false。因为你说你已经有20个成功的电话,初始化必须已经完成。否则,其他20个电话就不应该起作用。

https://github.com/freedesktop/cairo/blob/52a7c79fd4ff96bb5fac175f0199819b0f8c18fc/src/cairo-atomic-private.h#L398-L411

根据上面的..。这是不可能的,对吧?除非某些东西覆盖了一些它不应该触及的内存,并且once的值被破坏了,或者类似的东西。或者,这是由于我不明白的原因而产生的某种错误编译。你是自己编译开罗的,还是从哪里得到的?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58120390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档