/*
 * Copyright © 2009 Red Hat, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Red Hat not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission.  Red Hat makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include "pixman-private.h"

pixman_implementation_t *
_pixman_implementation_create (pixman_implementation_t *fallback,
			       const pixman_fast_path_t *fast_paths)
{
    pixman_implementation_t *imp;

    assert (fast_paths);

    if ((imp = malloc (sizeof (pixman_implementation_t))))
    {
	pixman_implementation_t *d;

	memset (imp, 0, sizeof *imp);

	imp->fallback = fallback;
	imp->fast_paths = fast_paths;
	
	/* Make sure the whole fallback chain has the right toplevel */
	for (d = imp; d != NULL; d = d->fallback)
	    d->toplevel = imp;
    }

    return imp;
}

#define N_CACHED_FAST_PATHS 8

typedef struct
{
    struct
    {
	pixman_implementation_t *	imp;
	pixman_fast_path_t		fast_path;
    } cache [N_CACHED_FAST_PATHS];
} cache_t;

PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);

static void
dummy_composite_rect (pixman_implementation_t *imp,
		      pixman_composite_info_t *info)
{
}

void
_pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
					 pixman_op_t               op,
					 pixman_format_code_t      src_format,
					 uint32_t                  src_flags,
					 pixman_format_code_t      mask_format,
					 uint32_t                  mask_flags,
					 pixman_format_code_t      dest_format,
					 uint32_t                  dest_flags,
					 pixman_implementation_t **out_imp,
					 pixman_composite_func_t  *out_func)
{
    pixman_implementation_t *imp;
    cache_t *cache;
    int i;

    /* Check cache for fast paths */
    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);

    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
    {
	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);

	/* Note that we check for equality here, not whether
	 * the cached fast path matches. This is to prevent
	 * us from selecting an overly general fast path
	 * when a more specific one would work.
	 */
	if (info->op == op			&&
	    info->src_format == src_format	&&
	    info->mask_format == mask_format	&&
	    info->dest_format == dest_format	&&
	    info->src_flags == src_flags	&&
	    info->mask_flags == mask_flags	&&
	    info->dest_flags == dest_flags	&&
	    info->func)
	{
	    *out_imp = cache->cache[i].imp;
	    *out_func = cache->cache[i].fast_path.func;

	    goto update_cache;
	}
    }

    for (imp = toplevel; imp != NULL; imp = imp->fallback)
    {
	const pixman_fast_path_t *info = imp->fast_paths;

	while (info->op != PIXMAN_OP_NONE)
	{
	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
		/* Formats */
		((info->src_format == src_format) ||
		 (info->src_format == PIXMAN_any))			&&
		((info->mask_format == mask_format) ||
		 (info->mask_format == PIXMAN_any))			&&
		((info->dest_format == dest_format) ||
		 (info->dest_format == PIXMAN_any))			&&
		/* Flags */
		(info->src_flags & src_flags) == info->src_flags	&&
		(info->mask_flags & mask_flags) == info->mask_flags	&&
		(info->dest_flags & dest_flags) == info->dest_flags)
	    {
		*out_imp = imp;
		*out_func = info->func;

		/* Set i to the last spot in the cache so that the
		 * move-to-front code below will work
		 */
		i = N_CACHED_FAST_PATHS - 1;

		goto update_cache;
	    }

	    ++info;
	}
    }

    /* We should never reach this point */
    _pixman_log_error (
        FUNC,
        "No composite function found\n"
        "\n"
        "The most likely cause of this is that this system has issues with\n"
        "thread local storage\n");

    *out_imp = NULL;
    *out_func = dummy_composite_rect;
    return;

update_cache:
    if (i)
    {
	while (i--)
	    cache->cache[i + 1] = cache->cache[i];

	cache->cache[0].imp = *out_imp;
	cache->cache[0].fast_path.op = op;
	cache->cache[0].fast_path.src_format = src_format;
	cache->cache[0].fast_path.src_flags = src_flags;
	cache->cache[0].fast_path.mask_format = mask_format;
	cache->cache[0].fast_path.mask_flags = mask_flags;
	cache->cache[0].fast_path.dest_format = dest_format;
	cache->cache[0].fast_path.dest_flags = dest_flags;
	cache->cache[0].fast_path.func = *out_func;
    }
}

static void
dummy_combine (pixman_implementation_t *imp,
	       pixman_op_t              op,
	       uint32_t *               pd,
	       const uint32_t *         ps,
	       const uint32_t *         pm,
	       int                      w)
{
}

