/*
 * Copyright (C) 2011-2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /*! \mainpage notitle
  *
  * RenderScript is a high-performance runtime that provides
  * compute operations at the native level. RenderScript code is compiled on devices
  * at runtime to allow platform-independence as well.
  * This reference documentation describes the RenderScript runtime APIs, which you
  * can utilize to write RenderScript code in C99. The RenderScript compute header
  * files are automatically included for you.
  *
  * To use RenderScript, you need to utilize the RenderScript runtime APIs documented here
  * as well as the Android framework APIs for RenderScript.
  * For documentation on the Android framework APIs, see the <a target="_parent" href=
  * "http://developer.android.com/reference/android/renderscript/package-summary.html">
  * android.renderscript</a> package reference.
  * For more information on how to develop with RenderScript and how the runtime and
  * Android framework APIs interact, see the <a target="_parent" href=
  * "http://developer.android.com/guide/topics/renderscript/index.html">RenderScript
  * developer guide</a> and the <a target="_parent" href=
  * "http://developer.android.com/resources/samples/RenderScript/index.html">
  * RenderScript samples</a>.
  */

/** @file rs_core.rsh
 *  \brief todo-jsams
 *
 *  todo-jsams
 *
 */

#ifndef __RS_CORE_RSH__
#define __RS_CORE_RSH__

#define _RS_RUNTIME extern

#define RS_KERNEL __attribute__((kernel))

#include "rs_types.rsh"
#include "rs_allocation.rsh"
#include "rs_atomic.rsh"
#include "rs_core_math.rsh"
#include "rs_debug.rsh"
#include "rs_element.rsh"
#include "rs_math.rsh"
#include "rs_matrix.rsh"
#include "rs_object.rsh"
#include "rs_quaternion.rsh"
#include "rs_sampler.rsh"
#include "rs_time.rsh"

/**
 * Send a message back to the client.  Will not block and returns true
 * if the message was sendable and false if the fifo was full.
 * A message ID is required.  Data payload is optional.
 */
extern bool __attribute__((overloadable))
    rsSendToClient(int cmdID);
/**
 * \overload
 */
extern bool __attribute__((overloadable))
    rsSendToClient(int cmdID, const void *data, uint len);
/**
 * Send a message back to the client, blocking until the message is queued.
 * A message ID is required.  Data payload is optional.
 */
extern void __attribute__((overloadable))
    rsSendToClientBlocking(int cmdID);
/**
 * \overload
 */
extern void __attribute__((overloadable))
    rsSendToClientBlocking(int cmdID, const void *data, uint len);


/**
 * Launch order hint for rsForEach calls.  This provides a hint to the system to
 * determine in which order the root function of the target is called with each
 * cell of the allocation.
 *
 * This is a hint and implementations may not obey the order.
 */
enum rs_for_each_strategy {
    RS_FOR_EACH_STRATEGY_SERIAL = 0,
    RS_FOR_EACH_STRATEGY_DONT_CARE = 1,
    RS_FOR_EACH_STRATEGY_DST_LINEAR = 2,
    RS_FOR_EACH_STRATEGY_TILE_SMALL= 3,
    RS_FOR_EACH_STRATEGY_TILE_MEDIUM = 4,
    RS_FOR_EACH_STRATEGY_TILE_LARGE = 5
};


/**
 * Structure to provide extra information to a rsForEach call.  Primarly used to
 * restrict the call to a subset of cells in the allocation.
 */
typedef struct rs_script_call {
    enum rs_for_each_strategy strategy;
    uint32_t xStart;
    uint32_t xEnd;
    uint32_t yStart;
    uint32_t yEnd;
    uint32_t zStart;
    uint32_t zEnd;
    uint32_t arrayStart;
    uint32_t arrayEnd;
} rs_script_call_t;

/**
 * Make a script to script call to launch work. One of the input or output is
 * required to be a valid object. The input and output must be of the same
 * dimensions.
 * API 10-13
 *
 * @param script The target script to call
 * @param input The allocation to source data from
 * @param output the allocation to write date into
 * @param usrData The user definied params to pass to the root script.  May be
 *                NULL.
 * @param sc Extra control infomation used to select a sub-region of the
 *           allocation to be processed or suggest a walking strategy.  May be
 *           NULL.
 *
 *  */
#if !defined(RS_VERSION) || (RS_VERSION < 14)
extern void __attribute__((overloadable))
    rsForEach(rs_script script, rs_allocation input,
              rs_allocation output, const void * usrData,
              const rs_script_call_t *sc);
/**
 * \overload
 */
extern void __attribute__((overloadable))
    rsForEach(rs_script script, rs_allocation input,
              rs_allocation output, const void * usrData);
#else

/**
 * Make a script to script call to launch work. One of the input or output is
 * required to be a valid object. The input and output must be of the same
 * dimensions.
 * API 14+
 *
 * @param script The target script to call
 * @param input The allocation to source data from
 * @param output the allocation to write date into
 * @param usrData The user definied params to pass to the root script.  May be
 *                NULL.
 * @param usrDataLen The size of the userData structure.  This will be used to
 *                   perform a shallow copy of the data if necessary.
 * @param sc Extra control infomation used to select a sub-region of the
 *           allocation to be processed or suggest a walking strategy.  May be
 *           NULL.
 *
 */
extern void __attribute__((overloadable))
    rsForEach(rs_script script, rs_allocation input, rs_allocation output,
              const void * usrData, size_t usrDataLen, const rs_script_call_t *);
/**
 * \overload
 */
extern void __attribute__((overloadable))
    rsForEach(rs_script script, rs_allocation input, rs_allocation output,
              const void * usrData, size_t usrDataLen);
/**
 * \overload
 */
extern void __attribute__((overloadable))
    rsForEach(rs_script script, rs_allocation input, rs_allocation output);
#endif



#undef _RS_RUNTIME

#endif
