Re: Cairo crash with a simple stroke (win32) - PATCH proposal
Fred bca21 <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <CAKTSDKYfO3TTBsJpFn9mOO2+4B-XT3jP2f_PD8RVfkSe_Z157Q@mail.gmail.com> |
bump! Is anyone interested? At least a comment? I am starting to wonder if my emails are actually received by list members... :-) Fred. 2012/11/7 Fred bca21 <[email protected]>: > Hi, > > Does the patch below make sense to you? It seems the extent should > just be offset to the origin when mapping the win32 surface to an > image, since the image is already created at the right location. I > have not been able to make extensive tests yet, but can someone review > this patch? > > BTW, is there any way to build and run the tests on windows? Neither > the configure nor the Makefile.Win32 method work on my system. > > Index: src/win32/cairo-win32-display-surface.c > =================================================================== > --- src/win32/cairo-win32-display-surface.c > +++ src/win32/cairo-win32-display-surface.c > @@ -464,8 +464,16 @@ > surface = to_win32_display_surface (surface->fallback); > done: > GdiFlush(); > - return _cairo_image_surface_map_to_image (surface->image, extents); > > + // since the image built above is already offset at the right > position, create the image at 0,0. > + { > + cairo_rectangle_int_t r; > + r.x=0; > + r.y=0; > + r.width=extents->width; > + r.height=extents->height; > + return _cairo_image_surface_map_to_image (surface->image, &r); > + } > err: > cairo_surface_destroy (surface->fallback); > surface->fallback = NULL; > > > 2012/11/7 Fred bca21 <[email protected]>: >> Hi Again, >> >> It appears that the bug seems to happen because the extents of the >> fallback image has an offset in its origin. >> when performing the mapping of the surface to an image, in >> cairo-win32-display-surface.c, on line 467: >> return _cairo_image_surface_map_to_image (surface->image, extents); >> >> this actually creates a pixman image with an invalid pointer, that is >> supposed to be compensated by the device transform, as you can see in >> cairo-image-surface.c on line 805: >> uint8_t *data; >> >> data = other->data; >> data += extents->y * other->stride; // THIS POINTER IS OUTSIDE OF >> THE ACTUAL IMAGE (the image is created with the actual extent, not the >> entire surface extent) >> data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8; >> >> surface =_cairo_image_surface_create_with_pixman_format (data, >> other->pixman_format, >> extents->width, >> extents->height, >> other->stride); >> >> cairo_surface_set_device_offset (surface, -extents->x, >> -extents->y); /// THIS IS SUPPOSED TO COMPENSATE THE OFFSET ABOVE >> return surface; >> >> But in the end, when reaching the _fill_xrgb32_lerp_opaque_spans >> function, the data pointer is still the wrong one (as offset in the >> function above, not compensated by the device transform). >> >> So either the device transform should be applied at some point and it >> is not, or the mapping of the image is wrong and should not use the >> origin of the extents, >> >> That's all I can do for now with my imited knowledge, but I hope it >> helps a little bit and maybe this will motivate someone to check this >> out. >> >> Regards, >> >> Fred. >> >> 2012/11/7 Fred bca21 <[email protected]>: >>> Hi, >>> >>> No surprise: the issue is still here in 1.12.8. Running the code below >>> crashes in _fill_xrgb32_lerp_opaque_spans. >>> >>> If anyone can give me an idea of how to get started on debugging this, >>> I'd be glad to help fixing this problem. I have already spent some >>> time on it, but it's pretty hard to understand where the composite >>> destination data pointer is changed without not much knowledge of the >>> cairo code. >>> >>> Just wondering: why isn't there much interest for this problem? >>> >>> Thanks! >>> >>> Fred. >>> >>> { >>> // build a bitmap (same issue with DIB, whatever the bit depth) >>> HDC dc=::CreateCompatibleDC(NULL); >>> HBITMAP hBmp=::CreateCompatibleBitmap(dc,100,200); >>> ::SelectObject(dc,hBmp); >>> >>> // set clip region for the DC to one single line in the middle of the bitmap >>> HRGN hrgn = CreateRectRgn(0,100,100, 101); >>> SelectClipRgn(dc, hrgn); >>> ::DeleteObject(hrgn); >>> >>> // create cairo context >>> cairo_surface_t* surface=cairo_win32_surface_create(dc); >>> if(surface) >>> { >>> cairo_t* context=cairo_create(surface); >>> if(context) >>> { >>> // draw one line >>> cairo_move_to(context,1, 1); >>> cairo_line_to(context,10,120); >>> cairo_set_source_rgb(context,1,1,1); >>> >>> // CRASHES HERE: >>> cairo_stroke(context); >>> >>> // cleanup >>> cairo_destroy(context); >>> } >>> cairo_surface_destroy(surface); >>> } >>> } >>> >>> 2012/11/5 Fred bca21 <[email protected]>: >>>> Hi, >>>> >>>> Thank you Martin for your answer. The thing is, it is a feature that a >>>> surface built on a HDC gets the right clipping region. It is indeed >>>> possible to manually overwrite, re-compute and apply the clipping >>>> region to the cairo context, but it is probably better just to fix >>>> cairo and this feature :-). Also, this problem is also probably >>>> occuring in other cases (it is a crash in the compositing functions). >>>> >>>> Has anyone found a way to fix it properly? >>>> >>>> I'll double check with the new 1.12.8 that has just been released >>>> (there seem to be changes in this area), but it would be great to have >>>> feedback from the experts. >>>> >>>> Regards, >>>> >>>> Fred. >>>> >>>> >>>> 2012/10/30 Martin Schlemmer <[email protected]>: >>>>> Hi, >>>>> >>>>>> After some additionnal debugging, it appears that the raw data pointer >>>>>> (unsigned char *data;) in the destination image surface for the >>>>>> compositor is invalid, hence the crash. I have not been able to find >>>>>> out where this comes from yet (the multiple casts throughout the code >>>>>> does not make easy for a newcomer to track this field in the image >>>>>> surface). All I can say is it is valid when the fallback image for the >>>>>> surface is created, at the beginning of the cairo_stroke call. >>>>> >>>>>> Does anybody have any clue? I feel a bit lonely on this issue :). >>>>> >>>>> I am not sure if its a feature or a bug, but if you remove the bits that sets the Clip Region directly on the HDC, it does not crash. >>>>> I assume that you should rather use: >>>>> >>>>> cairo_rectangle () >>>>> cairo_clip () >>>>> >>>>> on the created context. >>>>> >>>>> I could however be incorrect, and that creating a surface from a HDC which already has a Clip Region set directly on the HDC should not give current results - maybe somebody can verify? >>>>> >>>>> >>>>> Regards, >>>>> Martin >>>>> >>>>> >>>>>>2012/10/25 Fred bca21 <fredbca21 at gmail.com>: >>>>>> Hi, >>>>>> >>>>>> I have just tested with the latest cairo release (1.12.6), and it >>>>>> appears that the issue is still here (crash at the exact same >>>>>> location). Has anyone an idea of how to fix it? Should I maybe post >>>>>> this to the bugs mailing list? >>>>>> >>>>>> Regards, >>>>>> >>>>>> Fred. >>>>>> >>>>>> >>>>>> 2012/10/19 Fred bca21 <fredbca21 at gmail.com>: >>>>>>> Hi, >>>>>>> >>>>>>> I am new to this list but I have been using cairo and monitoring posts >>>>>>> for a couple of months now. I have a strange issue on windows when the >>>>>>> intersection between the clipping region and the drawing is very >>>>>>> small, so I am posting here with the hope that someone can help (I am >>>>>>> a bit too new to cairo's internals to debug this problem). >>>>>>> >>>>>>> Typically, the simple code below crashes (I am using a DDB bitmap for >>>>>>> the example, but it also crashes with any DC). >>>>>>> >>>>>>> #include "cairo.h" >>>>>>> #include "cairo-win32.h" >>>>>>> #include <windows.h> >>>>>>> { >>>>>>> // build a bitmap (same issue with DIB, whatever the bit depth) >>>>>>> HDC dc=::CreateCompatibleDC(NULL); >>>>>>> HBITMAP hBmp=::CreateCompatibleBitmap(dc,100,200); >>>>>>> ::SelectObject(dc,hBmp); >>>>>>> >>>>>>> // set clip region for the DC to one single line in the middle of the bitmap >>>>>>> HRGN hrgn = CreateRectRgn(0,100,100, 101); >>>>>>> SelectClipRgn(dc, hrgn); >>>>>>> ::DeleteObject(hrgn); >>>>>>> >>>>>>> // create cairo context >>>>>>> cairo_surface_t* surface=cairo_win32_surface_create(dc); >>>>>>> if(surface) >>>>>>> { >>>>>>> cairo_t* context=cairo_create(surface); >>>>>>> if(context) >>>>>>> { >>>>>>> // draw one line >>>>>>> cairo_move_to(context,1, 1); >>>>>>> cairo_line_to(context,10,120); >>>>>>> cairo_set_source_rgb(context,1,1,1); >>>>>>> >>>>>>> // CRASHES HERE (see below): >>>>>>> cairo_stroke(context); >>>>>>> >>>>>>> // cleanup >>>>>>> cairo_destroy(context); >>>>>>> } >>>>>>> cairo_surface_destroy(surface); >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> The crash occurs in cairo-image-compositor.c, on line 2197, in >>>>>>> _fill_xrgb32_lerp_opaque_spans(): >>>>>>> >>>>>>> } else while (len--) { >>>>>>> // On this line below, d has an invalid address >>>>>>> *d = lerp8x4 (r->u.fill.pixel, a, *d); >>>>>>> d++; >>>>>>> } >>>>>>> >>>>>>> If it may help, am using the static lib version of the latest release >>>>>>> (1.12.4 - pixman 26.2), and it crashes in debug or release mode, 32 or >>>>>>> 64-bit windows. It's too bad because this crash occurs all the time in >>>>>>> my code that extensively uses clipping regions! >>>>>>> >>>>>>> This crash also occurs with the previous version of cairo (1.12.2) and >>>>>>> pixman 26.0, but at a different stage (in pixman if I remember well), >>>>> >>>>> >>>>> Vrywaringsklousule / Disclaimer: http://www.nwu.ac.za/it/gov-man/disclaimer.html >>>>> -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo