Gimp/app/display/gimpdisplayxfer.c

290 lines
6.9 KiB
C
Raw Normal View History

app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
#include <gegl.h>
#include <gtk/gtk.h>
#include "display-types.h"
#include "gimpdisplayxfer.h"
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
#define NUM_PAGES 2
typedef struct _RTree RTree;
typedef struct _RTreeNode RTreeNode;
struct _RTreeNode
{
RTreeNode *children[2];
RTreeNode *next;
gint x, y, w, h;
};
struct _RTree
{
RTreeNode root;
RTreeNode *available;
};
struct _GimpDisplayXfer
{
/* track subregions of render_surface for efficient uploads */
RTree rtree;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
cairo_surface_t *render_surface[NUM_PAGES];
gint page;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
};
gint GIMP_DISPLAY_RENDER_BUF_WIDTH = 256;
gint GIMP_DISPLAY_RENDER_BUF_HEIGHT = 256;
static RTreeNode *
rtree_node_create (RTree *rtree,
RTreeNode **prev,
2016-12-20 19:05:32 -08:00
gint x,
gint y,
gint w,
gint h)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
{
RTreeNode *node;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
gimp_assert (x >= 0 && x+w <= rtree->root.w);
gimp_assert (y >= 0 && y+h <= rtree->root.h);
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
if (w <= 0 || h <= 0)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
return NULL;
node = g_slice_alloc (sizeof (*node));
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
node->children[0] = NULL;
node->children[1] = NULL;
node->x = x;
node->y = y;
node->w = w;
node->h = h;
node->next = *prev;
*prev = node;
return node;
}
static void
rtree_node_destroy (RTree *rtree,
RTreeNode *node)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
{
gint i;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
for (i = 0; i < 2; i++)
{
if (node->children[i])
2016-12-20 19:05:32 -08:00
rtree_node_destroy (rtree, node->children[i]);
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
}
g_slice_free (RTreeNode, node);
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
}
static RTreeNode *
rtree_node_insert (RTree *rtree,
RTreeNode **prev,
2016-12-20 19:05:32 -08:00
RTreeNode *node,
gint w,
gint h)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
{
*prev = node->next;
if (((node->w - w) | (node->h - h)) > 1)
{
gint ww = node->w - w;
gint hh = node->h - h;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
if (ww >= hh)
2016-12-20 19:05:32 -08:00
{
node->children[0] = rtree_node_create (rtree, prev,
node->x + w, node->y,
ww, node->h);
node->children[1] = rtree_node_create (rtree, prev,
node->x, node->y + h,
w, hh);
}
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
else
2016-12-20 19:05:32 -08:00
{
node->children[0] = rtree_node_create (rtree, prev,
node->x, node->y + h,
node->w, hh);
node->children[1] = rtree_node_create (rtree, prev,
node->x + w, node->y,
ww, h);
}
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
}
return node;
}
static RTreeNode *
rtree_insert (RTree *rtree,
gint w,
gint h)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
{
RTreeNode *node, **prev;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
for (prev = &rtree->available; (node = *prev); prev = &node->next)
if (node->w >= w && node->h >= h)
return rtree_node_insert (rtree, prev, node, w, h);
return NULL;
}
static void
rtree_init (RTree *rtree,
gint w,
gint h)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
{
rtree->root.x = 0;
rtree->root.y = 0;
rtree->root.w = w;
rtree->root.h = h;
rtree->root.children[0] = NULL;
rtree->root.children[1] = NULL;
rtree->root.next = NULL;
rtree->available = &rtree->root;
}
static void
rtree_reset (RTree *rtree)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
{
gint i;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
for (i = 0; i < 2; i++)
{
if (rtree->root.children[i] == NULL)
2016-12-20 19:05:32 -08:00
continue;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
rtree_node_destroy (rtree, rtree->root.children[i]);
rtree->root.children[i] = NULL;
}
rtree->root.next = NULL;
rtree->available = &rtree->root;
}
static void
xfer_destroy (void *data)
{
GimpDisplayXfer *xfer = data;
gint i;
for (i = 0; i < NUM_PAGES; i++)
cairo_surface_destroy (xfer->render_surface[i]);
rtree_reset (&xfer->rtree);
g_free (xfer);
}
GimpDisplayXfer *
gimp_display_xfer_realize (GtkWidget *widget)
{
GdkScreen *screen;
GimpDisplayXfer *xfer;
const gchar *env;
env = g_getenv ("GIMP_DISPLAY_RENDER_BUF_SIZE");
if (env)
{
gint width = atoi (env);
gint height = width;
env = strchr (env, 'x');
if (env)
height = atoi (env + 1);
if (width > 0 && width <= 8192 &&
height > 0 && height <= 8192)
{
GIMP_DISPLAY_RENDER_BUF_WIDTH = width;
GIMP_DISPLAY_RENDER_BUF_HEIGHT = height;
}
}
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
screen = gtk_widget_get_screen (widget);
xfer = g_object_get_data (G_OBJECT (screen), "gimp-display-xfer");
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
if (xfer == NULL)
{
cairo_t *cr;
gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH;
gint h = GIMP_DISPLAY_RENDER_BUF_HEIGHT;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
int n;
xfer = g_new (GimpDisplayXfer, 1);
rtree_init (&xfer->rtree, w, h);
cr = gdk_cairo_create (gtk_widget_get_window (widget));
for (n = 0; n < NUM_PAGES; n++)
{
xfer->render_surface[n] =
cairo_surface_create_similar_image (cairo_get_target (cr),
CAIRO_FORMAT_ARGB32, w, h);
cairo_surface_mark_dirty (xfer->render_surface[n]);
}
cairo_destroy (cr);
xfer->page = 0;
g_object_set_data_full (G_OBJECT (screen),
2016-12-20 19:05:32 -08:00
"gimp-display-xfer",
xfer, xfer_destroy);
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
}
return xfer;
}
cairo_surface_t *
gimp_display_xfer_get_surface (GimpDisplayXfer *xfer,
2016-12-20 19:05:32 -08:00
gint w,
gint h,
2016-12-20 19:05:32 -08:00
gint *src_x,
gint *src_y)
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
{
RTreeNode *node;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
gimp_assert (w <= GIMP_DISPLAY_RENDER_BUF_WIDTH &&
h <= GIMP_DISPLAY_RENDER_BUF_HEIGHT);
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
node = rtree_insert (&xfer->rtree, w, h);
if (node == NULL)
{
xfer->page = (xfer->page + 1) % NUM_PAGES;
cairo_surface_flush (xfer->render_surface[xfer->page]);
rtree_reset (&xfer->rtree);
cairo_surface_mark_dirty (xfer->render_surface[xfer->page]); /* XXX */
node = rtree_insert (&xfer->rtree, w, h);
gimp_assert (node != NULL);
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
}
*src_x = node->x;
*src_y = node->y;
app: Use SHM transport for data transfer for display Recent Cairo uses SHM transports when available, and exposes the ability for its users to manage images shared between it and the display. This allows us to eliminate copies, and if the architecture supports it even to upload directly into GPU addressable memory without any copies (all in normal system memory so we suffer no performance penalty when applying the filters). The caveat is that we need to be aware of the synchronize requirements, the cairo_surface_flush and cairo_surface_mark_dirty, around access to the transport image. To reduce the frequency of these barriers, we can subdivide the transport image into small chunks as to satisfy individual updates and delay the synchronisation barrier until we are forced to reuse earlier pixels. Note this bumps the required Cairo version to 1.12, and please be aware that the XSHM transport requires bug fixes from cairo.git (will be 1.12.12) v2: After further reflections with Mitch, we realized we can share the transport surface between all canvases by attaching it to the common screen. v3: Fix a couple of typos in insert_node() introduced when switching variables names. v4: Encapsulating within an image surface rather than a subsurface was hiding the backing SHM segment from cairo, causing it to allocate further SHM resources to stream the upload. We should be able to use a sub-surface here, but it is more convenient to wrap the pixels in an image surface for rendering the filters (and conveniently masking the callee flushes from invalidating our parent transport surface). Cc: Michael Natterer <mitch@gimp.org>
2013-01-30 01:50:54 -08:00
return xfer->render_surface[xfer->page];
}