From 7fc2654a1fdd6d6c41eddaac50b3668433873679 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Sat, 27 Apr 2013 04:27:39 -0400 Subject: [PATCH] pixman/refactor: Delete this file Essentially all of it is obsolete by now. --- pixman/refactor | 478 -------------------------------------------------------- 1 file changed, 478 deletions(-) delete mode 100644 pixman/refactor diff --git a/pixman/refactor b/pixman/refactor deleted file mode 100644 index 65e207a..0000000 --- a/pixman/refactor +++ /dev/null @@ -1,478 +0,0 @@ -Roadmap - -- Move all the fetchers etc. into pixman-image to make pixman-compose.c - less intimidating. - - DONE - -- Make combiners for unified alpha take a mask argument. That way - we won't need two separate paths for unified vs component in the - general compositing code. - - DONE, except that the Altivec code needs to be updated. Luca is - looking into that. - -- Delete separate 'unified alpha' path - - DONE - -- Split images into their own files - - DONE - -- Split the gradient walker code out into its own file - - DONE - -- Add scanline getters per image - - DONE - -- Generic 64 bit fetcher - - DONE - -- Split fast path tables into their respective architecture dependent - files. - -See "Render Algorithm" below for rationale - -Images will eventually have these virtual functions: - - get_scanline() - get_scanline_wide() - get_pixel() - get_pixel_wide() - get_untransformed_pixel() - get_untransformed_pixel_wide() - get_unfiltered_pixel() - get_unfiltered_pixel_wide() - - store_scanline() - store_scanline_wide() - -1. - -Initially we will just have get_scanline() and get_scanline_wide(); -these will be based on the ones in pixman-compose. Hopefully this will -reduce the complexity in pixman_composite_rect_general(). - -Note that there is access considerations - the compose function is -being compiled twice. - - -2. - -Split image types into their own source files. Export noop virtual -reinit() call. Call this whenever a property of the image changes. - - -3. - -Split the get_scanline() call into smaller functions that are -initialized by the reinit() call. - -The Render Algorithm: - (first repeat, then filter, then transform, then clip) - -Starting from a destination pixel (x, y), do - - 1 x = x - xDst + xSrc - y = y - yDst + ySrc - - 2 reject pixel that is outside the clip - - This treats clipping as something that happens after - transformation, which I think is correct for client clips. For - hierarchy clips it is wrong, but who really cares? Without - GraphicsExposes hierarchy clips are basically irrelevant. Yes, - you could imagine cases where the pixels of a subwindow of a - redirected, transformed window should be treated as - transparent. I don't really care - - Basically, I think the render spec should say that pixels that - are unavailable due to the hierarchy have undefined content, - and that GraphicsExposes are not generated. Ie., basically - that using non-redirected windows as sources is fail. This is - at least consistent with the current implementation and we can - update the spec later if someone makes it work. - - The implication for render is that it should stop passing the - hierarchy clip to pixman. In pixman, if a souce image has a - clip it should be used in computing the composite region and - nowhere else, regardless of what "has_client_clip" says. The - default should be for there to not be any clip. - - I would really like to get rid of the client clip as well for - source images, but unfortunately there is at least one - application in the wild that uses them. - - 3 Transform pixel: (x, y) = T(x, y) - - 4 Call p = GetUntransformedPixel (x, y) - - 5 If the image has an alpha map, then - - Call GetUntransformedPixel (x, y) on the alpha map - - add resulting alpha channel to p - - return p - - Where GetUnTransformedPixel is: - - 6 switch (filter) - { - case NEAREST: - return GetUnfilteredPixel (x, y); - break; - - case BILINEAR: - return GetUnfilteredPixel (...) // 4 times - break; - - case CONVOLUTION: - return GetUnfilteredPixel (...) // as many times as necessary. - break; - } - - Where GetUnfilteredPixel (x, y) is - - 7 switch (repeat) - { - case REPEAT_NORMAL: - case REPEAT_PAD: - case REPEAT_REFLECT: - // adjust x, y as appropriate - break; - - case REPEAT_NONE: - if (x, y) is outside image bounds - return 0; - break; - } - - return GetRawPixel(x, y) - - Where GetRawPixel (x, y) is - - 8 Compute the pixel in question, depending on image type. - -For gradients, repeat has a totally different meaning, so -UnfilteredPixel() and RawPixel() must be the same function so that -gradients can do their own repeat algorithm. - -So, the GetRawPixel - - for bits must deal with repeats - for gradients must deal with repeats (differently) - for solids, should ignore repeats. - - for polygons, when we add them, either ignore repeats or do - something similar to bits (in which case, we may want an extra - layer of indirection to modify the coordinates). - -It is then possible to build things like "get scanline" or "get tile" on -top of this. In the simplest case, just repeatedly calling GetPixel() -would work, but specialized get_scanline()s or get_tile()s could be -plugged in for common cases. - -By not plugging anything in for images with access functions, we only -have to compile the pixel functions twice, not the scanline functions. - -And we can get rid of fetchers for the bizarre formats that no one -uses. Such as b2g3r3 etc. r1g2b1? Seriously? It is also worth -considering a generic format based pixel fetcher for these edge cases. - -Since the actual routines depend on the image attributes, the images -must be notified when those change and update their function pointers -appropriately. So there should probably be a virtual function called -(* reinit) or something like that. - -There will also be wide fetchers for both pixels and lines. The line -fetcher will just call the wide pixel fetcher. The wide pixel fetcher -will just call expand, except for 10 bit formats. - -Rendering pipeline: - -Drawable: - 0. if (picture has alpha map) - 0.1. Position alpha map according to the alpha_x/alpha_y - 0.2. Where the two drawables intersect, the alpha channel - Replace the alpha channel of source with the one - from the alpha map. Replacement only takes place - in the intersection of the two drawables' geometries. - 1. Repeat the drawable according to the repeat attribute - 2. Reconstruct a continuous image according to the filter - 3. Transform according to the transform attribute - 4. Position image such that src_x, src_y is over dst_x, dst_y - 5. Sample once per destination pixel - 6. Clip. If a pixel is not within the source clip, then no - compositing takes place at that pixel. (Ie., it's *not* - treated as 0). - - Sampling a drawable: - - - If the channel does not have an alpha channel, the pixels in it - are treated as opaque. - - Note on reconstruction: - - - The top left pixel has coordinates (0.5, 0.5) and pixels are - spaced 1 apart. - -Gradient: - 1. Unless gradient type is conical, repeat the underlying (0, 1) - gradient according to the repeat attribute - 2. Integrate the gradient across the plane according to type. - 3. Transform according to transform attribute - 4. Position gradient - 5. Sample once per destination pixel. - 6. Clip - -Solid Fill: - 1. Repeat has no effect - 2. Image is already continuous and defined for the entire plane - 3. Transform has no effect - 4. Positioning has no effect - 5. Sample once per destination pixel. - 6. Clip - -Polygon: - 1. Repeat has no effect - 2. Image is already continuous and defined on the whole plane - 3. Transform according to transform attribute - 4. Position image - 5. Supersample 15x17 per destination pixel. - 6. Clip - -Possibly interesting additions: - - More general transformations, such as warping, or general - shading. - - - Shader image where a function is called to generate the - pixel (ie., uploading assembly code). - - - Resampling kernels - - In principle the polygon image uses a 15x17 box filter for - resampling. If we allow general resampling filters, then we - get all the various antialiasing types for free. - - Bilinear downsampling looks terrible and could be much - improved by a resampling filter. NEAREST reconstruction - combined with a box resampling filter is what GdkPixbuf - does, I believe. - - Useful for high frequency gradients as well. - - (Note that the difference between a reconstruction and a - resampling filter is mainly where in the pipeline they - occur. High quality resampling should use a correctly - oriented kernel so it should happen after transformation. - - An implementation can transform the resampling kernel and - convolve it with the reconstruction if it so desires, but it - will need to deal with the fact that the resampling kernel - will not necessarily be pixel aligned. - - "Output kernels" - - One could imagine doing the resampling after compositing, - ie., for each destination pixel sample each source image 16 - times, then composite those subpixels individually, then - finally apply a kernel. - - However, this is effectively the same as full screen - antialiasing, which is a simpler way to think about it. So - resampling kernels may make sense for individual images, but - not as a post-compositing step. - - Fullscreen AA is inefficient without chained compositing - though. Consider an (image scaled up to oversample size IN - some polygon) scaled down to screen size. With the current - implementation, there will be a huge temporary. With chained - compositing, the whole thing ends up being equivalent to the - output kernel from above. - - - Color space conversion - - The complete model here is that each surface has a color - space associated with it and that the compositing operation - also has one associated with it. Note also that gradients - should have associcated colorspaces. - - - Dithering - - If people dither something that is already dithered, it will - look terrible, but don't do that, then. (Dithering happens - after resampling if at all - what is the relationship - with color spaces? Presumably dithering should happen in linear - intensity space). - - - Floating point surfaces, 16, 32 and possibly 64 bit per - channel. - - Maybe crack: - - - Glyph polygons - - If glyphs could be given as polygons, they could be - positioned and rasterized more accurately. The glyph - structure would need subpixel positioning though. - - - Luminance vs. coverage for the alpha channel - - Whether the alpha channel should be interpreted as luminance - modulation or as coverage (intensity modulation). This is a - bit of a departure from the rendering model though. It could - also be considered whether it should be possible to have - both channels in the same drawable. - - - Alternative for component alpha - - - Set component-alpha on the output image. - - - This means each of the components are sampled - independently and composited in the corresponding - channel only. - - - Have 3 x oversampled mask - - - Scale it down by 3 horizontally, with [ 1/3, 1/3, 1/3 ] - resampling filter. - - Is this equivalent to just using a component alpha mask? - - Incompatible changes: - - - Gradients could be specified with premultiplied colors. (You - can use a mask to get things like gradients from solid red to - transparent red. - -Refactoring pixman - -The pixman code is not particularly nice to put it mildly. Among the -issues are - -- inconsistent naming style (fb vs Fb, camelCase vs - underscore_naming). Sometimes there is even inconsistency *within* - one name. - - fetchProc32 ACCESS(pixman_fetchProcForPicture32) - - may be one of the uglies names ever created. - - coding style: - use the one from cairo except that pixman uses this brace style: - - while (blah) - { - } - - Format do while like this: - - do - { - - } - while (...); - -- PIXMAN_COMPOSITE_RECT_GENERAL() is horribly complex - -- switch case logic in pixman-access.c - - Instead it would be better to just store function pointers in the - image objects themselves, - - get_pixel() - get_scanline() - -- Much of the scanline fetching code is for formats that no one - ever uses. a2r2g2b2 anyone? - - It would probably be worthwhile having a generic fetcher for any - pixman format whatsoever. - -- Code related to particular image types should be split into individual - files. - - pixman-bits-image.c - pixman-linear-gradient-image.c - pixman-radial-gradient-image.c - pixman-solid-image.c - -- Fast path code should be split into files based on architecture: - - pixman-mmx-fastpath.c - pixman-sse2-fastpath.c - pixman-c-fastpath.c - - etc. - - Each of these files should then export a fastpath table, which would - be declared in pixman-private.h. This should allow us to get rid - of the pixman-mmx.h files. - - The fast path table should describe each fast path. Ie there should - be bitfields indicating what things the fast path can handle, rather than - like now where it is only allowed to take one format per src/mask/dest. Ie., - - { - FAST_a8r8g8b8 | FAST_x8r8g8b8, - FAST_null, - FAST_x8r8g8b8, - FAST_repeat_normal | FAST_repeat_none, - the_fast_path - } - -There should then be *one* file that implements pixman_image_composite(). -This should do this: - - optimize_operator(); - - convert 1x1 repeat to solid (actually this should be done at - image creation time). - - is there a useful fastpath? - -There should be a file called pixman-cpu.c that contains all the -architecture specific stuff to detect what CPU features we have. - -Issues that must be kept in mind: - - - we need accessor code to be preserved - - - maybe there should be a "store_scanline" too? - - Is this sufficient? - - We should preserve the optimization where the - compositing happens directly in the destination - whenever possible. - - - It should be possible to create GPU samplers from the - images. - -The "horizontal" classification should be a bit in the image, the -"vertical" classification should just happen inside the gradient -file. Note though that - - (a) these will change if the tranformation/repeat changes. - - (b) at the moment the optimization for linear gradients - takes the source rectangle into account. Presumably - this is to also optimize the case where the gradient - is close enough to horizontal? - -Who is responsible for repeats? In principle it should be the scanline -fetch. Right now NORMAL repeats are handled by walk_composite_region() -while other repeats are handled by the scanline code. - - -(Random note on filtering: do you filter before or after -transformation? Hardware is going to filter after transformation; -this is also what pixman does currently). It's not completely clear -what filtering *after* transformation means. One thing that might look -good would be to do *supersampling*, ie., compute multiple subpixels -per destination pixel, then average them together. -- 2.7.4