/*
 * Copyright (C) 2016 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.
 */

// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.

/*
 * rs_io.rsh: Input/Output Functions
 *
 * These functions are used to:
 * - Send information to the Java client, and
 * - Send the processed allocation or receive the next allocation to process.
 */

#ifndef RENDERSCRIPT_RS_IO_RSH
#define RENDERSCRIPT_RS_IO_RSH

/*
 * rsAllocationIoReceive: Receive new content from the queue
 *
 * Receive a new set of contents from the queue.
 *
 * This function should not be called from inside a kernel, or from any function
 * that may be called directly or indirectly from a kernel. Doing so would cause a
 * runtime error.
 *
 * Parameters:
 *   a: Allocation to work on.
 */
#if (defined(RS_VERSION) && (RS_VERSION >= 16))
extern void __attribute__((overloadable))
    rsAllocationIoReceive(rs_allocation a);
#endif

/*
 * rsAllocationIoSend: Send new content to the queue
 *
 * Send the contents of the Allocation to the queue.
 *
 * This function should not be called from inside a kernel, or from any function
 * that may be called directly or indirectly from a kernel. Doing so would cause a
 * runtime error.
 *
 * Parameters:
 *   a: Allocation to work on.
 */
#if (defined(RS_VERSION) && (RS_VERSION >= 16))
extern void __attribute__((overloadable))
    rsAllocationIoSend(rs_allocation a);
#endif

/*
 * rsSendToClient: Send a message to the client, non-blocking
 *
 * Sends a message back to the client.  This call does not block.
 * It returns true if the message was sent and false if the
 * message queue is full.
 *
 * A message ID is required.  The data payload is optional.
 *
 * See RenderScript.RSMessageHandler.
 *
 * Parameters:
 *   data: Application specific data.
 *   len: Length of the data, in bytes.
 */
extern bool __attribute__((overloadable))
    rsSendToClient(int cmdID);

extern bool __attribute__((overloadable))
    rsSendToClient(int cmdID, const void* data, uint len);

/*
 * rsSendToClientBlocking: Send a message to the client, blocking
 *
 * Sends a message back to the client.  This function will block
 * until there is room on the message queue for this message.
 * This function may return before the message was delivered and
 * processed by the client.
 *
 * A message ID is required.  The data payload is optional.
 *
 * See RenderScript.RSMessageHandler.
 *
 * Parameters:
 *   data: Application specific data.
 *   len: Length of the data, in bytes.
 */
extern void __attribute__((overloadable))
    rsSendToClientBlocking(int cmdID);

extern void __attribute__((overloadable))
    rsSendToClientBlocking(int cmdID, const void* data, uint len);

#endif // RENDERSCRIPT_RS_IO_RSH
