|
Packit |
030a23 |
/*
|
|
Packit |
030a23 |
* Copyright © 2009 Red Hat, Inc.
|
|
Packit |
030a23 |
*
|
|
Packit |
030a23 |
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
Packit |
030a23 |
* documentation for any purpose is hereby granted without fee, provided that
|
|
Packit |
030a23 |
* the above copyright notice appear in all copies and that both that
|
|
Packit |
030a23 |
* copyright notice and this permission notice appear in supporting
|
|
Packit |
030a23 |
* documentation, and that the name of Red Hat not be used in advertising or
|
|
Packit |
030a23 |
* publicity pertaining to distribution of the software without specific,
|
|
Packit |
030a23 |
* written prior permission. Red Hat makes no representations about the
|
|
Packit |
030a23 |
* suitability of this software for any purpose. It is provided "as is"
|
|
Packit |
030a23 |
* without express or implied warranty.
|
|
Packit |
030a23 |
*
|
|
Packit |
030a23 |
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
|
Packit |
030a23 |
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
Packit |
030a23 |
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
Packit |
030a23 |
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
Packit |
030a23 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
Packit |
030a23 |
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
Packit |
030a23 |
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
Packit |
030a23 |
* SOFTWARE.
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
030a23 |
#include <config.h>
|
|
Packit |
030a23 |
#endif
|
|
Packit |
030a23 |
#include <stdlib.h>
|
|
Packit |
030a23 |
#include "pixman-private.h"
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
pixman_implementation_t *
|
|
Packit |
030a23 |
_pixman_implementation_create (pixman_implementation_t *fallback,
|
|
Packit |
030a23 |
const pixman_fast_path_t *fast_paths)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_implementation_t *imp;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
assert (fast_paths);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if ((imp = malloc (sizeof (pixman_implementation_t))))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_implementation_t *d;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
memset (imp, 0, sizeof *imp);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp->fallback = fallback;
|
|
Packit |
030a23 |
imp->fast_paths = fast_paths;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Make sure the whole fallback chain has the right toplevel */
|
|
Packit |
030a23 |
for (d = imp; d != NULL; d = d->fallback)
|
|
Packit |
030a23 |
d->toplevel = imp;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return imp;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
#define N_CACHED_FAST_PATHS 8
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
typedef struct
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
struct
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_implementation_t * imp;
|
|
Packit |
030a23 |
pixman_fast_path_t fast_path;
|
|
Packit |
030a23 |
} cache [N_CACHED_FAST_PATHS];
|
|
Packit |
030a23 |
} cache_t;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
dummy_composite_rect (pixman_implementation_t *imp,
|
|
Packit |
030a23 |
pixman_composite_info_t *info)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
void
|
|
Packit |
030a23 |
_pixman_implementation_lookup_composite (pixman_implementation_t *toplevel,
|
|
Packit |
030a23 |
pixman_op_t op,
|
|
Packit |
030a23 |
pixman_format_code_t src_format,
|
|
Packit |
030a23 |
uint32_t src_flags,
|
|
Packit |
030a23 |
pixman_format_code_t mask_format,
|
|
Packit |
030a23 |
uint32_t mask_flags,
|
|
Packit |
030a23 |
pixman_format_code_t dest_format,
|
|
Packit |
030a23 |
uint32_t dest_flags,
|
|
Packit |
030a23 |
pixman_implementation_t **out_imp,
|
|
Packit |
030a23 |
pixman_composite_func_t *out_func)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_implementation_t *imp;
|
|
Packit |
030a23 |
cache_t *cache;
|
|
Packit |
030a23 |
int i;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Check cache for fast paths */
|
|
Packit |
030a23 |
cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Note that we check for equality here, not whether
|
|
Packit |
030a23 |
* the cached fast path matches. This is to prevent
|
|
Packit |
030a23 |
* us from selecting an overly general fast path
|
|
Packit |
030a23 |
* when a more specific one would work.
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
if (info->op == op &&
|
|
Packit |
030a23 |
info->src_format == src_format &&
|
|
Packit |
030a23 |
info->mask_format == mask_format &&
|
|
Packit |
030a23 |
info->dest_format == dest_format &&
|
|
Packit |
030a23 |
info->src_flags == src_flags &&
|
|
Packit |
030a23 |
info->mask_flags == mask_flags &&
|
|
Packit |
030a23 |
info->dest_flags == dest_flags &&
|
|
Packit |
030a23 |
info->func)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
*out_imp = cache->cache[i].imp;
|
|
Packit |
030a23 |
*out_func = cache->cache[i].fast_path.func;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
goto update_cache;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
for (imp = toplevel; imp != NULL; imp = imp->fallback)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
const pixman_fast_path_t *info = imp->fast_paths;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
while (info->op != PIXMAN_OP_NONE)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
if ((info->op == op || info->op == PIXMAN_OP_any) &&
|
|
Packit |
030a23 |
/* Formats */
|
|
Packit |
030a23 |
((info->src_format == src_format) ||
|
|
Packit |
030a23 |
(info->src_format == PIXMAN_any)) &&
|
|
Packit |
030a23 |
((info->mask_format == mask_format) ||
|
|
Packit |
030a23 |
(info->mask_format == PIXMAN_any)) &&
|
|
Packit |
030a23 |
((info->dest_format == dest_format) ||
|
|
Packit |
030a23 |
(info->dest_format == PIXMAN_any)) &&
|
|
Packit |
030a23 |
/* Flags */
|
|
Packit |
030a23 |
(info->src_flags & src_flags) == info->src_flags &&
|
|
Packit |
030a23 |
(info->mask_flags & mask_flags) == info->mask_flags &&
|
|
Packit |
030a23 |
(info->dest_flags & dest_flags) == info->dest_flags)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
*out_imp = imp;
|
|
Packit |
030a23 |
*out_func = info->func;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Set i to the last spot in the cache so that the
|
|
Packit |
030a23 |
* move-to-front code below will work
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
i = N_CACHED_FAST_PATHS - 1;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
goto update_cache;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
++info;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* We should never reach this point */
|
|
Packit |
030a23 |
_pixman_log_error (
|
|
Packit |
030a23 |
FUNC,
|
|
Packit |
030a23 |
"No composite function found\n"
|
|
Packit |
030a23 |
"\n"
|
|
Packit |
030a23 |
"The most likely cause of this is that this system has issues with\n"
|
|
Packit |
030a23 |
"thread local storage\n");
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
*out_imp = NULL;
|
|
Packit |
030a23 |
*out_func = dummy_composite_rect;
|
|
Packit |
030a23 |
return;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
update_cache:
|
|
Packit |
030a23 |
if (i)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
while (i--)
|
|
Packit |
030a23 |
cache->cache[i + 1] = cache->cache[i];
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
cache->cache[0].imp = *out_imp;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.op = op;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.src_format = src_format;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.src_flags = src_flags;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.mask_format = mask_format;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.mask_flags = mask_flags;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.dest_format = dest_format;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.dest_flags = dest_flags;
|
|
Packit |
030a23 |
cache->cache[0].fast_path.func = *out_func;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static void
|
|
Packit |
030a23 |
dummy_combine (pixman_implementation_t *imp,
|
|
Packit |
030a23 |
pixman_op_t op,
|
|
Packit |
030a23 |
uint32_t * pd,
|
|
Packit |
030a23 |
const uint32_t * ps,
|
|
Packit |
030a23 |
const uint32_t * pm,
|
|
Packit |
030a23 |
int w)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
pixman_combine_32_func_t
|
|
Packit |
030a23 |
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
|
|
Packit |
030a23 |
pixman_op_t op,
|
|
Packit |
030a23 |
pixman_bool_t component_alpha,
|
|
Packit |
030a23 |
pixman_bool_t narrow)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
while (imp)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_combine_32_func_t f = NULL;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
switch ((narrow << 1) | component_alpha)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
case 0: /* not narrow, not component alpha */
|
|
Packit |
030a23 |
f = (pixman_combine_32_func_t)imp->combine_float[op];
|
|
Packit |
030a23 |
break;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
case 1: /* not narrow, component_alpha */
|
|
Packit |
030a23 |
f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
|
|
Packit |
030a23 |
break;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
case 2: /* narrow, not component alpha */
|
|
Packit |
030a23 |
f = imp->combine_32[op];
|
|
Packit |
030a23 |
break;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
case 3: /* narrow, component_alpha */
|
|
Packit |
030a23 |
f = imp->combine_32_ca[op];
|
|
Packit |
030a23 |
break;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (f)
|
|
Packit |
030a23 |
return f;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp = imp->fallback;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* We should never reach this point */
|
|
Packit |
030a23 |
_pixman_log_error (FUNC, "No known combine function\n");
|
|
Packit |
030a23 |
return dummy_combine;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
pixman_bool_t
|
|
Packit |
030a23 |
_pixman_implementation_blt (pixman_implementation_t * imp,
|
|
Packit |
030a23 |
uint32_t * src_bits,
|
|
Packit |
030a23 |
uint32_t * dst_bits,
|
|
Packit |
030a23 |
int src_stride,
|
|
Packit |
030a23 |
int dst_stride,
|
|
Packit |
030a23 |
int src_bpp,
|
|
Packit |
030a23 |
int dst_bpp,
|
|
Packit |
030a23 |
int src_x,
|
|
Packit |
030a23 |
int src_y,
|
|
Packit |
030a23 |
int dest_x,
|
|
Packit |
030a23 |
int dest_y,
|
|
Packit |
030a23 |
int width,
|
|
Packit |
030a23 |
int height)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
while (imp)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
if (imp->blt &&
|
|
Packit |
030a23 |
(*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
|
|
Packit |
030a23 |
src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
|
|
Packit |
030a23 |
width, height))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
return TRUE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp = imp->fallback;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return FALSE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
pixman_bool_t
|
|
Packit |
030a23 |
_pixman_implementation_fill (pixman_implementation_t *imp,
|
|
Packit |
030a23 |
uint32_t * bits,
|
|
Packit |
030a23 |
int stride,
|
|
Packit |
030a23 |
int bpp,
|
|
Packit |
030a23 |
int x,
|
|
Packit |
030a23 |
int y,
|
|
Packit |
030a23 |
int width,
|
|
Packit |
030a23 |
int height,
|
|
Packit |
030a23 |
uint32_t filler)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
while (imp)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
if (imp->fill &&
|
|
Packit |
030a23 |
((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
return TRUE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp = imp->fallback;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return FALSE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static uint32_t *
|
|
Packit |
030a23 |
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
return NULL;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
void
|
|
Packit |
030a23 |
_pixman_implementation_iter_init (pixman_implementation_t *imp,
|
|
Packit |
030a23 |
pixman_iter_t *iter,
|
|
Packit |
030a23 |
pixman_image_t *image,
|
|
Packit |
030a23 |
int x,
|
|
Packit |
030a23 |
int y,
|
|
Packit |
030a23 |
int width,
|
|
Packit |
030a23 |
int height,
|
|
Packit |
030a23 |
uint8_t *buffer,
|
|
Packit |
030a23 |
iter_flags_t iter_flags,
|
|
Packit |
030a23 |
uint32_t image_flags)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_format_code_t format;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
iter->image = image;
|
|
Packit |
030a23 |
iter->buffer = (uint32_t *)buffer;
|
|
Packit |
030a23 |
iter->x = x;
|
|
Packit |
030a23 |
iter->y = y;
|
|
Packit |
030a23 |
iter->width = width;
|
|
Packit |
030a23 |
iter->height = height;
|
|
Packit |
030a23 |
iter->iter_flags = iter_flags;
|
|
Packit |
030a23 |
iter->image_flags = image_flags;
|
|
Packit |
030a23 |
iter->fini = NULL;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (!iter->image)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
iter->get_scanline = get_scanline_null;
|
|
Packit |
030a23 |
return;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
format = iter->image->common.extended_format_code;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
while (imp)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
if (imp->iter_info)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
const pixman_iter_info_t *info;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
for (info = imp->iter_info; info->format != PIXMAN_null; ++info)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
if ((info->format == PIXMAN_any || info->format == format) &&
|
|
Packit |
030a23 |
(info->image_flags & image_flags) == info->image_flags &&
|
|
Packit |
030a23 |
(info->iter_flags & iter_flags) == info->iter_flags)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
iter->get_scanline = info->get_scanline;
|
|
Packit |
030a23 |
iter->write_back = info->write_back;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (info->initializer)
|
|
Packit |
030a23 |
info->initializer (iter, info);
|
|
Packit |
030a23 |
return;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp = imp->fallback;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
pixman_bool_t
|
|
Packit |
030a23 |
_pixman_disabled (const char *name)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
const char *env;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if ((env = getenv ("PIXMAN_DISABLE")))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
do
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
const char *end;
|
|
Packit |
030a23 |
int len;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if ((end = strchr (env, ' ')))
|
|
Packit |
030a23 |
len = end - env;
|
|
Packit |
030a23 |
else
|
|
Packit |
030a23 |
len = strlen (env);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (strlen (name) == len && strncmp (name, env, len) == 0)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
printf ("pixman: Disabled %s implementation\n", name);
|
|
Packit |
030a23 |
return TRUE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
env += len;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
while (*env++);
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return FALSE;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
static const pixman_fast_path_t empty_fast_path[] =
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
{ PIXMAN_OP_NONE }
|
|
Packit |
030a23 |
};
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
pixman_implementation_t *
|
|
Packit |
030a23 |
_pixman_choose_implementation (void)
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_implementation_t *imp;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp = _pixman_implementation_create_general();
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (!_pixman_disabled ("fast"))
|
|
Packit |
030a23 |
imp = _pixman_implementation_create_fast_path (imp);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp = _pixman_x86_get_implementations (imp);
|
|
Packit |
030a23 |
imp = _pixman_arm_get_implementations (imp);
|
|
Packit |
030a23 |
imp = _pixman_ppc_get_implementations (imp);
|
|
Packit |
030a23 |
imp = _pixman_mips_get_implementations (imp);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
imp = _pixman_implementation_create_noop (imp);
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
if (_pixman_disabled ("wholeops"))
|
|
Packit |
030a23 |
{
|
|
Packit |
030a23 |
pixman_implementation_t *cur;
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
/* Disable all whole-operation paths except the general one,
|
|
Packit |
030a23 |
* so that optimized iterators are used as much as possible.
|
|
Packit |
030a23 |
*/
|
|
Packit |
030a23 |
for (cur = imp; cur->fallback; cur = cur->fallback)
|
|
Packit |
030a23 |
cur->fast_paths = empty_fast_path;
|
|
Packit |
030a23 |
}
|
|
Packit |
030a23 |
|
|
Packit |
030a23 |
return imp;
|
|
Packit |
030a23 |
}
|