The renderControl.in file in this directory defines an API which is decoded
on the android guest into a stream and get decoded and executed on the host.
It is used in order to query the host renderer as well as send the host renderer
control commands.

The following describes each of the entries defined by this renderControl API.


GLint rcGetRendererVersion();
       This function queries the host renderer version number.

EGLint rcGetEGLVersion(EGLint* major, EGLint* minor);
       This function queries the host renderer for the EGL version
       it supports. returns EGL_FALSE on failure.

EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize);
       This function queries the host for EGL string (.i.e EGL_EXTENSIONS).
       if buffer is NULL or the bufferSize is not big enough the return value
       is the negative number of bytes required to store the string value
       otherwise the string value is copied to buffer and its size is
       returned.

EGLint rcGetNumConfigs(uint32_t* numAttribs);
       queries the host for the number of supported EGL configs.
       The function returns the number of supported configs and returns in
       numAttribs the number of attributes available for each config.

EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer);
       This function queries the host for the all set of supported configs
       with their attribute values.
       bufSize is the size of buffer, the size should be at least equal to
       (numConfigs + 1) * numAttribs * sizeof(GLuint)
       where numConfigs and numAttribs are the values returned in 
       rcGetNumConfigs. if bufSize is not big enough then the negative number
       of required bytes is returned otherwise the function returns the number
       of configs and buffer is filled as follows: The first 'numAttribs'
       integer values are filled with the EGL enumerant describing a config
       attribute, next for each config there are 'numAttribs' integer values
       holding the attribute values for that config, the values are specified
       in the same order as the attribute vector.

EGLint rcChooseConfig(EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size)
       This function triggers an eglChooseConfig on the host, to get a list of 
       configs matching the given attribs values.
 	attribs - a list of attribute names followed by the desired values, terminated by EGL_NONE
	attribs_size - the size of the list
	configs - the returned matching configuration names (same names as familiar to the client in rcGetConfigs)
	configs_size - the size of the configs buffers
	returns - the actual number of matching configurations (<= configs_size) 

EGLint rcGetFBParam(EGLint param);
       queries the host for framebuffer parameter, see renderControl_types.h
       for possible values of 'param'.

uint32_t rcCreateContext(uint32_t config, uint32_t share, uint32_t glVersion);
       This function creates a rendering context on the host and returns its
       handle. config is the config index for the context, share is either zero
       or a handle to a sharing context. glVersion is either 1 or 2 for GLES1
       or GLES2 context respectively.


void rcDestroyContext(uint32_t context);
       This function destroys a rendering context on the host.
       context is a handle returned in rcCreateContext.

uint32_t rcCreateWindowSurface(uint32_t config, uint32_t width, uint32_t height);
       This function creates a 'window' surface on the host which can be then
       bind for rendering through rcMakeCurrent.
       The function returns a handle to the created window surface.

void rcDestroyWindowSurface(uint32_t windowSurface);
       This function destoys a window surface.

uint32_t rcCreateColorBuffer(uint32_t width, uint32_t height, GLenum internalFormat);
       This function creates a colorBuffer object on the host which can be then
       be specified as a render target for a window surface through 
       rcSetWindowColorBuffer or to be displayed on the framebuffer window
       through rcFBPost.
       The function returns a handle to the colorBuffer object.

void rcDestroyColorBuffer(uint32_t colorbuffer);
       destroyes a colorBuffer object.

void rcFlushWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer);
	   This flushes the current window color buffer

void rcSetWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer);
       This set the target color buffer for a windowSurface, when set the
       previous target colorBuffer gets updated before switching to the new
       colorBuffer.

EGLint rcMakeCurrent(uint32_t context, uint32_t drawSurf, uint32_t readSurf);
       Binds a windowSurface(s) and current rendering context for the 
       calling thread.

void rcFBPost(uint32_t colorBuffer);
       This function causes the content of the colorBuffer object to be
       displayed on the host framebuffer window. The function returns
       immediatly, the buffer will be displayed at the next swap interval.

void rcFBSetSwapInterval(EGLint interval);
       Sets the swap interval for the host framebuffer window.

void rcBindTexture(uint32_t colorBuffer);
       This function instruct the host to bind the content of the specified
       colorBuffer to the current binded texture object of the calling thread.
       This function should be used to implement eglBindTexImage.

EGLint rcColorBufferCacheFlush(uint32_t colorbuffer, EGLint postCount, int forRead);
       This function returns only after all rendering requests for the specified
       colorBuffer rendering target has been processed and after all 'postCount'
       posts for the buffer requested previously through rcFBPost has been
       processed.
       if 'forRead' is not-zero, the function returns positive value in case
       there was rendering done to the buffer since the last CacheFlush request
       with non-zero 'forRead' value, otherwise the function returns zero or
       negative value on failure.

void rcReadColorBuffer(uint32_t colorbuffer, GLint x, GLint y, 
                       GLint width, GLint height, GLenum format, 
                       GLenum type, void* pixels);
       This function queries the host for the pixel content of a colorBuffer's
       subregion. It act the same as OpenGL glReadPixels however pixels
       are always packed with alignment of 1.

void rcUpdateColorBuffer(uint32_t colorbuffer, GLint x, GLint y, 
                         GLint width, GLint height, GLenum format, 
                         GLenum type, void* pixels);
       Updates the content of a subregion of a colorBuffer object.
       pixels are always unpacked with alignment of 1.