pixman_combine_32_func_t
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
					pixman_op_t		 op,
					pixman_bool_t		 component_alpha,
					pixman_bool_t		 narrow)
{
    while (imp)
    {
	pixman_combine_32_func_t f = NULL;

	switch ((narrow << 1) | component_alpha)
	{
	case 0: /* not narrow, not component alpha */
	    f = (pixman_combine_32_func_t)imp->combine_float[op];
	    break;
	    
	case 1: /* not narrow, component_alpha */
	    f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
	    break;

	case 2: /* narrow, not component alpha */
	    f = imp->combine_32[op];
	    break;

	case 3: /* narrow, component_alpha */
	    f = imp->combine_32_ca[op];
	    break;
	}

	if (f)
	    return f;

	imp = imp->fallback;
    }

    /* We should never reach this point */
    _pixman_log_error (FUNC, "No known combine function\n");
    return dummy_combine;
}

pixman_bool_t
_pixman_implementation_blt (pixman_implementation_t * imp,
                            uint32_t *                src_bits,
                            uint32_t *                dst_bits,
                            int                       src_stride,
                            int                       dst_stride,
                            int                       src_bpp,
                            int                       dst_bpp,
                            int                       src_x,
                            int                       src_y,
                            int                       dest_x,
                            int                       dest_y,
                            int                       width,
                            int                       height)
{
    while (imp)
    {
	if (imp->blt &&
	    (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
			 src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
			 width, height))
	{
	    return TRUE;
	}

	imp = imp->fallback;
    }

    return FALSE;
}

pixman_bool_t
_pixman_implementation_fill (pixman_implementation_t *imp,
                             uint32_t *               bits,
                             int                      stride,
                             int                      bpp,
                             int                      x,
                             int                      y,
                             int                      width,
                             int                      height,
                             uint32_t                 filler)
{
    while (imp)
    {
	if (imp->fill &&
	    ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
	{
	    return TRUE;
	}

	imp = imp->fallback;
    }

    return FALSE;
}

static uint32_t *
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
{
    return NULL;
}

void
_pixman_implementation_iter_init (pixman_implementation_t *imp,
                                  pixman_iter_t           *iter,
                                  pixman_image_t          *image,
                                  int                      x,
                                  int                      y,
                                  int                      width,
                                  int                      height,
                                  uint8_t                 *buffer,
                                  iter_flags_t             iter_flags,
                                  uint32_t                 image_flags)
{
    pixman_format_code_t format;

    iter->image = image;
    iter->buffer = (uint32_t *)buffer;
    iter->x = x;
    iter->y = y;
    iter->width = width;
    iter->height = height;
    iter->iter_flags = iter_flags;
    iter->image_flags = image_flags;
    iter->fini = NULL;

    if (!iter->image)
    {
	iter->get_scanline = get_scanline_null;
	return;
    }

    format = iter->image->common.extended_format_code;

    while (imp)
    {
        if (imp->iter_info)
        {
            const pixman_iter_info_t *info;

            for (info = imp->iter_info; info->format != PIXMAN_null; ++info)
            {
                if ((info->format == PIXMAN_any || info->format == format) &&
                    (info->image_flags & image_flags) == info->image_flags &&
                    (info->iter_flags & iter_flags) == info->iter_flags)
                {
                    iter->get_scanline = info->get_scanline;
                    iter->write_back = info->write_back;

                    if (info->initializer)
                        info->initializer (iter, info);
                    return;
                }
            }
        }

        imp = imp->fallback;
    }
}

pixman_bool_t
_pixman_disabled (const char *name)
{
    const char *env;

    if ((env = getenv ("PIXMAN_DISABLE")))
    {
	do
	{
	    const char *end;
	    int len;

	    if ((end = strchr (env, ' ')))
		len = end - env;
	    else
		len = strlen (env);

	    if (strlen (name) == len && strncmp (name, env, len) == 0)
	    {
		printf ("pixman: Disabled %s implementation\n", name);
		return TRUE;
	    }

	    env += len;
	}
	while (*env++);
    }

    return FALSE;
}

static const pixman_fast_path_t empty_fast_path[] =
{
    { PIXMAN_OP_NONE }
};

pixman_implementation_t *
_pixman_choose_implementation (void)
{
    pixman_implementation_t *imp;

    imp = _pixman_implementation_create_general();

    if (!_pixman_disabled ("fast"))
	imp = _pixman_implementation_create_fast_path (imp);

    imp = _pixman_x86_get_implementations (imp);
    imp = _pixman_arm_get_implementations (imp);
    imp = _pixman_ppc_get_implementations (imp);
    imp = _pixman_mips_get_implementations (imp);

    imp = _pixman_implementation_create_noop (imp);

    if (_pixman_disabled ("wholeops"))
    {
        pixman_implementation_t *cur;

        /* Disable all whole-operation paths except the general one,
         * so that optimized iterators are used as much as possible.
         */
        for (cur = imp; cur->fallback; cur = cur->fallback)
            cur->fast_paths = empty_fast_path;
    }

    return imp;
}
